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

/**
 * Énumération des formats d'export disponibles pour les rapports et données analytics
 *
 * <p>Cette énumération définit les différents formats dans lesquels les données peuvent être
 * exportées depuis l'application UnionFlow.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2025-01-16
 */
public enum FormatExport {

  // === FORMATS DOCUMENTS ===
  PDF("PDF", "pdf", "application/pdf", "Portable Document Format", true, true),
  WORD(
      "Word",
      "docx",
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "Microsoft Word",
      true,
      false),

  // === FORMATS TABLEURS ===
  EXCEL(
      "Excel",
      "xlsx",
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      "Microsoft Excel",
      true,
      true),
  CSV("CSV", "csv", "text/csv", "Comma Separated Values", false, true),

  // === FORMATS DONNÉES ===
  JSON("JSON", "json", "application/json", "JavaScript Object Notation", false, true),
  XML("XML", "xml", "application/xml", "eXtensible Markup Language", false, false),

  // === FORMATS IMAGES ===
  PNG("PNG", "png", "image/png", "Portable Network Graphics", true, false),
  JPEG("JPEG", "jpg", "image/jpeg", "Joint Photographic Experts Group", true, false),
  SVG("SVG", "svg", "image/svg+xml", "Scalable Vector Graphics", true, false),

  // === FORMATS SPÉCIALISÉS ===
  POWERPOINT(
      "PowerPoint",
      "pptx",
      "application/vnd.openxmlformats-officedocument.presentationml.presentation",
      "Microsoft PowerPoint",
      true,
      false),
  HTML("HTML", "html", "text/html", "HyperText Markup Language", true, false);

  private final String libelle;
  private final String extension;
  private final String mimeType;
  private final String description;
  private final boolean supporteGraphiques;
  private final boolean supporteGrandesQuantitesDonnees;

  /**
   * Constructeur de l'énumération FormatExport
   *
   * @param libelle Le libellé affiché à l'utilisateur
   * @param extension L'extension de fichier
   * @param mimeType Le type MIME du format
   * @param description La description du format
   * @param supporteGraphiques true si le format supporte les graphiques
   * @param supporteGrandesQuantitesDonnees true si le format supporte de grandes quantités de
   *     données
   */
  FormatExport(
      String libelle,
      String extension,
      String mimeType,
      String description,
      boolean supporteGraphiques,
      boolean supporteGrandesQuantitesDonnees) {
    this.libelle = libelle;
    this.extension = extension;
    this.mimeType = mimeType;
    this.description = description;
    this.supporteGraphiques = supporteGraphiques;
    this.supporteGrandesQuantitesDonnees = supporteGrandesQuantitesDonnees;
  }

  /**
   * Retourne le libellé du format
   *
   * @return Le libellé affiché à l'utilisateur
   */
  public String getLibelle() {
    return libelle;
  }

  /**
   * Retourne l'extension de fichier
   *
   * @return L'extension sans le point (ex: "pdf", "xlsx")
   */
  public String getExtension() {
    return extension;
  }

  /**
   * Retourne le type MIME du format
   *
   * @return Le type MIME complet
   */
  public String getMimeType() {
    return mimeType;
  }

  /**
   * Retourne la description du format
   *
   * @return La description complète du format
   */
  public String getDescription() {
    return description;
  }

  /**
   * Vérifie si le format supporte les graphiques
   *
   * @return true si le format peut inclure des graphiques
   */
  public boolean supporteGraphiques() {
    return supporteGraphiques;
  }

  /**
   * Vérifie si le format supporte de grandes quantités de données
   *
   * @return true si le format peut gérer de gros volumes de données
   */
  public boolean supporteGrandesQuantitesDonnees() {
    return supporteGrandesQuantitesDonnees;
  }

  /**
   * Vérifie si le format est adapté aux rapports exécutifs
   *
   * @return true si le format convient aux rapports de direction
   */
  public boolean isFormatExecutif() {
    return this == PDF || this == POWERPOINT || this == WORD;
  }

  /**
   * Vérifie si le format est adapté à l'analyse de données
   *
   * @return true si le format convient à l'analyse de données
   */
  public boolean isFormatAnalyse() {
    return this == EXCEL || this == CSV || this == JSON;
  }

  /**
   * Vérifie si le format est adapté au partage web
   *
   * @return true si le format convient au partage sur le web
   */
  public boolean isFormatWeb() {
    return this == HTML || this == PNG || this == SVG || this == JSON;
  }

  /**
   * Retourne l'icône appropriée pour le format
   *
   * @return L'icône Material Design
   */
  public String getIcone() {
    return switch (this) {
      case PDF -> "picture_as_pdf";
      case WORD -> "description";
      case EXCEL -> "table_chart";
      case CSV -> "grid_on";
      case JSON -> "code";
      case XML -> "code";
      case PNG, JPEG -> "image";
      case SVG -> "vector_image";
      case POWERPOINT -> "slideshow";
      case HTML -> "web";
    };
  }

  /**
   * Retourne la couleur appropriée pour le format
   *
   * @return Le code couleur hexadécimal
   */
  public String getCouleur() {
    return switch (this) {
      case PDF -> "#FF5722"; // Rouge-orange
      case WORD -> "#2196F3"; // Bleu
      case EXCEL -> "#4CAF50"; // Vert
      case CSV -> "#607D8B"; // Bleu gris
      case JSON -> "#FF9800"; // Orange
      case XML -> "#795548"; // Marron
      case PNG, JPEG -> "#E91E63"; // Rose
      case SVG -> "#9C27B0"; // Violet
      case POWERPOINT -> "#FF5722"; // Rouge-orange
      case HTML -> "#00BCD4"; // Cyan
    };
  }

  /**
   * Génère un nom de fichier avec l'extension appropriée
   *
   * @param nomBase Le nom de base du fichier
   * @return Le nom de fichier complet avec extension
   */
  public String genererNomFichier(String nomBase) {
    return nomBase + "." + extension;
  }

  /**
   * Retourne la taille maximale recommandée pour ce format (en MB)
   *
   * @return La taille maximale en mégaoctets
   */
  public int getTailleMaximaleRecommandee() {
    return switch (this) {
      case PDF, WORD, POWERPOINT -> 50; // 50 MB pour les documents
      case EXCEL -> 100; // 100 MB pour Excel
      case CSV, JSON, XML -> 200; // 200 MB pour les données
      case PNG, JPEG -> 10; // 10 MB pour les images
      case SVG, HTML -> 5; // 5 MB pour les formats légers
    };
  }

  /**
   * Vérifie si le format nécessite un traitement spécial
   *
   * @return true si le format nécessite un traitement particulier
   */
  public boolean necessiteTraitementSpecial() {
    return this == PDF || this == EXCEL || this == POWERPOINT || this == WORD;
  }

  /**
   * Retourne les formats recommandés pour un type de rapport donné
   *
   * @param typeRapport Le type de rapport (executif, analytique, technique)
   * @return Un tableau des formats recommandés
   */
  public static FormatExport[] getFormatsRecommandes(String typeRapport) {
    return switch (typeRapport.toLowerCase()) {
      case "executif" -> new FormatExport[] {PDF, POWERPOINT, WORD};
      case "analytique" -> new FormatExport[] {EXCEL, CSV, JSON, PDF};
      case "technique" -> new FormatExport[] {JSON, XML, CSV, HTML};
      case "partage" -> new FormatExport[] {PDF, PNG, HTML};
      default -> new FormatExport[] {PDF, EXCEL, CSV};
    };
  }
}
