<?php

namespace App\Http\Controllers;

use App\Models\BibliothequeProjet;
use App\Models\Categorie;
use App\Models\Direction;
use App\Models\Domaine;
use App\Models\EtapeProjet;
use App\Models\Famille;
use App\Models\ProjetStatut;
use App\Models\Segment;
use App\Models\Service;
use App\Models\Paat;
use App\Models\Projet;
use App\Traits\ProjetsListesOnglets;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use PAAT_STATUT;
use ETAPE_PROJET;
use PROJET_STATUT;

class BibliothequeProjetController extends Controller
{
    use ProjetsListesOnglets;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('permission:see_bibliotheque_projets')->only(['index, show']);
        $this->middleware('permission:add_bibliotheque_projets')->only(['create', 'store']);
        $this->middleware('permission:creer_projet_from_bibliotheque_projets')->only(['creer_projet']);
        $this->middleware('permission:delete_bibliotheque_projets')->only(['destroy']);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('bibliotheque_projets.index', [
            'bibliotheque_projets' => BibliothequeProjet::where('structure_id', Auth::user()->structure_id)->get()
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('projets.form.form', array_merge(
            $this->getListesOnglets(),
            [
                'route' => 'store',
                'editable' => true
            ]
        ));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'direction_id' => 'required',
            'objet' => 'required|string|max:255',
            'description' => 'nullable|string',
            'budget' => 'required|string',
            'niveau_mutualisation_id' => 'required',
            'operateur_mutualisation_id' => 'required',
            'impact_budgetaire' => 'nullable|numeric|between:0,100',
            'imputation_budgetaire_id' => 'required',
            'programmation' => 'required|boolean',
            'type_calcul_gains' => 'required|integer|between:1,3',
            'ondam' => 'required|boolean',
            'referentiel' => 'nullable|boolean',
            'libelle_marche_a_renouveler' => 'nullable|string|max:255',
            'numero_marche_a_renouveler' => 'nullable|string|max:255',
            'libelle_nouveau_marche' => 'nullable|string|max:255',
            'numero_nouveau_marche' => 'nullable|string|max:255',
            'date_debut' => 'required|date_format:d/m/Y',
            'date_fin' => 'required|date_format:d/m/Y'
        ]);

        // Gestion directions et services
        $direction = $request->direction_id != null ? Direction::find($request->direction_id) : null;
        $split_service = isset($request->service_id) ? explode('_', $request->service_id) : null;
        $service = $split_service != null ? Service::find(end($split_service)) : null;
        if ($service !== null) {
            if ($service->direction_id != $direction->id) {
                // Normalement on ne rentre jamais dans ce cas
                abort(403);
            }
        }

        // Gestion familles, domaines, catégories et segments
        $famille = $request->famille_id != null ? Famille::find($request->famille_id) : null;
        $split_domaine = isset($request->domaine_id) ? explode('_', $request->domaine_id) : null;
        $domaine = $split_domaine != null ? Domaine::find(end($split_domaine)) : null;
        $split_categorie = isset($request->categorie_id) ? explode('_', $request->categorie_id) : null;
        $categorie = $split_categorie != null ? Categorie::find(end($split_categorie)) : null;
        $split_segment = isset($request->segment_id) ? explode('_', $request->segment_id) : null;
        $segment = $split_segment != null ? Segment::find(end($split_segment)) : null;

        BibliothequeProjet::create(
            array_merge(
                $request->only([
                    'objet',
                    'description',
                    'niveau_mutualisation_id',
                    'operateur_mutualisation_id',
                    'budget',
                    'imputation_budgetaire_id',
                    'programmation',
                    'type_calcul_gains',
                    'ondam',
                    'referentiel',
                    'renouvellement_marche',
                    'libelle_marche_a_renouveler',
                    'numero_marche_a_renouveler',
                    'libelle_nouveau_marche',
                    'numero_nouveau_marche',
                ]),
                [
                    // On ajoute les champs manquants
                    'structure_id' => Auth::user()->structure_id,
                    'date_debut' => date_create_from_format('d/m/Y', $request->date_debut),
                    'date_fin' => date_create_from_format('d/m/Y', $request->date_fin),
                    // On surcharge certains champs
                    'impact_budgetaire' => $request->impact_budgetaire ?? 0,
                    'direction_id' => $direction->id,
                    'service_id' => $service != null ? $service->id : null,
                    'famille_id' => $famille != null ? $famille->id : null,
                    'domaine_id' => $domaine != null ? $domaine->id : null,
                    'categorie_id' => $categorie != null ? $categorie->id : null,
                    'segment_id' => $segment != null ? $segment->id : null,
                ]
            )
        );

        return redirect()->route('bibliotheque_projets.index')->with('success', 'Bibliothèque projet ajoutée avec succès.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $projet = BibliothequeProjet::find($id);
        if ($projet != null) {
            if($projet->structure_id === Auth::user()->structure_id) {
                return view('projets.form.form', array_merge(
                    $this->getListesOnglets(),
                    [
                        'projet' => $projet,
                        'route' => 'update',
                        'editable' => false
                    ]
                ));
            } else {
                abort(403);
            }
        } else {
            abort(404);
        }

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $bibliotheque_projet = BibliothequeProjet::find($id);
        if (isset($bibliotheque_projet)) {
            if($bibliotheque_projet->structure_id === Auth::user()->structure_id) {
                $bibliotheque_projet->delete();
                return redirect()->route('bibliotheque_projets.index')->with('success', 'Bibliothèque projet supprimée avec succès.');

            } else {
                abort(403);
            }
        } else {
            abort(404);
        }
    }

    /**
     * Fonction qui permet de créer un projet depuis la bibliothèque
     * @param $id
     */
    public function creer_projet($id)
    {
        $template = BibliothequeProjet::find($id);
        if (isset($template)) {
            $paat_courant = Paat::select('id')->where('structure_id', Auth::user()->structure_id)->whereIn('statut', [PAAT_STATUT::EN_COURS, PAAT_STATUT::INITIALISATION])->first();
            if (isset($paat_courant)) {
                // On récupère le prochain id en base pour créer la référence
                $statement = DB::select("SHOW TABLE STATUS LIKE 'projets'");
                $nextId = $statement[0]->Auto_increment;

                // On récupère les attributs du template sauf l'id, created_at et updated_at
                $attr = $template->getAttributes();
                unset($attr['id'], $attr['created_at'], $attr['updated_at']);

                // On crée le projet
                $projet = Projet::create(array_merge($attr, [
                    'paat_id' => $paat_courant->id,
                    'owner_id' => Auth::user()->getAuthIdentifier(),
                    'reference' => 'F-' . $nextId . '-' . date('m') . "-" . date('Y')
                ]));

                // Mise à jour du statut du projet créé
                EtapeProjet::firstOrCreate([
                    'etape' => ETAPE_PROJET::CREATION,
                    'projet_id' => $projet->id
                ]);
                ProjetStatut::firstOrCreate([
                    'message' => '',
                    'user_id' => Auth::user()->getAuthIdentifier(),
                    'statut_id' => PROJET_STATUT::EN_COURS,
                    'projet_id' => $projet->id
                ]);

                return redirect()->route('projets.edit', $projet->id)->with('success', 'Le projet a bien été créé à partir de la bibliothèque.');
            } else {
                return redirect()->back()
                    ->withErrors(['Impossible de créer le projet à partir de la bibliothèque car votre structure ne possède aucun PAAT en cours.']);
            }
        } else {
            abort(404);
        }
    }
}
