<?php

namespace App\Http\Controllers\Projets;

use App\Http\Controllers\Controller;
use App\Http\Requests\Projets\Fichiers\StoreFichier;
use App\Http\Requests\Projets\Fichiers\UpdateFichier;
use App\Models\CommentairesRapportActivite;
use App\Models\Fichier;
use App\Models\FichierHasProjet;
use App\Models\Paat;
use App\Models\Projet;
use App\Models\User;
use App\Notifications\TelechargerFichier;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use PAAT_STATUT;
use ROLE;

class FichierController extends Controller
{
    public function __construct()
    {
        $this->middleware('permission:see_projet')->only('download');
        $this->middleware('permission:edit_projet')->only(['create', 'store', 'edit', 'update', 'destroy']);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @param int $projet_id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function create(int $projet_id)
    {
        if (Projet::checkIfUserCanEditOrDestroy(Projet::find($projet_id), true)) {
            // On ne retourne pas une vue ici car on est à l'intérieur d'un projet
            return redirect()->route('projets.edit', $projet_id)->with(['active' => 'fichiers.create']);
        } else {
            abort(403);
        }
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @param int $projet_id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(StoreFichier $request, int $projet_id)
    {
        $projet = Projet::find($projet_id);
        if (isset($projet)) {
            if (Projet::checkIfUserCanEditOrDestroy($projet, true)) {
                $request->validated();

                if ($request->hasFile('fichier')) {
                    $url = Storage::put('public/structures/' . Auth::user()->structure_id . '/projets/' . $projet->id . '/', $request->file('fichier'));
                    $fichier = Fichier::firstOrCreate([
                        'nom' => $request->file('fichier')->getClientOriginalName(),
                        'url' => $url,
                        'upload_by' => Auth::user()->getAuthIdentifier(),
                        'commentaire' => $request->commentaire
                    ]);

                    if ($fichier) {
                        FichierHasProjet::firstOrCreate(['fichier_id' => $fichier->id, 'projet_id' => $projet->id]);

                        return redirect()->route('projets.edit', $projet->id)->with([
                            'success' => 'Fichier enregistré avec succès.',
                            'active' => 'fichiers'
                        ]);
                    } else {
                        // Le fichier ne s'est pas upload correctement -> On clear le strorage
                        Storage::delete($url);
                        return redirect()->route('projets.edit', $projet->id)
                            ->withErrors('Une erreur est survenue lors de l\'ajout du fichier.')
                            ->with(['active' => 'fichiers']);
                    }
                } else {
                    return redirect()->route('projets.edit', $projet->id)
                        ->withErrors('Impossible d\'ajouter le fichier.')
                        ->with(['active' => 'fichiers']);
                }
            } else {
                abort(403);
            }
        } else {
            abort(404);
        }
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param int $projet_id
     * @param int $fichier_id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function edit(int $projet_id, int $fichier_id)
    {
        $projet = Projet::find($projet_id);
        $fichier = Fichier::find($fichier_id);

        if (isset($projet) && isset($fichier)) {
            if (FichierHasProjet::where('projet_id', $projet->id)->where('fichier_id', $fichier->id)->exists()
                && Projet::checkIfUserCanEditOrDestroy($projet, true)) {
                // On ne retourne pas une vue ici car on est à l'intérieur d'un projet
                return redirect()->route('projets.edit', [$projet->id, $fichier->id])
                    ->with([
                        'fichier' => $fichier, // On passe le fichier en session que l'on récupère dans le projet controller -> getListOnglet()
                        'active' => 'fichiers.edit'
                    ]);
            } else {
                abort(403);
            }
        } else {
            abort(404);
        }
    }

    /**
     * Update the specified resource in storage.
     *
     * @param UpdateFichier $request
     * @param int $projet_id
     * @param int $fichier_id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(UpdateFichier $request, int $projet_id, int $fichier_id)
    {
        $projet = Projet::find($projet_id);
        $fichier = Fichier::find($fichier_id);

        if (isset($projet) && isset($fichier)) {
            if (FichierHasProjet::where('projet_id', $projet->id)->where('fichier_id', $fichier->id)->exists()
                && Projet::checkIfUserCanEditOrDestroy($projet, true)) {
                $validated = $request->validated();
                $fichier->update(['commentaire' => $validated['commentaire']]);
                return redirect()->route('projets.edit', $projet->id)->with([
                    'success' => 'Fichier mis à jour avec succès.',
                    'active' => 'fichiers'
                ]);
            } else {
                abort(403);
            }
        } else {
            abort(404);
        }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $projet_id
     * @param int $fichier_id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(int $projet_id, int $fichier_id)
    {
        $projet = Projet::find($projet_id);
        $fichier = Fichier::find($fichier_id);
        if (isset($projet) && isset($fichier)) {
            $fichierProjet = FichierHasProjet::where('projet_id', $projet->id)->where('fichier_id', $fichier->id)->first();
            if (isset($fichierProjet) && Projet::checkIfUserCanEditOrDestroy($projet, true)) {
                // On supprime le lien avec le projet en premier -> au pire on a un fichier orphelin
                $fichierProjet->delete();
                Storage::delete($fichier->url);
                $fichier->delete();

                return redirect()->route('projets.edit', $projet->id)->with([
                    'success' => 'Le fichier a été supprimé avec succès.',
                    'active' => 'fichiers'
                ]);
            } else {
                abort(403);
            }
        } else {
            abort(404);
        }
    }

    public function download(int $projet_id, int $fichier_id)
    {
        $projet = Projet::find($projet_id);
        $fichier = Fichier::find($fichier_id);
        if (isset($projet) && isset($fichier)) {
            if (FichierHasProjet::where('fichier_id', $fichier->id)->where('projet_id', $projet->id)->exists()
                && Projet::checkIfUserCanEditOrDestroy($projet)) {
                return Storage::download($fichier->url, $fichier->nom);
            } else {
                return redirect()->route('projets.edit', $projet->id)
                    ->withErrors('Vous n\'avez pas l\'autorisation pour télécharger le fichier')
                    ->with(['active' => 'fichiers']);
            }
        } else {
            return redirect()->route('projets.edit', $projet->id)
                ->withErrors('Impossible de télécharger le fichier.')
                ->with(['active' => 'fichiers']);
        }
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @param int $projet_id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store_export_pdf(Request $request)
    {
        if ($request->hasFile('file')) {
            $user_rapport_activite = CommentairesRapportActivite::get_current_monthly_rapport_activite();
            // S'il y a un rapport d'activité d'enregistré, on upload le fichier
            if (isset($user_rapport_activite)) {
                // S'il y a déjà un fichier lié, on le supprime
                if ($user_rapport_activite->fichier && Storage::get($user_rapport_activite->fichier->url) != null) {
                    Storage::delete($user_rapport_activite->fichier->url);
                }

                // TODO : si on a un rapport qui porte le même nom qu'un ancien rapport sur un autre mois/année,
                // alors le fichier va être mis à jour mais sans changer d'ID, par conséquent l'ancien rapport est perdu
                $filename = $request->filename;
                $url = Storage::putFileAs(
                    'public/exports/rapport_responsable_ars/' . Auth::user()->id,
                    $request->file('file'),
                    $filename
                );
                $fichier = Fichier::create([
                    'nom' => $filename,
                    'url' => $url,
                    'upload_by' => Auth::user()->getAuthIdentifier(),
                    'commentaire' => null
                ]);

                if ($fichier) {
                    $user_rapport_activite->fichier_id = $fichier->id;
                    $user_rapport_activite->save();
                    return response()->json([], 200);
                } else {
                    // Le fichier ne s'est pas upload correctement -> On clear le strorage
                    Storage::delete($url);
                    return response()->json([
                        'error' => 'Une erreur est survenue lors de la sauvegarde du fichier.'
                    ], 500);
                }
            } else {
                return response()->json([
                    'error' => "Il n'y a aucun rapport d'enregistré pour ce mois-ci. 
                        Le rapport est donc juste téléchargé, mais pas enregistré.
                        Pour que le rapport soit correctement sauvegardé, veuillez d'abord enregistrer 
                        les informations du rapport."
                ], 500);
            }
        } else {
            return response()->json([
                'error' => 'Le fichier n\'a pas été envoyé au serveur correctement.'
            ], 500);
        }
    }

    public function download_export_pdf(int $fichier_id = -1)
    {
        $fichier = Fichier::find($fichier_id);
        if (isset($fichier)) {
            return Storage::download($fichier->url, $fichier->nom);
        } else {
            return redirect()->route('home')
                ->withErrors("Impossible de télécharger le rapport. Veuillez réessayer.");
        }
    }

    public function notify_export_pdf(int $fichier_id, string $role)
    {
        if (isset($fichier_id) && isset($role)) {
            $fichier = Fichier::find($fichier_id);
            if (isset($fichier)) {
                $message = "Le fichier $fichier->nom a été sauvegardé. Vous pouvez le télécharger en cliquant ici.";
                $users = User::role($role . '_' . Auth::user()->structure_id)->get();
                foreach($users as $user) {
                    $user->notify(new TelechargerFichier($message, $fichier_id));
                }
                return redirect()->route('home')
                    ->with('success', 'Notification de la disponibilité du fichier envoyée avec succès.');
            } else {
                abort(404);
            }
        } else {
            abort(500);
        }

    }
}
