package dev.lions.unionflow.server.resource;

import dev.lions.unionflow.server.api.dto.solidarite.request.CreateDemandeAideRequest;
import dev.lions.unionflow.server.api.dto.solidarite.request.UpdateDemandeAideRequest;
import dev.lions.unionflow.server.api.dto.solidarite.response.DemandeAideResponse;
import dev.lions.unionflow.server.api.enums.solidarite.StatutAide;
import dev.lions.unionflow.server.api.enums.solidarite.TypeAide;
import dev.lions.unionflow.server.api.enums.solidarite.PrioriteAide;
import dev.lions.unionflow.server.entity.Membre;
import dev.lions.unionflow.server.service.DemandeAideService;
import dev.lions.unionflow.server.repository.MembreRepository;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;
import java.util.UUID;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import io.quarkus.security.identity.SecurityIdentity;

import java.util.Collections;
import java.util.List;

/**
 * Resource REST pour les demandes d'aide.
 * Expose l'API attendue par le client (DemandeAideService REST client).
 */
@Path("/api/demandes-aide")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Demandes d'aide", description = "Gestion des demandes d'aide solidarité")
@RolesAllowed({ "USER", "MEMBRE", "ADMIN", "SUPER_ADMIN", "ADMIN_ORGANISATION" })
public class DemandeAideResource {

    @Inject
    DemandeAideService demandeAideService;

    @Inject
    MembreRepository membreRepository;

    @Inject
    SecurityIdentity securityIdentity;

    @GET
    @Path("/mes")
    @Operation(summary = "Mes demandes d'aide", description = "Liste les demandes du membre connecté")
    public List<DemandeAideResponse> mesDemandes(
            @QueryParam("page") @DefaultValue("0") int page,
            @QueryParam("size") @DefaultValue("50") int size) {
        String email = securityIdentity.getPrincipal().getName();
        Membre membre = membreRepository.findByEmail(email).orElse(null);
        if (membre == null) {
            return List.of();
        }
        List<DemandeAideResponse> all = demandeAideService.rechercherAvecFiltres(
                java.util.Map.of("demandeurId", membre.getId()));
        int from = Math.min(page * size, all.size());
        int to = Math.min(from + size, all.size());
        return from < to ? all.subList(from, to) : List.of();
    }

    @GET
    @Operation(summary = "Liste les demandes d'aide avec pagination")
    public List<DemandeAideResponse> listerToutes(
            @QueryParam("page") @DefaultValue("0") int page,
            @QueryParam("size") @DefaultValue("20") int size) {
        List<DemandeAideResponse> all = demandeAideService.rechercherAvecFiltres(Collections.emptyMap());
        int from = Math.min(page * size, all.size());
        int to = Math.min(from + size, all.size());
        return from < to ? all.subList(from, to) : List.of();
    }

    @GET
    @Path("/search")
    @Operation(summary = "Recherche les demandes d'aide avec filtres (statut, type, urgence)")
    public List<DemandeAideResponse> rechercher(
            @QueryParam("statut") String statut,
            @QueryParam("type") String type,
            @QueryParam("urgence") String urgence,
            @QueryParam("page") @DefaultValue("0") int page,
            @QueryParam("size") @DefaultValue("20") int size) {
        
        java.util.Map<String, Object> filtres = new java.util.HashMap<>();
        if (statut != null && !statut.isEmpty()) {
            try { filtres.put("statut", StatutAide.valueOf(statut)); } catch (IllegalArgumentException e) {}
        }
        if (type != null && !type.isEmpty()) {
            try { filtres.put("typeAide", TypeAide.valueOf(type)); } catch (IllegalArgumentException e) {}
        }
        if (urgence != null && !urgence.isEmpty()) {
            try { filtres.put("priorite", PrioriteAide.valueOf(urgence)); } catch (IllegalArgumentException e) {}
        }
        
        List<DemandeAideResponse> all = demandeAideService.rechercherAvecFiltres(filtres);
        int from = Math.min(page * size, all.size());
        int to = Math.min(from + size, all.size());
        return from < to ? all.subList(from, to) : List.of();
    }

    @GET
    @Path("/{id}")
    @Operation(summary = "Récupère une demande d'aide par son ID")
    public DemandeAideResponse obtenirParId(@PathParam("id") UUID id) {
        DemandeAideResponse response = demandeAideService.obtenirParId(id);
        if (response == null) {
            throw new NotFoundException("Demande d'aide non trouvée : " + id);
        }
        return response;
    }

    @POST
    @Operation(summary = "Crée une nouvelle demande d'aide")
    public Response creer(@Valid CreateDemandeAideRequest request) {
        DemandeAideResponse response = demandeAideService.creerDemande(request);
        return Response.status(Response.Status.CREATED).entity(response).build();
    }

    @PUT
    @Path("/{id}")
    @Operation(summary = "Met à jour une demande d'aide")
    public DemandeAideResponse mettreAJour(@PathParam("id") UUID id, @Valid UpdateDemandeAideRequest request) {
        return demandeAideService.mettreAJour(id, request);
    }

    @PUT
    @Path("/{id}/approuver")
    @Operation(summary = "Approuver une demande d'aide")
    public DemandeAideResponse approuver(@PathParam("id") UUID id, @QueryParam("motif") String motif) {
        return demandeAideService.changerStatut(id, StatutAide.APPROUVEE, motif);
    }

    @PUT
    @Path("/{id}/rejeter")
    @Operation(summary = "Rejeter une demande d'aide")
    public DemandeAideResponse rejeter(@PathParam("id") UUID id, @QueryParam("motif") String motif) {
        return demandeAideService.changerStatut(id, StatutAide.REJETEE, motif);
    }
}
