use glacier_ui::{GlacierUI, EngineMessage, Component, Context, Template};
use iced::{Element, Task};
use std::time::Duration;

/// Demonstra navegação entre telas: cada tela é um componente registrado, e os
/// botões declaram o destino no próprio XML via `navigateTo`/`navigateBack` — a
/// navegação é tratada pelo motor em `dispatch`. O estado (`user_name`) é
/// compartilhado entre todas as telas.
///
/// As três telas reaproveitam o mesmo tipo `Tela`, instanciado com nomes e
/// templates diferentes.
struct Tela {
    nome: &'static str,
    template: &'static str,
}

impl Component for Tela {
    fn name(&self) -> &str {
        self.nome
    }

    fn template(&self) -> Template {
        Template::File(self.template.into())
    }

    fn update(&mut self, action: &str, value: Option<&str>, ctx: &mut Context) {
        if action == "mudar_nome" {
            if let Some(v) = value {
                ctx.set("user_name", v);
            }
        }
    }
}

struct AppNav {
    motor: GlacierUI,
}

impl AppNav {
    fn new() -> (Self, Task<EngineMessage>) {
        let mut motor = GlacierUI::new();

        let telas = [
            Tela { nome: "home", template: "templates/nav_home.xml" },
            Tela { nome: "perfil", template: "templates/nav_perfil.xml" },
            Tela { nome: "config", template: "templates/nav_config.xml" },
        ];
        for tela in telas {
            let nome = tela.nome;
            if let Err(e) = motor.register(Box::new(tela)) {
                eprintln!("Erro ao registrar '{}': {}", nome, e);
            }
        }

        // Estado compartilhado entre as telas (não pertence a uma tela só).
        motor.define_data("user_name", "Clara Silva");
        motor.define_data("user_role", "Engenheira de Software");

        // Tela inicial.
        motor.set_initial_screen("home");

        (Self { motor }, Task::none())
    }

    fn update(&mut self, message: EngineMessage) -> Task<EngineMessage> {
        self.motor.dispatch(&message)
    }

    fn view(&self) -> Element<'_, EngineMessage> {
        self.motor.render_current().unwrap_or_else(|e| {
            iced::widget::text(format!("Erro ao render: {}", e))
                .color(iced::Color::from_rgb(1.0, 0.0, 0.0))
                .into()
        })
    }

    fn subscription(&self) -> iced::Subscription<EngineMessage> {
        GlacierUI::reload_subscription(Duration::from_millis(500))
    }
}

fn main() -> iced::Result {
    iced::application("Glacier - Navegação", AppNav::update, AppNav::view)
        .subscription(AppNav::subscription)
        .run_with(|| AppNav::new())
}
