// ui/comun.rs — Funciones compartidas entre módulos de UI

use gtk4 as gtk;
use gtk::prelude::*;
use gtk::{ApplicationWindow, ListStore, TreeView};
use gdk4;
use crate::models::TipoPautaje;
use crate::storage;

/// Establece el ícono de la ventana (taskbar/titlebar) desde bytes PNG embebidos
pub fn aplicar_icono_ventana(ventana: &ApplicationWindow, bytes: &[u8]) {
    let loader = gdk4::gdk_pixbuf::PixbufLoader::new();
    let _ = loader.write(bytes);
    let _ = loader.close();
    if let Some(pb) = loader.pixbuf() {
        let tex = gdk4::Texture::for_pixbuf(&pb);
        ventana.connect_realize(move |w| {
            if let Some(surf) = w.surface() {
                use gdk4::prelude::ToplevelExt;
                if let Some(tl) = surf.dynamic_cast_ref::<gdk4::Toplevel>() {
                    tl.set_icon_list(&[tex.clone()]);
                }
            }
        });
    }
}

/// Ajusta el tamaño de la ventana según la resolución del monitor.
/// Nunca supera max_ancho/max_alto y nunca excede el área visible del monitor
/// (resta ~90px de título + taskbar). Usar 0 en max_ancho/max_alto = sin límite.
pub fn aplicar_tamanio_ventana(ventana: &ApplicationWindow, max_ancho: i32, max_alto: i32) {
    aplicar_tamanio_ventana_pct(ventana, 1.0, 1.0, max_ancho, max_alto);
}

/// Igual que aplicar_tamanio_ventana pero el tamaño base es un porcentaje
/// del monitor (pct_ancho, pct_alto ∈ 0.0-1.0). max_* recorta si el porcentaje
/// resulta mayor que el máximo deseado; 0 = sin límite superior.
pub fn aplicar_tamanio_ventana_pct(
    ventana: &ApplicationWindow,
    pct_ancho: f64,
    pct_alto: f64,
    max_ancho: i32,
    max_alto: i32,
) {
    let win = ventana.clone();
    ventana.connect_realize(move |w| {
        if let Some(surf) = w.surface() {
            let display = gtk4::prelude::WidgetExt::display(w);
            use gdk4::prelude::DisplayExt;
            if let Some(monitor) = display.monitor_at_surface(&surf) {
                use gdk4::prelude::MonitorExt;
                // geometry() ya excluye taskbars/paneles; solo restamos barra de título (~30px)
                let geo = monitor.geometry();
                let disponible_ancho = ((geo.width() as f64 * pct_ancho) as i32 - 20).max(400);
                let disponible_alto  = ((geo.height() as f64 * pct_alto)  as i32 - 90).max(400);
                let ancho = if max_ancho > 0 { disponible_ancho.min(max_ancho) } else { disponible_ancho };
                let alto  = if max_alto  > 0 { disponible_alto.min(max_alto)   } else { disponible_alto  };
                win.set_default_size(ancho, alto);
            }
        }
    });
}

/// Recarga el ListStore con las entradas del corte actual
pub fn recargar_store(store: &ListStore, tipo: &TipoPautaje, hora: u8, minuto: u8) {
    store.clear();
    let entradas = storage::leer_entradas(tipo, hora, minuto);
    for entrada in &entradas {
        store.insert_with_values(
            None,
            &[
                (0, &entrada.nombre_display()),
                (1, &entrada.dias),
                (2, &entrada.inicio.format("%Y%m%d").to_string()),
                (3, &entrada.fin.format("%Y%m%d").to_string()),
                (4, &entrada.ruta),
            ],
        );
    }
}

/// Retorna el índice (0-based) de la fila seleccionada en el TreeView
pub fn seleccion_indice(tree: &TreeView) -> Option<usize> {
    let (paths, _) = tree.selection().selected_rows();
    paths.first().and_then(|p| {
        p.indices().first().map(|i| *i as usize)
    })
}

/// Selecciona la fila en el índice dado
pub fn seleccionar_fila(tree: &TreeView, idx: usize) {
    if let Some(path) = gtk::TreePath::from_string(&idx.to_string()) {
        tree.selection().select_path(&path);
    }
}
