package dev.lions.unionflow.server.api.dto.solidarite.response;

import dev.lions.unionflow.server.api.dto.base.BaseResponse;
import dev.lions.unionflow.server.api.dto.solidarite.PieceJustificativeDTO;
import dev.lions.unionflow.server.api.enums.solidarite.StatutEvaluation;
import dev.lions.unionflow.server.api.enums.solidarite.TypeEvaluation;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
 * Réponse détaillée pour une évaluation d'aide.
 */
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EvaluationAideResponse extends BaseResponse {

    private UUID demandeAideId;
    private UUID propositionAideId;
    private UUID evaluateurId;
    private String evaluateurNom;
    private String roleEvaluateur;
    private TypeEvaluation typeEvaluation;
    private Double noteGlobale;
    private Map<String, Double> notesDetaillees;
    private String commentairePrincipal;
    private String pointsPositifs;
    private String pointsAmelioration;
    private String recommandations;
    private Boolean recommande;
    private Boolean aideUtile;
    private Boolean problemeResolu;
    private Double noteDelaiReponse;
    private Double noteCommunication;
    private Double noteProfessionnalisme;
    private Double noteRespectEngagements;
    private Boolean estPublique;
    private Boolean estAnonyme;
    private Boolean estVerifiee;
    private LocalDateTime dateVerification;
    private UUID verificateurId;
    private List<PieceJustificativeDTO> piecesJointes;
    private List<String> tags;
    private Map<String, Object> donneesAdditionnelles;
    private Integer nombreUtile;
    private Integer nombreSignalements;
    private StatutEvaluation statut;

    // === MÉTHODES UTILITAIRES ===

    public Double getNoteMoyenneDetaillees() {
        if (notesDetaillees == null || notesDetaillees.isEmpty()) {
            return noteGlobale;
        }

        return notesDetaillees.values().stream()
                .mapToDouble(Double::doubleValue)
                .average()
                .orElse(noteGlobale != null ? noteGlobale : 0.0);
    }

    public boolean isPositive() {
        return noteGlobale != null && noteGlobale >= 4.0;
    }

    public boolean isNegative() {
        return noteGlobale != null && noteGlobale <= 2.0;
    }

    public double getScoreQualite() {
        double score = noteGlobale != null ? noteGlobale : 0.0;

        if (noteDelaiReponse != null)
            score += noteDelaiReponse * 0.1;
        if (noteCommunication != null)
            score += noteCommunication * 0.1;
        if (noteProfessionnalisme != null)
            score += noteProfessionnalisme * 0.1;
        if (noteRespectEngagements != null)
            score += noteRespectEngagements * 0.1;

        if (recommande != null && recommande)
            score += 0.2;
        if (problemeResolu != null && problemeResolu)
            score += 0.3;

        if (nombreSignalements != null && nombreSignalements > 0)
            score -= nombreSignalements * 0.1;

        return Math.min(5.0, Math.max(0.0, score));
    }

    public boolean isComplete() {
        boolean noteOk = noteGlobale != null;
        boolean commentaireNonVide = commentairePrincipal != null && !commentairePrincipal.trim().isEmpty();
        boolean recommandeOk = recommande != null;
        boolean aideUtileOk = aideUtile != null;
        boolean problemeResoluOk = problemeResolu != null;
        return noteOk & commentaireNonVide & recommandeOk & aideUtileOk & problemeResoluOk;
    }

    public String getNiveauSatisfaction() {
        if (noteGlobale == null)
            return "Non évalué";

        return switch (noteGlobale.intValue()) {
            case 5 -> "Excellent";
            case 4 -> "Très bien";
            case 3 -> "Bien";
            case 2 -> "Passable";
            case 1 -> "Insuffisant";
            default -> "Non évalué";
        };
    }
}
