<?php

namespace App\Http\Controllers;

use App\Http\Requests\PlainteStoreRequest;
use App\Mail\PlainteIrrecevableMail;
use App\Mail\PlainteResolutionProposeeMail;
use App\Models\Communication;
use App\Models\Plaignant;
use App\Models\Plainte;
use App\Models\User;
use App\Services\ComplaintNotificationService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;

class PlainteController extends Controller
{
    public ComplaintNotificationService $complaintNotificationService;
    public function __construct(ComplaintNotificationService $complaintNotificationService)
    {
        $this->complaintNotificationService = $complaintNotificationService;
    }
     public function index(Request $request)
    {
        $query = Plainte::query();

        // Filtres
        if ($request->statut) {
            $query->where('statut', $request->statut);
        }
        
        if ($request->niveau_sensibilite) {
            $query->where('niveau_sensibilite', $request->niveau_sensibilite);
        }
        
        // if ($request->has('type_plainte')) {
        //     $query->where('type_plainte', $request->type_plainte);
        // }

        if ($request->search) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('numero', 'like', "%{$search}%")
                  ->orWhere('objet', 'like', "%{$search}%")
                  ->orWhereHas('plaignant', function($q) use ($search) {
                      $q->where('nom', 'like', "%{$search}%")
                        ->orWhere('prenom', 'like', "%{$search}%");
                  });
            });
        }

        $plaintes = $query->orderBy('date_reception', 'desc')->paginate(20);
        
        // Statistiques pour le dashboard
        $stats = [
            'total' => Plainte::count(),
            'en_attente' => Plainte::whereIn('statut', ['recu', 'en_attente','en_examen', 'en_enquete'])->count(),
            'resolues' => Plainte::where('statut', 'resolu')->count(),
            'sensibles' => Plainte::where('niveau_sensibilite', 'sensible')->count(),
            'delai_depasse' => Plainte::get()->filter->isDelaiDepasse()->count(),
        ];

        return view('plaintes.index', compact('plaintes', 'stats'));
    }
    public function liste(Request $request)
    {
        $query = Plainte::query();

        // Filter by status
        if ($request->has('status') && !empty($request->status)) {
            $query->where('statut', $request->status);
        }

        // Filter by date range
        if ($request->has('from_date') && !empty($request->from_date)) {
            $query->whereDate('date_reception', '>=', $request->from_date);
        }

        if ($request->has('to_date') && !empty($request->to_date)) {
            $query->whereDate('date_reception', '<=', $request->to_date);
        }

        // Order by most recent first
        $plaintes = $query->latest('date_reception')->paginate(15);
        
        return view('plaintes.liste', compact('plaintes'));
    }

    public function create()
    {
        return view('plaintes.create');
    }
    public function formulaire(Request $request)
    {
        // Validator::validate($request->all(),[
        //     'type_plainte'=>'required',
        //     'type_plaignant'=>'required',
        //     'anonyme'=>'required',
        // ]);

        // $type_plainte=$request->type_plainte;
        // $type_plaignant=$request->type_plaignant;
        // $anonyme=$request->anonyme;
        return view('plaintes.formulaire');
    }
    public function create1()
    {
        return view('create');
    }
    

    public function store(PlainteStoreRequest $request)
    {

        try{
        DB::beginTransaction();
            $plaignant_id=null;
                // Créer ou récupérer le plaignant
                if(!$request->boolean('est_anonyme')){
                    $plaignant = Plaignant::create(
                        $request->validated()['plaignant']
                    );
                    $plaignant_id=$plaignant->id;
                }
                else{
                    $plaignant=Plaignant::create([
                            'email'=>$request->plaignant['email'],
                            'nom'=>"Anonyme",
                    ]);
                    $plaignant_id=$plaignant->id;
                }
                

                // dd($plaignant);
                // Créer la plainte
                $plainte = Plainte::create([
                    'plaignant_id' => $plaignant_id,
                    'objet' => $request->objet,
                    'description' => $request->description,
                    'canal_reception' => $request->canal_reception,
                    'type_plainte' => $request->type_plainte,
                    'niveau_sensibilite' => $this->determineNiveauSensibilite($request),
                    'date_reception' => now(),
                    'est_anonyme' => $request->boolean('est_anonyme'),
                ]);
                // dd($plainte);

                // Gestion des fichiers/preuves
                if ($request->hasFile('preuves')) {
                    foreach ($request->file('preuves') as $file) {
                        $path = $file->store('plaintes/' . $plainte->id, 'public');
                        $plainte->media()->create([
                            'nom' => $file->getClientOriginalName(),
                            'chemin' => $path,
                            'taille' => $file->getSize(),
                            'type' => $file->getMimeType()
                        ]);
                    }
                    // $plainte->update(['preuves' => $preuves]);
                }
                // dd($plainte);
                // Envoyer accusé de réception automatiquement
                $this->envoyerAccuseReception($plainte);
                Session::flash('success', 'Plainte enregistrée avec succès');
            DB::commit();
            return redirect()->route('plaintes.suivi-plainte', ['reference' => $plainte->reference]);
        }catch(Exception $e){
            DB::rollBack();
            dd($e);
            return back()->with('error', 'Une erreur est survenue lors de l\'enregistrement de la plainte');
        }
    }

    public function proposerResolution(Request $request, Plainte $plainte)
    {
        $request->validate([
            'resolution' => 'required|string|min:10',
            'fichiers.*' => 'nullable|file|max:10240|mimes:pdf,doc,docx',
        ]);
        
        DB::beginTransaction();
        try {
            // Save the resolution proposal
            $resolution=$plainte->resolutions()->create([
                'resolution' => $request->resolution,
                'statut' => 'en_attente',
                'date_proposition' => now(),
                'propose_par' => auth()->user()->id,
            ]);

            // Handle file uploads
            if ($request->hasFile('fichiers')) {
                foreach ($request->file('fichiers') as $file) {
                    $path = $file->store('resolutions/' . $plainte->id, 'public');
                    
                    $resolution->media()->create([
                        'nom' => $file->getClientOriginalName(),
                        'chemin' => $path,
                        'taille' => $file->getSize(),
                        'type' => $file->getMimeType()
                    ]);
                }
            }

            
            // Send email to the complainant
            if ($plainte->plaignant && $plainte->plaignant->email) {
                Mail::to($plainte->plaignant->email)
                    ->send(new PlainteResolutionProposeeMail($plainte));
            }
            

            DB::commit();
            return redirect()
                ->back()
                ->with('success', 'La proposition de résolution a été envoyée avec succès.');

        } catch (\Exception $e) {
            dd($e);
            DB::rollBack();
            Log::error('Erreur lors de la proposition de résolution: ' . $e->getMessage());
            
            return redirect()
                ->back()
                ->with('error', 'Une erreur est survenue lors de l\'envoi de la proposition de résolution.')
                ->withInput();
        }
    }
    public function show(Plainte $plainte)
    {
        return view('plaintes.show', compact('plainte'));
    }
    public function suiviPlainte($reference)
    {
        $plainte=Plainte::where('reference',$reference)->first();
        if (!$plainte) {
            return abort(405,'Plainte non trouvée');
        }
        return view('plaintes.suivi-plainte', compact('plainte'));
    }

    public function updateStatus(Request $request, Plainte $plainte)
    {
        $validated = $request->validate([
            'statut' => 'required|in:recu,en_examen,recevable,irrecevable,en_enquete,resolu,en_appel,clos',
            'decision' => 'nullable|string',
            'mesures_correctives' => 'nullable|array',
        ]);

        $plainte->update($validated);
        // dd($validated);
        // Actions automatiques selon le statut
        match($validated['statut']) {
            'recevable' => $this->onPlainteAccepted($plainte),
            'irrecevable' => $this->onPlainteRejected($plainte),
            'resolu' => $this->onPlainteResolved($plainte),
            'clos' => $this->onPlainteClosed($plainte),
            default => null
        };

        return back()->with('success', 'Statut mis à jour avec succès');
    }

    private function determineNiveauSensibilite(Request $request)
    {
        $motsClesSensibles = [
            'viol', 'abus sexuel', 'violence', 'discrimination', 
            'détournement', 'corruption', 'décès', 'accident grave'
        ];
        
        $description = strtolower($request->description . ' ' . $request->objet);
        
        foreach ($motsClesSensibles as $mot) {
            if (str_contains($description, $mot)) {
                return 'sensible';
            }
        }
        
        return 'non_sensible';
    }

    private function assignPlainte(Request $request)
    {
        // Logique d'assignation automatique selon le niveau de sensibilité et le type
        // Pour l'instant, assigner à l'utilisateur connecté
        return Auth::id();
    }

    private function envoyerAccuseReception(Plainte $plainte)
    {
        // Créer l'enregistrement de communication
        Communication::create([
            'plainte_id' => $plainte->id,
            'sent_by' => User::first()->id,
            'type' => 'accuse_reception',
            'canal' => $plainte->plaignant->email ? 'email' : 'telephone',
            'message' => "Accusé de réception pour la plainte {$plainte->numero}",
            'date_envoi' => now(),
        ]);

        $plainte->update(['date_accuse_reception' => now()]);
        $this->complaintNotificationService->sendAccuseReception($plainte);
        // Ici, ajouter la logique d'envoi d'email/SMS réel
        // Mail::to($plainte->plaignant->email)->send(new AccuseReceptionMail($plainte));
    }

    private function onPlainteAccepted(Plainte $plainte)
    {
        try {
            $this->complaintNotificationService->notifyStatusChange($plainte);
        } catch (\Exception $e) {
            // Gérer l'exception
            // dd($e);
            Log::error('Erreur lors de la notification du statut de la plainte', [
                'plainte_id' => $plainte->id,
                'error' => $e->getMessage(),
            ]);
        }

        // Notifier le plaignant que sa plainte est recevable
        // Communication::create([
        //     'plainte_id' => $plainte->id,
        //     'sent_by' => Auth::id(),
        //     'type' => 'notification_decision',
        //     'canal' => 'email',
        //     'message' => "Votre plainte {$plainte->numero} a été déclarée recevable et est en cours de traitement.",
        //     'date_envoi' => now(),
        // ]);
    }

    private function onPlainteRejected(Plainte $plainte)
    {
        $this->complaintNotificationService->notifyStatusChange($plainte);

        // Send email notification to the complainant if email exists
        if ($plainte->plaignant && $plainte->plaignant->email) {
            try {
                Mail::to($plainte->plaignant->email)
                    ->send(new PlainteIrrecevableMail($plainte));
                
                // Log the communication
                Communication::create([
                    'plainte_id' => $plainte->id,
                    'sent_by' => Auth::id(),
                    'type' => 'notification_decision',
                    'canal' => 'email',
                    'message' => "Notification d'irrecevabilité envoyée pour la plainte {$plainte->numero}",
                    'date_envoi' => now(),
                    'statut' => 'envoyé'
                ]);
                
            } catch (\Exception $e) {
                Log::error('Erreur lors de l\'envoi de l\'email de plainte irrecevable: ' . $e->getMessage());
                
                // Log the failed communication attempt
                Communication::create([
                    'plainte_id' => $plainte->id,
                    'sent_by' => Auth::id(),
                    'type' => 'notification_decision',
                    'canal' => 'email',
                    'message' => "Échec d'envoi de la notification d'irrecevabilité: " . $e->getMessage(),
                    'date_envoi' => now(),
                    'statut' => 'échec'
                ]);
            }
        } else {
            // Log that no email was sent because no email address was available
            Communication::create([
                'plainte_id' => $plainte->id,
                'sent_by' => Auth::id(),
                'type' => 'notification_decision',
                'canal' => 'système',
                'message' => "Aucun email trouvé pour notifier le plaignant de l'irrecevabilité",
                'date_envoi' => now(),
                'statut' => 'non_envoyé'
            ]);
        }
    }

    private function onPlainteResolved(Plainte $plainte)
    {
        $plainte->update(['date_resolution' => now()]);
        $this->complaintNotificationService->notifyStatusChange($plainte);
        // Communication::create([
        //     'plainte_id' => $plainte->id,
        //     'sent_by' => Auth::id(),
        //     'type' => 'notification_decision',
        //     'canal' => 'email',
        //     'message' => "Votre plainte {$plainte->numero} a été résolue.",
        //     'date_envoi' => now(),
        // ]);
    }

    private function onPlainteClosed(Plainte $plainte)
    {
        $plainte->update(['date_cloture' => now()]);
        $this->complaintNotificationService->notifyStatusChange($plainte);

    }
}
