package dev.lions.unionflow.server.api.dto.notification;

import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.validation.constraints.*;
import java.util.Map;

/**
 * DTO pour les actions rapides des notifications UnionFlow
 *
 * <p>Ce DTO représente une action que l'utilisateur peut exécuter directement depuis la
 * notification sans ouvrir l'application.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2025-01-16
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ActionNotificationDTO {

  /** Identifiant unique de l'action */
  @NotBlank(message = "L'identifiant de l'action est obligatoire")
  private String id;

  /** Libellé affiché sur le bouton d'action */
  @NotBlank(message = "Le libellé de l'action est obligatoire")
  @Size(max = 30, message = "Le libellé ne peut pas dépasser 30 caractères")
  private String libelle;

  /** Description de l'action (tooltip) */
  @Size(max = 100, message = "La description ne peut pas dépasser 100 caractères")
  private String description;

  /** Type d'action à exécuter */
  @NotBlank(message = "Le type d'action est obligatoire")
  private String typeAction;

  /** Icône de l'action (Material Design) */
  private String icone;

  /** Couleur de l'action (hexadécimal) */
  private String couleur;

  /** URL à ouvrir (pour les actions de type "url") */
  private String url;

  /** Route de l'application à ouvrir (pour les actions de type "route") */
  private String route;

  /** Paramètres de l'action */
  private Map<String, String> parametres;

  /** Indique si l'action ferme la notification */
  private Boolean fermeNotification;

  /** Indique si l'action nécessite une confirmation */
  private Boolean necessiteConfirmation;

  /** Message de confirmation à afficher */
  private String messageConfirmation;

  /** Indique si l'action est destructive (suppression, etc.) */
  private Boolean estDestructive;

  /** Ordre d'affichage de l'action */
  private Integer ordre;

  /** Indique si l'action est activée */
  private Boolean estActivee;

  /** Condition d'affichage de l'action (expression) */
  private String conditionAffichage;

  /** Rôles autorisés à exécuter cette action */
  private String[] rolesAutorises;

  /** Permissions requises pour exécuter cette action */
  private String[] permissionsRequises;

  /** Délai d'expiration de l'action en minutes */
  private Integer delaiExpirationMinutes;

  /** Nombre maximum d'exécutions autorisées */
  private Integer maxExecutions;

  /** Nombre d'exécutions actuelles */
  private Integer nombreExecutions;

  /** Indique si l'action peut être exécutée plusieurs fois */
  private Boolean peutEtreRepetee;

  /** Style du bouton (primary, secondary, outline, text) */
  private String styleBouton;

  /** Taille du bouton (small, medium, large) */
  private String tailleBouton;

  /** Position du bouton (left, center, right) */
  private String positionBouton;

  /** Données personnalisées de l'action */
  private Map<String, Object> donneesPersonnalisees;

  // === CONSTRUCTEURS ===

  /** Constructeur par défaut */
  public ActionNotificationDTO() {
    this.fermeNotification = true;
    this.necessiteConfirmation = false;
    this.estDestructive = false;
    this.ordre = 0;
    this.estActivee = true;
    this.maxExecutions = 1;
    this.nombreExecutions = 0;
    this.peutEtreRepetee = false;
    this.styleBouton = "primary";
    this.tailleBouton = "medium";
    this.positionBouton = "right";
  }

  /** Constructeur avec paramètres essentiels */
  public ActionNotificationDTO(String id, String libelle, String typeAction) {
    this();
    this.id = id;
    this.libelle = libelle;
    this.typeAction = typeAction;
  }

  /** Constructeur pour action URL */
  public ActionNotificationDTO(String id, String libelle, String url, String icone) {
    this(id, libelle, "url");
    this.url = url;
    this.icone = icone;
  }

  /** Constructeur pour action de route */
  public ActionNotificationDTO(
      String id, String libelle, String route, String icone, Map<String, String> parametres) {
    this(id, libelle, "route");
    this.route = route;
    this.icone = icone;
    this.parametres = parametres;
  }

  // === GETTERS ET SETTERS ===

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getLibelle() {
    return libelle;
  }

  public void setLibelle(String libelle) {
    this.libelle = libelle;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getTypeAction() {
    return typeAction;
  }

  public void setTypeAction(String typeAction) {
    this.typeAction = typeAction;
  }

  public String getIcone() {
    return icone;
  }

  public void setIcone(String icone) {
    this.icone = icone;
  }

  public String getCouleur() {
    return couleur;
  }

  public void setCouleur(String couleur) {
    this.couleur = couleur;
  }

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  public String getRoute() {
    return route;
  }

  public void setRoute(String route) {
    this.route = route;
  }

  public Map<String, String> getParametres() {
    return parametres;
  }

  public void setParametres(Map<String, String> parametres) {
    this.parametres = parametres;
  }

  public Boolean getFermeNotification() {
    return fermeNotification;
  }

  public void setFermeNotification(Boolean fermeNotification) {
    this.fermeNotification = fermeNotification;
  }

  public Boolean getNecessiteConfirmation() {
    return necessiteConfirmation;
  }

  public void setNecessiteConfirmation(Boolean necessiteConfirmation) {
    this.necessiteConfirmation = necessiteConfirmation;
  }

  public String getMessageConfirmation() {
    return messageConfirmation;
  }

  public void setMessageConfirmation(String messageConfirmation) {
    this.messageConfirmation = messageConfirmation;
  }

  public Boolean getEstDestructive() {
    return estDestructive;
  }

  public void setEstDestructive(Boolean estDestructive) {
    this.estDestructive = estDestructive;
  }

  public Integer getOrdre() {
    return ordre;
  }

  public void setOrdre(Integer ordre) {
    this.ordre = ordre;
  }

  public Boolean getEstActivee() {
    return estActivee;
  }

  public void setEstActivee(Boolean estActivee) {
    this.estActivee = estActivee;
  }

  public String getConditionAffichage() {
    return conditionAffichage;
  }

  public void setConditionAffichage(String conditionAffichage) {
    this.conditionAffichage = conditionAffichage;
  }

  public String[] getRolesAutorises() {
    return rolesAutorises;
  }

  public void setRolesAutorises(String[] rolesAutorises) {
    this.rolesAutorises = rolesAutorises;
  }

  public String[] getPermissionsRequises() {
    return permissionsRequises;
  }

  public void setPermissionsRequises(String[] permissionsRequises) {
    this.permissionsRequises = permissionsRequises;
  }

  public Integer getDelaiExpirationMinutes() {
    return delaiExpirationMinutes;
  }

  public void setDelaiExpirationMinutes(Integer delaiExpirationMinutes) {
    this.delaiExpirationMinutes = delaiExpirationMinutes;
  }

  public Integer getMaxExecutions() {
    return maxExecutions;
  }

  public void setMaxExecutions(Integer maxExecutions) {
    this.maxExecutions = maxExecutions;
  }

  public Integer getNombreExecutions() {
    return nombreExecutions;
  }

  public void setNombreExecutions(Integer nombreExecutions) {
    this.nombreExecutions = nombreExecutions;
  }

  public Boolean getPeutEtreRepetee() {
    return peutEtreRepetee;
  }

  public void setPeutEtreRepetee(Boolean peutEtreRepetee) {
    this.peutEtreRepetee = peutEtreRepetee;
  }

  public String getStyleBouton() {
    return styleBouton;
  }

  public void setStyleBouton(String styleBouton) {
    this.styleBouton = styleBouton;
  }

  public String getTailleBouton() {
    return tailleBouton;
  }

  public void setTailleBouton(String tailleBouton) {
    this.tailleBouton = tailleBouton;
  }

  public String getPositionBouton() {
    return positionBouton;
  }

  public void setPositionBouton(String positionBouton) {
    this.positionBouton = positionBouton;
  }

  public Map<String, Object> getDonneesPersonnalisees() {
    return donneesPersonnalisees;
  }

  public void setDonneesPersonnalisees(Map<String, Object> donneesPersonnalisees) {
    this.donneesPersonnalisees = donneesPersonnalisees;
  }

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

  /** Vérifie si l'action peut être exécutée */
  public boolean peutEtreExecutee() {
    return estActivee && (nombreExecutions < maxExecutions || peutEtreRepetee);
  }

  /** Vérifie si l'action est expirée */
  public boolean isExpiree() {
    // Implémentation basée sur delaiExpirationMinutes et date de création de la notification
    return false; // À implémenter selon la logique métier
  }

  /** Incrémente le nombre d'exécutions */
  public void incrementerExecutions() {
    if (nombreExecutions == null) {
      nombreExecutions = 0;
    }
    nombreExecutions++;
  }

  /** Vérifie si l'utilisateur a les permissions requises */
  public boolean utilisateurAutorise(String[] rolesUtilisateur, String[] permissionsUtilisateur) {
    // Vérification des rôles
    if (rolesAutorises != null && rolesAutorises.length > 0) {
      boolean roleAutorise = false;
      for (String roleRequis : rolesAutorises) {
        for (String roleUtilisateur : rolesUtilisateur) {
          if (roleRequis.equals(roleUtilisateur)) {
            roleAutorise = true;
            break;
          }
        }
        if (roleAutorise) break;
      }
      if (!roleAutorise) return false;
    }

    // Vérification des permissions
    if (permissionsRequises != null && permissionsRequises.length > 0) {
      boolean permissionAutorisee = false;
      for (String permissionRequise : permissionsRequises) {
        for (String permissionUtilisateur : permissionsUtilisateur) {
          if (permissionRequise.equals(permissionUtilisateur)) {
            permissionAutorisee = true;
            break;
          }
        }
        if (permissionAutorisee) break;
      }
      if (!permissionAutorisee) return false;
    }

    return true;
  }

  /** Retourne la couleur par défaut selon le type d'action */
  public String getCouleurParDefaut() {
    if (couleur != null) return couleur;

    return switch (typeAction) {
      case "confirm" -> "#4CAF50"; // Vert pour confirmation
      case "cancel" -> "#F44336"; // Rouge pour annulation
      case "info" -> "#2196F3"; // Bleu pour information
      case "warning" -> "#FF9800"; // Orange pour avertissement
      case "url", "route" -> "#2196F3"; // Bleu pour navigation
      default -> "#9E9E9E"; // Gris par défaut
    };
  }

  /** Retourne l'icône par défaut selon le type d'action */
  public String getIconeParDefaut() {
    if (icone != null) return icone;

    return switch (typeAction) {
      case "confirm" -> "check";
      case "cancel" -> "close";
      case "info" -> "info";
      case "warning" -> "warning";
      case "url" -> "open_in_new";
      case "route" -> "arrow_forward";
      case "call" -> "phone";
      case "message" -> "message";
      case "email" -> "email";
      case "share" -> "share";
      default -> "touch_app";
    };
  }

  /** Crée une action de confirmation */
  public static ActionNotificationDTO creerActionConfirmation(String id, String libelle) {
    ActionNotificationDTO action = new ActionNotificationDTO(id, libelle, "confirm");
    action.setCouleur("#4CAF50");
    action.setIcone("check");
    action.setStyleBouton("primary");
    return action;
  }

  /** Crée une action d'annulation */
  public static ActionNotificationDTO creerActionAnnulation(String id, String libelle) {
    ActionNotificationDTO action = new ActionNotificationDTO(id, libelle, "cancel");
    action.setCouleur("#F44336");
    action.setIcone("close");
    action.setStyleBouton("outline");
    action.setEstDestructive(true);
    return action;
  }

  /** Crée une action de navigation */
  public static ActionNotificationDTO creerActionNavigation(
      String id, String libelle, String route) {
    ActionNotificationDTO action = new ActionNotificationDTO(id, libelle, "route");
    action.setRoute(route);
    action.setCouleur("#2196F3");
    action.setIcone("arrow_forward");
    return action;
  }

  @Override
  public String toString() {
    return String.format(
        "ActionNotificationDTO{id='%s', libelle='%s', type='%s'}", id, libelle, typeAction);
  }
}
