<?php

namespace App\Http\Controllers;

use App\Models\Activite;
use App\Models\Csd;
use App\Models\GroupeActivite;
use App\Models\Action;
use App\Models\Structure;
use App\Models\Resultat;
use App\Models\PrevisionActivite;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;

class ActivitesController extends Controller
{
    public function index()
    {
        try {
        
         $user = Auth::user();
           $groupId = $user->usergroup_id;
           if ($groupId == 4) {
            $activites = Activite::with(['action', 'structureresponsable', 'resultat'])
                        ->whereHas('action.programme.responsables', function ($query) use ($user) {
                            $query->where('user_id', $user->id);
                        })
                        ->orderBy('code')
                        ->get();
                
                 } 
                 elseif ($groupId == 5 ) {
                   $activites = Activite::select('activites.*')
                              ->join('actions', 'actions.id', '=', 'activites.action_id')
                              ->join('programmes', 'programmes.id', '=', 'actions.programme_id')
                              ->leftJoin('structure_activite', 'structure_activite.activite_id', '=', 'activites.id')
                              ->join('structures', function ($join) {
                                  $join->on('structures.id', '=', 'activites.structure_id')
                                       ->orOn('structures.id', '=', 'structure_activite.structure_id');
                              })
                              ->where('structures.responsablestructure_id', $user->id)
                              ->distinct()
                              ->with(['action', 'structureresponsable', 'resultat'])
                              ->orderBy('activites.code', 'asc')
                              ->get();
                
                }
				elseif ($groupId == 6 ) {
                   $activites = Activite::select('activites.*')
                              ->join('actions', 'actions.id', '=', 'activites.action_id')
                              ->join('programmes', 'programmes.id', '=', 'actions.programme_id')
                              ->leftJoin('structure_activite', 'structure_activite.activite_id', '=', 'activites.id')
                              ->join('structures', function ($join) {
                                  $join->on('structures.id', '=', 'activites.structure_id')
                                       ->orOn('structures.id', '=', 'structure_activite.structure_id');
                              })
                              ->where('structures.pointfocal_id', $user->id)
                              ->distinct()
                              ->with(['action', 'structureresponsable', 'resultat'])
                              ->orderBy('activites.code', 'asc')
                              ->get();
                
                }
                 else {
                 $activites = Activite::with(['action', 'structureresponsable', 'resultat'])
                ->orderBy('code')
                ->get();
                 }

            return view('activites.index', compact('activites'));
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur lors du chargement des activités : ' . $e->getMessage());
        }
    }

    public function create($actionid=null)
    {
		try {
				if (isset($actionid)) {
					$action = Action::select('ouvert', 'actif')->findOrFail($actionid);
					$actions = Action::where('id', $actionid)->get();
					//$actions = Action::findOrFail($actionid);
					if (!$action->ouvert) {
						return redirect()->back()->with('error', 'Impossible d\'ajouter des activités à une action fermée');
					}
					if (!$action->actif) {
						return redirect()->back()->with('error', 'Impossible, demandez l\'activation de l\'action');
					}
				}else{
					$actions = Action::where('actif', true)
					->where('ouvert', true)
					->orderBy('code')
					->get();
				}

				$structures = Structure::where('is_active', true)->get();
				$csds = Csd::whereHas('groupeactivites', function ($query) {
					$query->where('is_active', true)->whereHas('etapes');
				})->orderBy('nom')->get();

				$groupes = GroupeActivite::where('is_active', true)
					->whereHas('etapes')
					->orderBy('csd_id')
					->orderBy('code')
					->get();


				return view('activites.create', compact('actions', 'structures', 'groupes', 'actionid', 'csds'));
			} catch (\Exception $e) {
				return redirect()->back()->with('error', 'Erreur lors du chargement du formulaire : ' . $e->getMessage());
			}
    }

    public function store(Request $request)
    {
	//dd($request); die();
        $request->validate([
			'groupe_id' => 'required|integer',
            'code' => 'required',
            'nom' => 'required',
            'datedebut' => 'required|date',
            'datefin' => 'required|date|after_or_equal:datedebut',
            'montant' => 'required|numeric',
            'structure_id' => 'required|integer',
            'action_id' => 'required|integer',
            'resultat_id' => 'required|integer'
		]);
		
		try {
            $action = Action::select('ouvert', 'actif')->findOrFail($request->action_id);

            if ($action->ouvert && $action->actif) {
                $data = new Activite($request->all());

                if ($data->save()) {
                    return redirect()->route('actions.show', $request->action_id)
                        ->with('success', 'Activité ajoutée avec succès.');
                } else {
                    return redirect()->back()->with('error', 'Échec de l’enregistrement de l’activité.');
                }
            }

            return redirect()->back()->with('error', 'Impossible d\'ajouter des activités à une action fermée.');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur inattendue : ' . $e->getMessage());
        }
    }

    public function show($id)
    {
	    
    try {
            $activite = Activite::with([
                'action',
                'resultat',
                'structureresponsable',
                'groupeactivite',
                'structurespartenaires',
                'evaluations',
                'etapes',
                'previsions',
				'extrants'
            ])->findOrFail($id);

            $evalwaitings = PrevisionActivite::doesntHave('evaluations')
                ->where('activite_id', $id)
                ->where('dateevaluation', '<=', Carbon::now()->toDateString())
                ->get();

            return view('activites.show', compact('activite', 'evalwaitings'));
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur lors du chargement des détails de l’activité : ' . $e->getMessage());
        }
    }
	
	public function planning($id)
    {
	    
    try {
            $activite = Activite::with(['action', 'resultat', 'structureresponsable', 'groupeactivite', 'previsions'])
                ->findOrFail($id);

            $evalwaitings = PrevisionActivite::doesntHave('evaluations')
                ->where('activite_id', $id)
                ->where('dateevaluation', '<=', Carbon::now()->toDateString())
                ->get();

            return view('activites.planning', compact('activite', 'evalwaitings'));
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur lors du chargement du planning : ' . $e->getMessage());
        }
    }
	
	public function evaluate($id)
    {
	   
     try {
            header("Cache-Control: no-cache, must-revalidate, max-age=0");
            header("Pragma: no-cache");
            header("Expires: Fri, 01 Jan 1990 00:00:00 GMT");

            $activite = Activite::with(['action', 'resultat', 'structureresponsable', 'groupeactivite', 'evaluations'])
                ->findOrFail($id);
				
			/* // Dernière évaluation
			$lastEvaluation = $activite->evaluations()->orderBy('taux_realisation', 'desc')->first();
			
			$lastLevel = $lastEvaluation->taux_realisation ?? 0;
			
			
			
			// Étapes liées à l'activité et supérieures à la dernière évaluation
			$etapesDisponibles = $activite->etapes()
										   ->where('niveauexec', '>', $lastLevel)
										   ->orderBy('niveauexec', 'asc')
										   ->get(); */

            $evalwaitings = PrevisionActivite::doesntHave('evaluations')
                ->where('activite_id', $id)
                ->where('dateevaluation', '<=', Carbon::now()->toDateString())
                ->orderBy('dateevaluation', 'asc')
                ->get();
			
			// Regrouper les prévisions par extrant
			$groupedPrevisions = $evalwaitings->groupBy('extrant_id');

			// Préparer les étapes disponibles par extrant
			$etapesParExtrant = [];

			foreach ($groupedPrevisions as $extrantId => $previsions) {
				// Dernier niveau réalisé pour cet extrant
				$lastEvaluation = $activite->evaluations()
					->where('extrant_id', $extrantId)
					->orderBy('taux_realisation', 'desc')
					->first();

				$lastLevel = $lastEvaluation->taux_realisation ?? 0;

				// Étapes disponibles pour cet extrant (niveau supérieur au dernier niveau)
				$etapesParExtrant[$extrantId] = $activite->etapes()
					->where('niveauexec', '>', $lastLevel)
					->orderBy('niveauexec', 'asc')
					->get();
			}
			
            return view('activites.evaluate', compact('activite', 'evalwaitings', 'etapesParExtrant'));
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur lors du chargement de la page d’évaluation : ' . $e->getMessage());
        }
    
    }

    public function edit($id)
    {
  
   try {
            $activite = Activite::findOrFail($id);

            if ($activite->valide && (!$activite->ouvert || !$activite->actif)) {
                return redirect()->back()->with('error', 'Impossible. L\'activité doit être non validée ou bien active et ouverte');
            }

            if ($activite->clos) {
                return redirect()->back()->with('error', 'Impossible. Cette activité est clôturée');
            }

            $actions = Action::all();
            $structures = Structure::where('is_active', true)->get();

            $groupes = GroupeActivite::where('is_active', true)
                ->whereHas('etapes')
                ->orderBy('csd_id')
                ->orderBy('code')
                ->get();

            return view('activites.edit', compact('activite', 'actions', 'structures', 'groupes'));
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur lors du chargement du formulaire d’édition : ' . $e->getMessage());
        }
    }
	
	public function update(Request $request, $id)
	{
		try {

			$activite = Activite::findOrFail($id);

			if ($activite->clos) {
				return back()->with('error', 'Impossible. Cette activité est cloturée')->withInput();
			}

			$validated = $request->validate([
				'groupe_id' => 'required|integer',
				'code' => 'required|string',
				'nom' => 'required|string',
				'datedebut' => 'required|date',
				'datefin' => 'required|date|after_or_equal:datedebut',
				'montant' => 'required|numeric',
				'structure_id' => 'required|integer'
			]);

			// Mise à jour des valeurs envoyées par le formulaire
			$activite->fill($validated);

			// Logique métier
			$activite->valide = false;
			$activite->actif = false;
			$activite->ouvert = false;

			// Enregistrement
			$activite->save();

			return redirect()->route('activites.index')
				->with('success', 'Activité mise à jour avec succès.');

		} catch (\Exception $e) {

			return back()
				->with('error', 'Erreur inattendue : ' . $e->getMessage())
				->withInput();
		}
	}
	

    public function destroy($id)
    {	
        try {
            $activite = Activite::with('groupeactivite', 'structurespartenaires')->findOrFail($id);
			
			$cant_delete = $activite->previsions()->exists()
						|| $activite->evaluations()->exists()
						|| $activite->structurespartenaires()->exists();
			//dd($cant_delete); die();
			if($cant_delete) {
				return redirect()->back()->with('error', 'Impossible. Cette activité liée à des données (évaluations, prévisions, structures,...');
			}
			
			if($activite->clos || $activite->valide){
				return redirect()->back()->with('error', 'Impossible. Cette activité est cloturée ou validée');
			}
            $actionid = $activite->action_id;

            if ($activite->delete()) {
                return redirect()->route('actions.show', $actionid)->with('success', 'Activité supprimée avec succès.');
            } else {
                return redirect()->route('actions.show', $actionid)->with('error', 'Échec de la suppression.');
            }
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur inattendue : ' . $e->getMessage());
        }
    }
	
	public function valide($id)
    {
        $activite = Activite::findOrFail($id);
		if($activite->clos){
			return redirect()->back()->with('error', 'Impossible. Cette activité est cloturée');
		}
		$activite->valide = !$activite->valide;
		if (!$activite->valide) {
			$activite->actif = false;
            $activite->ouvert = false;
        }
		 if ($activite->save()) {
			return redirect()->back()->with('success', 'État mis à jour avec succès.');
		} else {
			return redirect()->back()->with('error', 'Échec de la mise à jour de l’état.');
		}
    }

    public function actif($id)
    {
		try {
            $activite = Activite::findOrFail($id);
			if($activite->clos){
				return redirect()->back()->with('error', 'Impossible. Cette activité est cloturée');
			}
            $actionactif = Action::select('actif')->findOrFail($activite->action_id);
			
		if(!$activite->valide){
			return redirect()->back()->with('error', 'Impossible, validez d\'abord par le responsable désigné');
		}

            if ($actionactif->actif) {
                $activite->actif = !$activite->actif;
                if (!$activite->actif) {
                    $activite->ouvert = false;
                }

                if ($activite->save()) {
                    return redirect()->back()->with('success', 'État mis à jour avec succès.');
                } else {
                    return redirect()->back()->with('error', 'Échec de la mise à jour de l’état.');
                }
            }

            return redirect()->back()->with('error', 'Non effectué. Vérifiez que l\'activité est active.');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur inattendue : ' . $e->getMessage());
        }
    }

    
    public function ouvert($id)
    {
        try {
            $activite = Activite::findOrFail($id);
			if($activite->clos){
				return redirect()->back()->with('error', 'Impossible. Cette activité est cloturée');
			}
		
            $actionouvert = Action::select('actif')->findOrFail($activite->action_id);

            if ($actionouvert->actif) {
                $newstate = !$activite->ouvert;

                if ($newstate && !$activite->actif) {
                    return redirect()->back()->with('error', 'Impossible, activez d\'abord l’activité.');
                }

                $activite->ouvert = $newstate;

                if ($activite->save()) {
                    return redirect()->back()->with('success', 'État d’ouverture modifié avec succès.');
                } else {
                    return redirect()->back()->with('error', 'Échec de la modification de l’état.');
                }
            }

            return redirect()->back()->with('error', 'Non effectué. Vérifiez que l\'action est activée.');
        } catch (\Exception $e) {
            return redirect()->back()->with('error', 'Erreur inattendue : ' . $e->getMessage());
        }
    }
	
	
	public function getGroupesParCsd($id)
    	{
		$groupes = GroupeActivite::where('csd_id', $id)
			->where('is_active', true)
			->whereHas('etapes')       // seulement les groupes ayant des étapes
			->orderBy('code')
			->get(['id', 'nom']);

  		return response()->json($groupes);
	} 


	public function getResultatsParAction($id)
    	{
		$resultats = Resultat::where('action_id', $id)
			->orderBy('created_at', 'asc')
			->get(['id', 'nom']);

	   	 return response()->json($resultats);
    	} 
}
