// ui/ventana_principal.rs — Ventana principal de GR Pautaje

use gtk4 as gtk;
use gtk::prelude::*;
use gtk::{
    Application, ApplicationWindow, Box as GtkBox, Button, ComboBoxText,
    Label, Orientation, Paned, ScrolledWindow, Separator,
    TreeView, TreeViewColumn, CellRendererText, ListStore, DropTarget,
};
use gtk::gdk;
use gdk4::FileList;
use glib;
use std::cell::RefCell;
use std::rc::Rc;
use chrono::{Local, NaiveDate};

use crate::i18n::tr;
use crate::models::{Estado, TipoPautaje};
use crate::storage;
use crate::ui::comun::{aplicar_icono_ventana, aplicar_tamanio_ventana_pct, recargar_store, seleccion_indice, seleccionar_fila};
use crate::ui::panel_arbol::construir_panel_arbol;
use crate::ui::dialogo_url::mostrar_dialogo_url;
use crate::skin;

const ICONO_PAUTAJE: &[u8] = include_bytes!("../../assets/pautaje48x48.png");

pub fn construir_ui(app: &Application) {
    storage::crear_directorios();

    let estado = Rc::new(RefCell::new(Estado::default()));

    let ventana = ApplicationWindow::builder()
        .application(app)
        .title(tr("win.pautaje"))
        .default_width(970)
        .default_height(700)
        .build();

    // CSS — usar display de la ventana, no el global
    let css = gtk::CssProvider::new();
    css.load_from_data(concat!(
        "button.dia-on {",
        "  background-image: image(#2e7d32); color: white;",
        "  padding: 6px 8px; min-height: 28px;",
        "}",
        "button.dia-on:hover { background-image: image(#388e3c); }",
        "button.todos-on {",
        "  background-image: image(#1565c0); color: white;",
        "  padding: 6px 8px; min-height: 28px;",
        "}",
        "button.todos-on:hover { background-image: image(#1976d2); }",
    ));
    gtk::style_context_add_provider_for_display(
        &gtk4::prelude::WidgetExt::display(&ventana),
        &css,
        gtk::STYLE_PROVIDER_PRIORITY_USER,
    );
    skin::aplicar_css_extra(&gtk4::prelude::WidgetExt::display(&ventana));

    let vbox_raiz = GtkBox::new(Orientation::Vertical, 0);

    // ── Fila 1: Fechas + Días de semana ──────────────────────────────────
    let fila_fechas = construir_fila_fechas(estado.clone());
    vbox_raiz.append(&fila_fechas);
    vbox_raiz.append(&Separator::new(Orientation::Horizontal));

    // ListStore: Comercial | LMXJVSD | Inicio | Fin | Ruta
    let store = ListStore::new(&[
        glib::Type::STRING,
        glib::Type::STRING,
        glib::Type::STRING,
        glib::Type::STRING,
        glib::Type::STRING,
    ]);

    // TreeView del panel derecho
    let tree_pautaje = Rc::new(construir_tree_pautaje(&store));

    // ── DropTarget para archivos externos desde Nemo (igual que botonera) ──
    {
        let st = store.clone();
        let ec = estado.clone();

        let drop_target = DropTarget::new(gtk::gio::File::static_type(), gdk::DragAction::COPY);

        drop_target.connect_drop(move |_, value, _, _| {
            if let Ok(file) = value.get::<gtk::gio::File>() {
                if let Some(path) = file.path() {
                    let ext = path.extension()
                        .and_then(|e| e.to_str())
                        .unwrap_or("")
                        .to_lowercase();
                    if matches!(ext.as_str(), "mp3"|"wav"|"ogg"|"flac"|"aac"|"m4a"|"gradio") {
                        let e = ec.borrow();
                        let entrada = crate::models::EntradaPautaje {
                            ruta: path.to_string_lossy().to_string(),
                            dias: e.dias.clone(),
                            inicio: e.fecha_inicio,
                            fin: e.fecha_fin,
                        };
                        // Guardar al archivo .com en disco
                        storage::agregar_entrada_siempre(&e.tipo, e.hora, e.minuto, entrada);
                        // Recargar la UI desde el archivo
                        crate::ui::comun::recargar_store(&st, &e.tipo, e.hora, e.minuto);
                        return true;
                    }
                }
            }
            false
        });

        tree_pautaje.add_controller(drop_target);
    }

    // Etiquetas de tiempo
    let lbl_acumulado = Label::new(Some("00:00:00"));
    lbl_acumulado.set_tooltip_text(Some(tr("paut.tip_acumulado")));
    let lbl_corte = Label::new(Some("00:00:00"));
    lbl_corte.set_tooltip_text(Some(tr("paut.tip_corte")));

    // ── Fila 2: Barra de herramientas ─────────────────────────────────────
    let fila_herr = construir_fila_herramientas(
        estado.clone(),
        store.clone(),
        tree_pautaje.clone(),
        lbl_acumulado.clone(),
        lbl_corte.clone(),
        &ventana,
    );
    vbox_raiz.append(&fila_herr);
    vbox_raiz.append(&Separator::new(Orientation::Horizontal));

    // ── Panel principal: árbol izq + tabla derecha ─────────────────────────
    let paned = Paned::new(Orientation::Horizontal);
    paned.set_vexpand(true);
    paned.set_position(380);

    let panel_izq = construir_panel_arbol(
        estado.clone(),
        store.clone(),
        lbl_acumulado,
        lbl_corte,
    );
    paned.set_start_child(Some(&panel_izq));

    let scroll_der = ScrolledWindow::new();
    scroll_der.set_hexpand(true);
    scroll_der.set_vexpand(true);
    scroll_der.set_child(Some(tree_pautaje.as_ref()));
    paned.set_end_child(Some(&scroll_der));

    vbox_raiz.append(&paned);
    ventana.set_child(Some(&vbox_raiz));
    aplicar_icono_ventana(&ventana, &skin::icono("pautaje48x48.png", ICONO_PAUTAJE));

    // 60 % del ancho, todo el alto disponible (sin límite superior de alto)
    aplicar_tamanio_ventana_pct(&ventana, 0.60, 1.0, 0, 0);

    ventana.present();
}

// ─── TreeView del panel de pautaje ────────────────────────────────────────

fn construir_tree_pautaje(store: &ListStore) -> TreeView {
    let tree = TreeView::with_model(store);
    tree.set_headers_visible(true);
    let columnas: &[(&str, i32, i32)] = &[
        (tr("paut.col_comercial"), 0, 340),
        (tr("paut.col_dias"),      1,  80),
        (tr("paut.col_inicio"),    2,  80),
        (tr("paut.col_fin"),       3,  80),
        (tr("paut.col_ruta"),      4, 240),
    ];
    for &(titulo, idx, ancho) in columnas {
        let renderer = CellRendererText::new();
        let col = TreeViewColumn::new();
        col.set_title(titulo);
        col.pack_start(&renderer, true);
        col.add_attribute(&renderer, "text", idx);
        col.set_resizable(true);
        col.set_min_width(ancho);
        tree.append_column(&col);
    }
    tree
}

// ─── Fila de fechas y días ────────────────────────────────────────────────

fn construir_fila_fechas(estado: Rc<RefCell<Estado>>) -> GtkBox {
    let hbox = GtkBox::new(Orientation::Horizontal, 6);
    hbox.set_margin_top(4);
    hbox.set_margin_bottom(4);
    hbox.set_margin_start(6);
    hbox.set_margin_end(6);

    hbox.append(&Label::new(Some(tr("paut.fecha_inicio"))));
    let entry_inicio = gtk::Entry::new();
    entry_inicio.set_width_chars(12);
    entry_inicio.set_text(&estado.borrow().fecha_inicio.format("%d/%m/%Y").to_string());
    hbox.append(&entry_inicio);

    hbox.append(&Label::new(Some(tr("paut.fecha_fin"))));
    let entry_fin = gtk::Entry::new();
    entry_fin.set_width_chars(12);
    entry_fin.set_text(&estado.borrow().fecha_fin.format("%d/%m/%Y").to_string());
    hbox.append(&entry_fin);

    hbox.append(&Separator::new(Orientation::Vertical));

    let dias_info: [(&str, char); 7] = [
        (tr("dia.lunes"),     '1'),
        (tr("dia.martes"),    '2'),
        (tr("dia.miercoles"), '3'),
        (tr("dia.jueves"),    '4'),
        (tr("dia.viernes"),   '5'),
        (tr("dia.sabado"),    '6'),
        (tr("dia.domingo"),   '7'),
    ];

    // Estado activo de cada día (todos activos por defecto)
    let dias_activos: Rc<RefCell<[bool; 7]>> = Rc::new(RefCell::new([true; 7]));

    // Crear botones normales (igual que parrilla)
    let btns_dias: Vec<gtk::Button> = dias_info.iter().map(|(etiqueta, _)| {
        let b = gtk::Button::with_label(etiqueta);
        b.add_css_class("dia-on");
        b
    }).collect();

    // Botón "Todos"
    let btn_todos = gtk::Button::with_label(tr("btn.all"));
    btn_todos.add_css_class("todos-on");
    // Estado del botón Todos
    let todos_on: Rc<RefCell<bool>> = Rc::new(RefCell::new(true));

    // Conectar lógica de cada botón de día
    for (i, ((_etiqueta, ch), btn)) in dias_info.iter().zip(btns_dias.iter()).enumerate() {
        let ch = *ch;
        let ec = estado.clone();
        let da = dias_activos.clone();
        let btn_todos_c = btn_todos.clone();
        let ton = todos_on.clone();
        btn.connect_clicked(move |b| {
            // Invertir estado de este día
            let nuevo = !da.borrow()[i];
            da.borrow_mut()[i] = nuevo;

            // Actualizar CSS del botón
            if nuevo {
                b.add_css_class("dia-on");
            } else {
                b.remove_css_class("dia-on");
            }

            // Sincronizar "Todos": verde solo si todos están activos
            let todos_activos = da.borrow().iter().all(|&v| v);
            *ton.borrow_mut() = todos_activos;
            if todos_activos {
                btn_todos_c.add_css_class("todos-on");
            } else {
                btn_todos_c.remove_css_class("todos-on");
            }

            // Actualizar estado de días
            let mut e = ec.borrow_mut();
            if nuevo {
                if !e.dias.contains(ch) {
                    e.dias.push(ch);
                    let mut v: Vec<char> = e.dias.chars().collect();
                    v.sort_unstable();
                    e.dias = v.into_iter().collect();
                }
            } else {
                e.dias.retain(|c| c != ch);
            }
        });
        hbox.append(btn);
    }

    // Separador antes de "Todos"
    hbox.append(&Separator::new(Orientation::Vertical));

    // Conectar lógica del botón "Todos"
    {
        let ec = estado.clone();
        let btns_c: Vec<gtk::Button> = btns_dias.clone();
        let da = dias_activos.clone();
        let ton = todos_on.clone();
        btn_todos.connect_clicked(move |b| {
            // Invertir el estado de todos
            let nuevo = !*ton.borrow();
            *ton.borrow_mut() = nuevo;

            if nuevo {
                b.add_css_class("todos-on");
            } else {
                b.remove_css_class("todos-on");
            }

            // Aplicar a todos los días
            for (i, btn_dia) in btns_c.iter().enumerate() {
                da.borrow_mut()[i] = nuevo;
                if nuevo {
                    btn_dia.add_css_class("dia-on");
                } else {
                    btn_dia.remove_css_class("dia-on");
                }
            }

            let mut e = ec.borrow_mut();
            e.dias = if nuevo { "1234567".to_string() } else { String::new() };
        });
    }
    hbox.append(&btn_todos);

    {
        let ec = estado.clone();
        entry_inicio.connect_changed(move |e| {
            if let Ok(f) = NaiveDate::parse_from_str(&e.text(), "%d/%m/%Y") {
                ec.borrow_mut().fecha_inicio = f;
            }
        });
    }
    {
        let ec = estado.clone();
        entry_fin.connect_changed(move |e| {
            if let Ok(f) = NaiveDate::parse_from_str(&e.text(), "%d/%m/%Y") {
                ec.borrow_mut().fecha_fin = f;
            }
        });
    }

    hbox
}

// ─── Barra de herramientas ────────────────────────────────────────────────

fn construir_fila_herramientas(
    estado: Rc<RefCell<Estado>>,
    store: ListStore,
    tree: Rc<TreeView>,
    lbl_acumulado: Label,
    lbl_corte: Label,
    ventana: &ApplicationWindow,
) -> GtkBox {
    let hbox = GtkBox::new(Orientation::Horizontal, 4);
    hbox.set_margin_start(4);
    hbox.set_margin_end(4);
    hbox.set_margin_top(2);
    hbox.set_margin_bottom(2);

    // ── 🗑 Limpiar caducados ──
    let btn_limpiar = Button::with_label("🗑");
    btn_limpiar.set_tooltip_text(Some(tr("paut.tip_limpiar")));
    {
        let vc = ventana.clone();
        let sc = store.clone();
        let ec = estado.clone();
        btn_limpiar.connect_clicked(move |_| {
            let dlg = gtk::MessageDialog::builder()
                .transient_for(&vc)
                .modal(true)
                .message_type(gtk::MessageType::Question)
                .buttons(gtk::ButtonsType::YesNo)
                .text(tr("paut.confirm_caducados"))
                .build();
            let sd = sc.clone();
            let ed = ec.clone();
            dlg.connect_response(move |d, resp| {
                if resp == gtk::ResponseType::Yes {
                    let hoy = Local::now().date_naive();
                    let n = storage::limpiar_caducados(hoy);
                    let e = ed.borrow();
                    recargar_store(&sd, &e.tipo, e.hora, e.minuto);
                    let info = gtk::MessageDialog::builder()
                        .modal(true)
                        .message_type(gtk::MessageType::Info)
                        .buttons(gtk::ButtonsType::Ok)
                        .text(&tr("paut.info_caducados").replace("{n}", &n.to_string()))
                        .build();
                    info.connect_response(|d2, _| d2.close());
                    info.present();
                }
                d.close();
            });
            dlg.present();
        });
    }
    hbox.append(&btn_limpiar);
    hbox.append(&lbl_acumulado);
    hbox.append(&lbl_corte);
    hbox.append(&Separator::new(Orientation::Vertical));

    // ── Desplegable Tipo ──
    let combo_tipo = ComboBoxText::new();
    combo_tipo.append_text(tr("paut.tipo_comerciales"));
    combo_tipo.append_text(tr("paut.tipo_eventos"));
    combo_tipo.append_text(tr("paut.tipo_eventos_espera"));
    combo_tipo.set_active(Some(0));
    {
        let ec = estado.clone();
        let sc = store.clone();
        combo_tipo.connect_changed(move |c| {
            if let Some(i) = c.active() {
                let mut e = ec.borrow_mut();
                e.tipo = TipoPautaje::from_index(i);
                recargar_store(&sc, &e.tipo, e.hora, e.minuto);
            }
        });
    }
    hbox.append(&combo_tipo);

    // ── Desplegable Hora ──
    let combo_hora = ComboBoxText::new();
    for h in 0u8..24 {
        combo_hora.append_text(&format!("{:02}", h));
    }
    combo_hora.set_active(Some(0));
    {
        let ec = estado.clone();
        let sc = store.clone();
        combo_hora.connect_changed(move |c| {
            if let Some(i) = c.active() {
                let mut e = ec.borrow_mut();
                e.hora = i as u8;
                recargar_store(&sc, &e.tipo, e.hora, e.minuto);
            }
        });
    }
    hbox.append(&combo_hora);

    // ── Desplegable Minuto ──
    let combo_min = ComboBoxText::new();
    for m in (0u8..60).step_by(5) {
        combo_min.append_text(&format!("{:02}", m));
    }
    combo_min.set_active(Some(0));
    {
        let ec = estado.clone();
        let sc = store.clone();
        combo_min.connect_changed(move |c| {
            if let Some(i) = c.active() {
                let mut e = ec.borrow_mut();
                e.minuto = (i as u8) * 5;
                recargar_store(&sc, &e.tipo, e.hora, e.minuto);
            }
        });
    }
    hbox.append(&combo_min);

    hbox.append(&Separator::new(Orientation::Vertical));

    // ── ▲ Subir ──
    let btn_subir = Button::with_label("▲");
    btn_subir.set_tooltip_text(Some(tr("paut.tip_subir")));
    {
        let ec = estado.clone(); let sc = store.clone(); let tc = tree.clone();
        btn_subir.connect_clicked(move |_| {
            if let Some(idx) = seleccion_indice(&tc) {
                let e = ec.borrow();
                storage::mover_entrada(&e.tipo, e.hora, e.minuto, idx, true);
                recargar_store(&sc, &e.tipo, e.hora, e.minuto);
                seleccionar_fila(&tc, idx.saturating_sub(1));
            }
        });
    }
    hbox.append(&btn_subir);

    // ── ▼ Bajar ──
    let btn_bajar = Button::with_label("▼");
    btn_bajar.set_tooltip_text(Some(tr("paut.tip_bajar")));
    {
        let ec = estado.clone(); let sc = store.clone(); let tc = tree.clone();
        btn_bajar.connect_clicked(move |_| {
            if let Some(idx) = seleccion_indice(&tc) {
                let e = ec.borrow();
                let n = storage::leer_entradas(&e.tipo, e.hora, e.minuto).len();
                storage::mover_entrada(&e.tipo, e.hora, e.minuto, idx, false);
                recargar_store(&sc, &e.tipo, e.hora, e.minuto);
                seleccionar_fila(&tc, (idx + 1).min(n.saturating_sub(1)));
            }
        });
    }
    hbox.append(&btn_bajar);

    // ── ✕ Eliminar ──
    let btn_eliminar = Button::with_label("✕");
    btn_eliminar.set_tooltip_text(Some(tr("paut.tip_eliminar")));
    {
        let ec = estado.clone(); let sc = store.clone(); let tc = tree.clone();
        btn_eliminar.connect_clicked(move |_| {
            if let Some(idx) = seleccion_indice(&tc) {
                let e = ec.borrow();
                storage::eliminar_entrada(&e.tipo, e.hora, e.minuto, idx);
                recargar_store(&sc, &e.tipo, e.hora, e.minuto);
            }
        });
    }
    hbox.append(&btn_eliminar);

    // ── ▶ Reproducir (placeholder) ──
    let btn_play = Button::with_label("▶");
    btn_play.set_tooltip_text(Some(tr("paut.tip_play_cue")));
    {
        let ec = estado.clone(); let tc = tree.clone();
        btn_play.connect_clicked(move |_| {
            if let Some(idx) = seleccion_indice(&tc) {
                let e = ec.borrow();
                let entradas = storage::leer_entradas(&e.tipo, e.hora, e.minuto);
                if let Some(entrada) = entradas.get(idx) {
                    eprintln!("[reproducir] {}", entrada.ruta);
                }
            }
        });
    }
    hbox.append(&btn_play);

    // ── 🌐 URL Streaming ──
    let btn_url = Button::with_label("🌐");
    btn_url.set_tooltip_text(Some(tr("paut.tip_url")));
    {
        let ec = estado.clone(); let sc = store.clone(); let vc = ventana.clone();
        btn_url.connect_clicked(move |_| {
            mostrar_dialogo_url(&vc, ec.clone(), sc.clone());
        });
    }
    hbox.append(&btn_url);

    // ── ⏰ Hora ──
    let btn_hora_s = Button::with_label("⏰");
    btn_hora_s.set_tooltip_text(Some(tr("paut.tip_hora")));
    {
        let ec = estado.clone();
        let sc = store.clone();
        btn_hora_s.connect_clicked(move |_| {
            let e = ec.borrow();
            let entrada = crate::models::EntradaPautaje {
                ruta: "Hora".to_string(),
                dias: e.dias.clone(),
                inicio: e.fecha_inicio,
                fin: e.fecha_fin,
            };
            storage::agregar_entrada_siempre(&e.tipo, e.hora, e.minuto, entrada);
            recargar_store(&sc, &e.tipo, e.hora, e.minuto);
        });
    }
    hbox.append(&btn_hora_s);

    // ── ↵ Entrada de línea (placeholder) ──
    let btn_linea = Button::with_label("↵");
    btn_linea.set_tooltip_text(Some(tr("paut.tip_linea")));
    hbox.append(&btn_linea);

    hbox
}
