// models.rs — Estructuras de datos para GR Pautaje

use chrono::NaiveDate;
use std::fmt;

// ─── Tipo de pautaje ───────────────────────────────────────────────────────

#[derive(Debug, Clone, PartialEq)]
pub enum TipoPautaje {
    Comerciales,
    Eventos,
    EventosEnEspera,
}

impl TipoPautaje {
    /// Nombre de la subcarpeta en ~/.gradio/data/
    pub fn carpeta(&self) -> &str {
        match self {
            TipoPautaje::Comerciales    => "comerciales",
            TipoPautaje::Eventos        => "eventos",
            TipoPautaje::EventosEnEspera => "eventos-espera",
        }
    }

    pub fn label(&self) -> &str {
        match self {
            TipoPautaje::Comerciales    => "Comerciales",
            TipoPautaje::Eventos        => "Eventos",
            TipoPautaje::EventosEnEspera => "Eventos en Espera",
        }
    }

    pub fn from_index(i: u32) -> Self {
        match i {
            0 => TipoPautaje::Comerciales,
            1 => TipoPautaje::Eventos,
            2 => TipoPautaje::EventosEnEspera,
            _ => TipoPautaje::Comerciales,
        }
    }

    pub fn to_index(&self) -> u32 {
        match self {
            TipoPautaje::Comerciales    => 0,
            TipoPautaje::Eventos        => 1,
            TipoPautaje::EventosEnEspera => 2,
        }
    }
}

impl fmt::Display for TipoPautaje {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.label())
    }
}

// ─── Entrada de pautaje ────────────────────────────────────────────────────

/// Una línea del archivo .com:
///   /ruta/al/audio.mp3|1234567|20260307|20260406
///
/// `dias` = cadena de dígitos 1-7 donde cada dígito presente indica
/// que el audio se emite ese día de la semana (1=Lun … 7=Dom).
#[derive(Debug, Clone)]
pub struct EntradaPautaje {
    pub ruta: String,
    pub dias: String,
    pub inicio: NaiveDate,
    pub fin: NaiveDate,
}

impl EntradaPautaje {
    /// Nombre del archivo (con extensión)
    pub fn nombre(&self) -> String {
        std::path::Path::new(&self.ruta)
            .file_name()
            .and_then(|n| n.to_str())
            .unwrap_or(&self.ruta)
            .to_string()
    }

    /// Nombre sin extensión para mostrar en la tabla
    pub fn nombre_display(&self) -> String {
        let ruta = self.ruta.trim_end_matches('\r');
        // Entrada de carpeta aleatoria: "/ruta/carpeta/*"
        if ruta.ends_with("/*") || (ruta.ends_with('*') && ruta.contains('/')) {
            let folder = ruta.trim_end_matches('*').trim_end_matches('/');
            let folder_name = std::path::Path::new(folder)
                .file_name()
                .and_then(|n| n.to_str())
                .unwrap_or(folder);
            return format!("📁 {} (aleatoria)", folder_name);
        }
        let n = self.nombre();
        match n.rfind('.') {
            Some(pos) => n[..pos].to_string(),
            None => n,
        }
    }

    /// Serializa al formato del archivo .com (con salto de línea)
    pub fn serializar(&self) -> String {
        format!(
            "{}|{}|{}|{}\n",
            self.ruta,
            self.dias,
            self.inicio.format("%Y%m%d"),
            self.fin.format("%Y%m%d"),
        )
    }

    /// Parsea una línea del archivo .com
    pub fn parsear(linea: &str) -> Option<Self> {
        let partes: Vec<&str> = linea.trim().splitn(4, '|').collect();
        if partes.len() < 4 { return None; }
        let ruta  = partes[0].to_string();
        let dias  = partes[1].to_string();
        let inicio = NaiveDate::parse_from_str(partes[2], "%Y%m%d").ok()?;
        let fin    = NaiveDate::parse_from_str(partes[3], "%Y%m%d").ok()?;
        Some(EntradaPautaje { ruta, dias, inicio, fin })
    }

    /// Duración real del archivo de audio en segundos.
    /// Lee los metadatos del archivo sin dependencias externas.
    pub fn duracion_secs(&self) -> u64 {
        crate::duracion_audio::leer_duracion(&self.ruta)
    }

    /// Duración formateada como "M:SS" o "H:MM:SS"
    pub fn duracion_fmt(&self) -> String {
        crate::duracion_audio::formato_duracion(self.duracion_secs())
    }
}

// ─── Estado de la aplicación ───────────────────────────────────────────────

/// Estado compartido entre todos los módulos de UI (via Rc<RefCell<Estado>>)
#[derive(Debug)]
pub struct Estado {
    pub fecha_inicio: NaiveDate,
    pub fecha_fin: NaiveDate,
    /// Días activos: cadena de dígitos '1'..'7' ordenados (ej: "12345")
    pub dias: String,
    pub tipo: TipoPautaje,
    pub hora: u8,
    pub minuto: u8,
}

impl Default for Estado {
    fn default() -> Self {
        let hoy = chrono::Local::now().date_naive();
        Estado {
            fecha_inicio: hoy,
            fecha_fin: hoy,
            dias: "1234567".to_string(),
            tipo: TipoPautaje::Comerciales,
            hora: 0,
            minuto: 0,
        }
    }
}

// ─── Utilidades ────────────────────────────────────────────────────────────

/// Formatea segundos como "HH:MM:SS"
pub fn formato_hhmmss(segundos: u64) -> String {
    let h = segundos / 3600;
    let m = (segundos % 3600) / 60;
    let s = segundos % 60;
    format!("{:02}:{:02}:{:02}", h, m, s)
}
