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

/**
 * Énumération des canaux de notification pour Android et iOS
 *
 * <p>Cette énumération définit les différents canaux de notification utilisés pour organiser et
 * prioriser les notifications push dans UnionFlow.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2025-01-16
 */
public enum CanalNotification {

  // === CANAUX PAR PRIORITÉ ===
  URGENT_CHANNEL(
      "urgent",
      "Notifications urgentes",
      "Alertes critiques nécessitant une action immédiate",
      5,
      true,
      true,
      true,
      "urgent",
      "#F44336"),

  ERROR_CHANNEL(
      "error",
      "Erreurs système",
      "Notifications d'erreurs et de problèmes techniques",
      4,
      true,
      true,
      false,
      "error",
      "#F44336"),

  WARNING_CHANNEL(
      "warning",
      "Avertissements",
      "Notifications d'avertissement et d'attention",
      4,
      true,
      true,
      false,
      "warning",
      "#FF9800"),

  IMPORTANT_CHANNEL(
      "important",
      "Notifications importantes",
      "Informations importantes à ne pas manquer",
      4,
      true,
      true,
      false,
      "important",
      "#FF5722"),

  REMINDER_CHANNEL(
      "reminder",
      "Rappels",
      "Rappels d'événements, cotisations et échéances",
      3,
      true,
      true,
      false,
      "reminder",
      "#2196F3"),

  SUCCESS_CHANNEL(
      "success",
      "Confirmations",
      "Notifications de succès et confirmations",
      2,
      false,
      false,
      false,
      "success",
      "#4CAF50"),

  CELEBRATION_CHANNEL(
      "celebration",
      "Célébrations",
      "Anniversaires, félicitations et événements joyeux",
      2,
      false,
      false,
      false,
      "celebration",
      "#FF9800"),

  DEFAULT_CHANNEL(
      "default",
      "Notifications générales",
      "Notifications d'information générale",
      2,
      false,
      false,
      false,
      "info",
      "#2196F3"),

  // === CANAUX PAR CATÉGORIE ===
  EVENTS_CHANNEL(
      "events",
      "Événements",
      "Notifications liées aux événements et activités",
      3,
      true,
      false,
      false,
      "event",
      "#2196F3"),

  PAYMENTS_CHANNEL(
      "payments",
      "Paiements",
      "Notifications de cotisations et paiements",
      4,
      true,
      true,
      false,
      "payment",
      "#4CAF50"),

  SOLIDARITY_CHANNEL(
      "solidarity",
      "Solidarité",
      "Notifications d'aide et de solidarité",
      3,
      true,
      false,
      false,
      "help",
      "#E91E63"),

  MEMBERS_CHANNEL(
      "members",
      "Membres",
      "Notifications concernant les membres",
      2,
      false,
      false,
      false,
      "people",
      "#2196F3"),

  ORGANIZATION_CHANNEL(
      "organization",
      "Organisation",
      "Annonces et informations organisationnelles",
      3,
      true,
      false,
      false,
      "business",
      "#2196F3"),

  SYSTEM_CHANNEL(
      "system",
      "Système",
      "Notifications système et maintenance",
      2,
      false,
      false,
      false,
      "settings",
      "#607D8B"),

  MESSAGES_CHANNEL(
      "messages",
      "Messages",
      "Messages privés et communications",
      3,
      true,
      false,
      false,
      "message",
      "#2196F3"),

  LOCATION_CHANNEL(
      "location",
      "Géolocalisation",
      "Notifications basées sur la localisation",
      2,
      false,
      false,
      false,
      "location_on",
      "#4CAF50");

  private final String id;
  private final String nom;
  private final String description;
  private final int importance;
  private final boolean sonActive;
  private final boolean vibrationActive;
  private final boolean lumiereLED;
  private final String typeDefaut;
  private final String couleur;

  /**
   * Constructeur de l'énumération CanalNotification
   *
   * @param id L'identifiant unique du canal
   * @param nom Le nom affiché du canal
   * @param description La description du canal
   * @param importance Le niveau d'importance (1=Min, 2=Low, 3=Default, 4=High, 5=Max)
   * @param sonActive true si le son est activé par défaut
   * @param vibrationActive true si la vibration est activée par défaut
   * @param lumiereLED true si la lumière LED est activée par défaut
   * @param typeDefaut Le type de notification par défaut pour ce canal
   * @param couleur La couleur hexadécimale du canal
   */
  CanalNotification(
      String id,
      String nom,
      String description,
      int importance,
      boolean sonActive,
      boolean vibrationActive,
      boolean lumiereLED,
      String typeDefaut,
      String couleur) {
    this.id = id;
    this.nom = nom;
    this.description = description;
    this.importance = importance;
    this.sonActive = sonActive;
    this.vibrationActive = vibrationActive;
    this.lumiereLED = lumiereLED;
    this.typeDefaut = typeDefaut;
    this.couleur = couleur;
  }

  /**
   * Retourne l'identifiant du canal
   *
   * @return L'ID unique du canal
   */
  public String getId() {
    return id;
  }

  /**
   * Retourne le nom du canal
   *
   * @return Le nom affiché du canal
   */
  public String getNom() {
    return nom;
  }

  /**
   * Retourne la description du canal
   *
   * @return La description détaillée du canal
   */
  public String getDescription() {
    return description;
  }

  /**
   * Retourne le niveau d'importance
   *
   * @return Le niveau d'importance (1-5)
   */
  public int getImportance() {
    return importance;
  }

  /**
   * Vérifie si le son est activé par défaut
   *
   * @return true si le son est activé
   */
  public boolean isSonActive() {
    return sonActive;
  }

  /**
   * Vérifie si la vibration est activée par défaut
   *
   * @return true si la vibration est activée
   */
  public boolean isVibrationActive() {
    return vibrationActive;
  }

  /**
   * Vérifie si la lumière LED est activée par défaut
   *
   * @return true si la lumière LED est activée
   */
  public boolean isLumiereLED() {
    return lumiereLED;
  }

  /**
   * Retourne le type de notification par défaut
   *
   * @return Le type par défaut pour ce canal
   */
  public String getTypeDefaut() {
    return typeDefaut;
  }

  /**
   * Retourne la couleur du canal
   *
   * @return Le code couleur hexadécimal
   */
  public String getCouleur() {
    return couleur;
  }

  /**
   * Vérifie si le canal est critique
   *
   * @return true si le canal a une importance élevée (4-5)
   */
  public boolean isCritique() {
    return importance >= 4;
  }

  /**
   * Vérifie si le canal est silencieux par défaut
   *
   * @return true si le canal n'émet ni son ni vibration
   */
  public boolean isSilencieux() {
    boolean pasDeSon = !sonActive;
    boolean pasDeVibration = !vibrationActive;
    return pasDeSon & pasDeVibration;
  }

  /**
   * Retourne le niveau d'importance Android
   *
   * @return Le niveau d'importance pour Android (IMPORTANCE_MIN à IMPORTANCE_MAX)
   */
  public String getImportanceAndroid() {
    return switch (importance) {
      case 1 -> "IMPORTANCE_MIN";
      case 2 -> "IMPORTANCE_LOW";
      case 3 -> "IMPORTANCE_DEFAULT";
      case 4 -> "IMPORTANCE_HIGH";
      case 5 -> "IMPORTANCE_MAX";
      default -> "IMPORTANCE_DEFAULT";
    };
  }

  /**
   * Retourne la priorité iOS
   *
   * @return La priorité pour iOS (low ou high)
   */
  public String getPrioriteIOS() {
    return importance >= 4 ? "high" : "low";
  }

  /**
   * Retourne le son par défaut pour le canal
   *
   * @return Le nom du fichier son ou "default"
   */
  public String getSonDefaut() {
    return switch (this) {
      case URGENT_CHANNEL -> "urgent_sound.mp3";
      case ERROR_CHANNEL -> "error_sound.mp3";
      case WARNING_CHANNEL -> "warning_sound.mp3";
      case IMPORTANT_CHANNEL -> "important_sound.mp3";
      case REMINDER_CHANNEL -> "reminder_sound.mp3";
      case SUCCESS_CHANNEL -> "success_sound.mp3";
      case CELEBRATION_CHANNEL -> "celebration_sound.mp3";
      default -> "default";
    };
  }

  /**
   * Retourne le pattern de vibration
   *
   * @return Le pattern de vibration en millisecondes
   */
  public long[] getPatternVibration() {
    return switch (this) {
      case URGENT_CHANNEL -> new long[] {0, 500, 200, 500, 200, 500}; // Triple vibration
      case ERROR_CHANNEL -> new long[] {0, 1000, 500, 1000}; // Double vibration longue
      case WARNING_CHANNEL -> new long[] {0, 300, 200, 300}; // Double vibration courte
      case IMPORTANT_CHANNEL -> new long[] {0, 500, 100, 200}; // Vibration distinctive
      case REMINDER_CHANNEL -> new long[] {0, 200, 100, 200}; // Vibration douce
      default -> new long[] {0, 250}; // Vibration simple
    };
  }

  /**
   * Vérifie si le canal peut être désactivé par l'utilisateur
   *
   * @return true si l'utilisateur peut désactiver ce canal
   */
  public boolean peutEtreDesactive() {
    return this != URGENT_CHANNEL && this != ERROR_CHANNEL;
  }

  /**
   * Retourne la durée de vie par défaut des notifications de ce canal
   *
   * @return La durée de vie en millisecondes
   */
  public long getDureeVieMs() {
    return switch (this) {
      case URGENT_CHANNEL -> 3600000L; // 1 heure
      case ERROR_CHANNEL -> 86400000L; // 24 heures
      case WARNING_CHANNEL -> 172800000L; // 48 heures
      case IMPORTANT_CHANNEL -> 259200000L; // 72 heures
      case REMINDER_CHANNEL -> 86400000L; // 24 heures
      case SUCCESS_CHANNEL -> 172800000L; // 48 heures
      case CELEBRATION_CHANNEL -> 259200000L; // 72 heures
      default -> 604800000L; // 1 semaine
    };
  }

  /**
   * Trouve un canal par son ID
   *
   * @param id L'identifiant du canal
   * @return Le canal correspondant ou DEFAULT_CHANNEL si non trouvé
   */
  public static CanalNotification parId(String id) {
    for (CanalNotification canal : values()) {
      if (canal.getId().equals(id)) {
        return canal;
      }
    }
    return DEFAULT_CHANNEL;
  }

  /**
   * Retourne tous les canaux critiques
   *
   * @return Un tableau des canaux critiques
   */
  public static CanalNotification[] getCanauxCritiques() {
    return new CanalNotification[] {
      URGENT_CHANNEL, ERROR_CHANNEL, WARNING_CHANNEL, IMPORTANT_CHANNEL
    };
  }

  /**
   * Retourne tous les canaux par catégorie
   *
   * @return Un tableau des canaux catégoriels
   */
  public static CanalNotification[] getCanauxCategories() {
    return new CanalNotification[] {
      EVENTS_CHANNEL,
      PAYMENTS_CHANNEL,
      SOLIDARITY_CHANNEL,
      MEMBERS_CHANNEL,
      ORGANIZATION_CHANNEL,
      SYSTEM_CHANNEL,
      MESSAGES_CHANNEL,
      LOCATION_CHANNEL
    };
  }
}
