<?php
namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Candidat;
use App\Services\CandidatService;
use App\Http\Requests\Admin\StoreCandidatAdminRequest;
use App\Http\Requests\Admin\UpdateCandidatAdminRequest;
use App\Http\Requests\Admin\ChangerStatutCandidatRequest;
use App\Http\Requests\Admin\RejeterPieceRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class CandidatAdminController extends Controller
{
    public function __construct(
        private readonly CandidatService $candidatService
    ) {}

    public function index(Request $request): JsonResponse
    {
        $query = Candidat::query();

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

        if ($request->has('ville_id')) {
            $query->where('ville_id', $request->ville_id);
        }

        $candidats = $query->with(['user', 'ville', 'quartierDomicile'])
            ->paginate(15);

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

    public function disponibles(Request $request): JsonResponse
    {
        $candidats = Candidat::where('statut', 'disponible')
            ->with(['user', 'ville'])
            ->get();

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

    public function store(StoreCandidatAdminRequest $request): JsonResponse
    {
        return DB::transaction(function () use ($request) {
            $user = User::create([
                'email' => $request->email,
                'password' => bcrypt($request->password),
                'role' => 'candidat',
                'statut' => 'actif',
                'email_verified_at' => now(),
            ]);

            $candidat = Candidat::create([
                'user_id' => $user->id,
                'reference' => 'CND-' . date('Y') . '-' . str_pad(Candidat::count() + 1, 4, '0', STR_PAD_LEFT),
                'nom' => $request->nom,
                'prenom' => $request->prenom,
                'date_naissance' => $request->date_naissance,
                'sexe' => $request->sexe,
                'nationalite' => $request->nationalite,
                'telephone' => $request->telephone,
                'type_situation' => $request->type_situation,
                'disponibilite' => $request->disponibilite,
                'ville_id' => $request->ville_id,
                'quartier_domicile_id' => $request->quartier_id,
                'statut' => 'soumis',
            ]);

            return response()->json([
                'uuid' => $user->uuid,
                'reference' => $candidat->reference,
                'nom_complet' => $candidat->nom . ' ' . $candidat->prenom,
                'telephone' => $candidat->telephone,
                'statut' => $candidat->statut,
            ], 201);
        });
    }

    public function show(string $uuid): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->with(['user', 'ville', 'quartierDomicile', 'parrain', 'piecesJointes', 'formations'])->firstOrFail();

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

    public function update(UpdateCandidatAdminRequest $request, string $uuid): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->firstOrFail();

        $candidat->update($request->validated());

        return response()->json($candidat->fresh());
    }

    public function changerStatut(ChangerStatutCandidatRequest $request, string $uuid): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->firstOrFail();

        $this->candidatService->changerStatut($candidat, \App\Enums\StatutCandidat::from($request->statut), $request->commentaire);

        return response()->json(['message' => 'Statut mis à jour avec succès']);
    }

    public function pieces(string $uuid): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->firstOrFail();

        $pieces = $candidat->piecesJointes;

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

    public function validerPiece(string $uuid, int $pieceId): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->firstOrFail();

        $piece = $candidat->piecesJointes()->findOrFail($pieceId);
        
        $piece->update([
            'statut_validation' => 'valide',
            'valide_par' => auth()->id(),
            'valide_at' => now(),
        ]);

        if ($piece->type_document === 'casier_judiciaire') {
            $piece->update(['date_expiration' => now()->addMonths(3)]);
        }

        return response()->json(['message' => 'Pièce validée avec succès']);
    }

    public function rejeterPiece(RejeterPieceRequest $request, string $uuid, int $pieceId): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->firstOrFail();

        $piece = $candidat->piecesJointes()->findOrFail($pieceId);
        
        $piece->update([
            'statut_validation' => 'rejete',
            'commentaire_rejet' => $request->commentaire,
        ]);

        return response()->json(['message' => 'Pièce rejetée avec succès']);
    }

    public function destroy(string $uuid): JsonResponse
    {
        $user = User::where('uuid', $uuid)->firstOrFail();
        $candidat = $user->candidat()->firstOrFail();

        $candidatStatut = $candidat->statut instanceof \App\Enums\StatutCandidat ? $candidat->statut->value : $candidat->statut;
        if ($candidatStatut === 'en_mission') {
            return response()->json(['message' => 'Impossible de supprimer un candidat en mission'], 422);
        }

        $candidat->delete();
        $user->delete();

        return response()->json(['message' => 'Candidat supprimé avec succès']);
    }
}
