mod installer;
mod steps;
mod jobs;
mod ui;
mod autoinstall;
mod branding;
mod funct;

use installer::{GlobalState, InstallerStep, WelcomeStep};
use steps::{LocationStep, KeyboardStep, UsersStep, SummaryStep, ExecutionStep, FinishStep, PartitionStep, BootloaderStep, NetworkStep};
use eframe::egui;
use rust_i18n::t;

rust_i18n::i18n!("locales");

fn main() -> eframe::Result<()> {
    // ── CLI: otomatik kurulum modu ───────────────────────
    let args: Vec<String> = std::env::args().collect();
    let demo_mode = args.contains(&"--demo".to_string());
    

    if let Some(pos) = args.iter().position(|a| a == "--auto-install") {
        if let Some(path) = args.get(pos + 1) {
            return run_auto_install(path, demo_mode);
        } else {
            eprintln!("Hata: --auto-install <dosya.toml> şeklinde kullanın.");
            std::process::exit(1);
        }
    }

    run_gui(demo_mode)
}

/// Grafik arayüzü başlatır (normal mod).
fn run_gui(demo_mode: bool) -> eframe::Result<()> {
    
    let icon_data = {
        let img = image::load_from_memory(include_bytes!("../assets/icons/YALI_icon_DARK.png"))
            .expect("YALI_icon_DARK.png yüklenemedi")
            .into_rgba8();
        let (w, h) = img.dimensions();
        egui::IconData {
            width: w,
            height: h,
            rgba: img.into_raw(),
        }
    };

    let options = eframe::NativeOptions {
        viewport: egui::ViewportBuilder::default()
            .with_inner_size([1200.0, 900.0])
            .with_min_inner_size([1080.0, 720.0])
            .with_title(t!("installer"))
            .with_icon(icon_data),
        ..Default::default()
    };

    eframe::run_native(
        t!("installer").as_ref(),
        options,
        Box::new(move |cc| {
            // Görsel yükleyicileri etkinleştir (PNG desteği)
            egui_extras::install_image_loaders(&cc.egui_ctx);
            ui::theme::set_theme_mode(true);
            ui::theme::apply(&cc.egui_ctx, true);
            let mut app = YaliApp::default();
            app.state.demo_mode = demo_mode;
            Box::new(app)
        }),
    )
}

/// Answer file ile tam otomatik, UI-siz kurulum.
fn run_auto_install(path: &str, demo_mode: bool) -> eframe::Result<()> {
    use autoinstall::{load, apply_to_state};
    use std::path::Path;

    println!("=== Yali-RS Otomatik Kurulum ===");
    println!("{}: {}", t!("answer_file"), path);

    // Dosyayı yükle ve doğrula
    let af = match load(Path::new(path)) {
        Ok(af) => af,
        Err(e) => {
            eprintln!("{}: {}", t!("error"), e);
            std::process::exit(1);
        }
    };

    println!("{}: {}", t!("disk"), af.install.disk);
    println!("{}: {}", t!("timezone"), af.install.timezone);
    println!("{}: {}", t!("username"), af.user.username);
    println!("{}: {}", t!("hostname"), af.user.hostname);

    // Sistem kontrollerini çalıştır
    println!("\n--- {} ---", t!("system_checks"));
    let checks = autoinstall::checker::run_all();
    for c in &checks {
        let sym = match c.status {
            autoinstall::checker::CheckStatus::Pass => "✓",
            autoinstall::checker::CheckStatus::Warn => "⚠",
            autoinstall::checker::CheckStatus::Fail => "✗",
        };
        println!("[{}] {}: {}", sym, c.name, c.message);
    }

    if !autoinstall::checker::all_passed(&checks) {
        eprintln!("{}: Critical check error. Installation stopped.", t!("error"));
        std::process::exit(2);
    }

    // State'i hazırla
    let mut state = GlobalState {
        demo_mode,
        ..Default::default()
    };
    apply_to_state(&af, &mut state);

    if state.partition_plan.is_none() {
        eprintln!("{}: {}: {}", t!("error"), t!("partition_plan_could_not_be_created"), af.install.disk);
        std::process::exit(3);
    }

    println!("\n--- {} ---", t!("installation_started"));

    // JobQueue'yu oluştur ve tokio'da çalıştır
    let locale     = af.install.locale.clone();
    let timezone   = af.install.timezone.clone();
    let username   = af.user.username.clone();
    let password   = af.user.password.clone();
    let hostname   = af.user.hostname.clone();
    let kb_layout  = af.install.keyboard.clone();
    let kb_variant = af.install.keyboard_variant.clone();
    let source     = af.install.source.clone();
    let mount      = af.install.mount.clone();
    let plan       = state.partition_plan.unwrap();

    let rt = tokio::runtime::Runtime::new().expect("tokio runtime");
    rt.block_on(async {
        use std::sync::mpsc;
        use jobs::{InstallMessage, UiSender};

        // CLI modunda egui Context yok; basit bir mpsc kanal kullanıyoruz.
        let (tx, rx) = mpsc::channel::<InstallMessage>();

        // Arka plan iş parçacığı — gerçek job kuyruğunu çalıştırır.
        let cli_ctx = eframe::egui::Context::default();
        let ui_sender = UiSender::new(tx, cli_ctx);

        let language_c  = if locale.starts_with("tr") { "tr".to_string() } else { "en".to_string() };
        let plan_c      = plan.clone();
        let locale_c    = locale.clone();
        let timezone_c  = timezone.clone();
        let username_c  = username.clone();
        let password_c  = password.clone();
        let hostname_c  = hostname.clone();
        let kb_layout_c = kb_layout.clone();
        let kb_variant_c= kb_variant.clone();
        let source_c    = source.clone();
        let mount_c     = mount.clone();

        std::thread::spawn(move || {
            let rt = tokio::runtime::Runtime::new().expect("tokio runtime");
            let mut queue = jobs::build_full_job_queue(
                plan_c,
                jobs::JobQueueConfig {
                    mount:               mount_c,
                    source:              source_c,
                    language:            language_c,
                    locale:              locale_c,
                    timezone:            timezone_c,
                    username:            username_c,
                    password:            password_c,
                    hostname:            hostname_c,
                    kb_layout:           kb_layout_c,
                    kb_variant:          kb_variant_c,
                    demo_mode,
                    boot_device:         String::new(),
                    bootloader_timeout:  5,
                    bootloader_password: String::new(),
                    kernel_options:      String::new(),
                    use_ntp:             true,
                    root_password:       String::new(),
                    display_manager:     "sddm".to_string(),
                    autologin:           true,
                    desktop_environment: "plasma".to_string(),
                    selected_package_groups: Vec::new(),
                    manual_year:         2026,
                    manual_month:        5,
                    manual_day:          26,
                    manual_hour:         12,
                    manual_minute:       0,
                },
            );
            rt.block_on(queue.run_all(ui_sender));
        });

        // Kanalı oku ve terminale yaz
        loop {
            match rx.recv() {
                Ok(InstallMessage::Log(line)) => println!("  {}", line),
                Ok(InstallMessage::Progress(p)) => {
                    print!("\r  {}: [{:50}] {:.0}%", t!("progress"), "=".repeat((p * 50.0) as usize), p * 100.0);
                    let _ = std::io::Write::flush(&mut std::io::stdout());
                }
                Ok(InstallMessage::SubProgress(p)) => {
                    print!("\r  {}: [{:50}] {:.0}%  ", t!("progress"), "=".repeat((p * 50.0) as usize), p * 100.0);
                    let _ = std::io::Write::flush(&mut std::io::stdout());
                }
                Ok(InstallMessage::CopyStarted) | Ok(InstallMessage::CopyFinished) => {}
                Ok(InstallMessage::CurrentFile(f)) => {
                    print!("\r  {}: {}          ", t!("install_current_file"), f);
                    let _ = std::io::Write::flush(&mut std::io::stdout());
                }
                Ok(InstallMessage::Done) => {
                    println!("\n\n{}: {}", t!("installation_done"), t!("installation_done_description"));
                    break;
                }
                Ok(InstallMessage::Error(e)) => {
                    eprintln!("\n{}: {}", t!("error"), e);
                    std::process::exit(4);
                }
                Err(_) => break,
            }
        }
    });

    Ok(())
}

struct YaliApp {
    state:              GlobalState,
    steps:              Vec<Box<dyn InstallerStep>>,
    rescue_step:        Option<Box<dyn InstallerStep>>,
    last_step:          usize,
    branding:           branding::BrandingConfig,
    loaded_language:    String,
    #[allow(dead_code)]
    show_cancel_dialog: bool,
}

impl Default for YaliApp {
    fn default() -> Self {
        let default_lang = "tr".to_string();
        let branding = branding::BrandingConfig::load_for_lang(&default_lang);
        let mut app = Self {
            state: GlobalState::default(),
            steps: vec![
                Box::new(WelcomeStep::default()),
                Box::new(LocationStep::default()),
                Box::new(KeyboardStep::default()),
                Box::new(NetworkStep::default()),
                Box::new(PartitionStep::default()),
                Box::new(UsersStep::default()),
                Box::new(BootloaderStep::default()),
                Box::new(SummaryStep),
                Box::new(ExecutionStep::default()),
                Box::new(FinishStep),
            ],
            rescue_step: Some(Box::new(steps::RescueStep::default())),
            last_step: usize::MAX,
            branding: branding.clone(),
            loaded_language: String::new(),
            show_cancel_dialog: false,
        };

        // OEM modu: varsayılan değerleri ata ve step engelleme
        if branding.oem.enabled {
            app.state.oem_mode = true;
            if !branding.oem.default_username.is_empty() {
                app.state.username = branding.oem.default_username.clone();
                app.state.hostname = branding.oem.default_hostname.clone();
            }
            if !branding.oem.default_password.is_empty() {
                app.state.password = branding.oem.default_password.clone();
                app.state.password_confirm = branding.oem.default_password.clone();
                // OEM varsayılan şifresi yüklendi; kullanıcı değiştirene kadar
                // ilerleme engellenir.
                app.state.oem_password_changed = false;
            }
            // OEM ön tanımlı disk planı varsa?
        }

        // Branding görsel verilerini GlobalState'e enjekte et
        app.state.branding_yali_dark    = branding.yali_logo_uri();
        app.state.branding_yali_light   = branding.yali_logo_uri();
        app.state.branding_pisi_dark    = branding.pisi_logo_dark_uri();
        app.state.branding_pisi_light   = branding.pisi_logo_light_uri();

        app.steps[0].on_enter(&mut app.state);
        app.last_step = 0;
        app
    }
}

impl eframe::App for YaliApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        rust_i18n::set_locale(&self.state.language);

        // Dil değişimi kontrolü -> branding dosyasını dinamik olarak yeniden yükle
        if self.loaded_language != self.state.language {
            self.loaded_language = self.state.language.clone();
            let branding = branding::BrandingConfig::load_for_lang(&self.loaded_language);
            self.branding = branding.clone();
            self.state.branding_yali_dark    = branding.yali_logo_uri();
            self.state.branding_yali_light   = branding.yali_logo_uri();
            self.state.branding_pisi_dark    = branding.pisi_logo_dark_uri();
            self.state.branding_pisi_light   = branding.pisi_logo_light_uri();

            // Pencere başlığını dinamik olarak güncelle
            ctx.send_viewport_cmd(egui::ViewportCommand::Title(self.branding.general.title.clone()));
        }

        // Rescue modu: tam ekran, sidebar yok, navigasyon yok
        if self.state.rescue_mode {
            if let Some(rescue) = &mut self.rescue_step {
                egui::CentralPanel::default()
                    .frame(egui::Frame::none()
                        .fill(ui::theme::c_bg_dark())
                        .inner_margin(egui::Margin::same(20.0)))
                    .show(ctx, |ui| {
                        egui::ScrollArea::vertical().show(ui, |ui| {
                            rescue.show(ui, &mut self.state);
                        });
                    });
            }
            return;
        }

        let cur     = self.state.current_step;
        let n_steps = self.steps.len();
        let is_exec   = cur == n_steps - 2;
        let is_finish = cur == n_steps - 1;

        // Adım değişmişse on_enter çağır
        if cur != self.last_step {
            if let Some(step) = self.steps.get_mut(cur) {
                step.on_enter(&mut self.state);
            }
            self.last_step = cur;
        }

        // ── Sol panel: adım listesi ──────────────────────────
        egui::SidePanel::left("sidebar")
            .exact_width(195.0)
            .frame(egui::Frame::none().fill(ui::theme::c_sidebar()))
            .show(ctx, |ui| {
                ui.add_space(20.0);

                // Dağıtım logosu — branding.toml'dan dinamik yüklenir
                ui.vertical_centered(|ui| {
                    let logo_uri = if self.state.is_dark {
                        &self.state.branding_yali_dark
                    } else {
                        &self.state.branding_yali_light
                    };
                    if !logo_uri.is_empty() {
                        ui.add(
                            egui::Image::from_uri(logo_uri.as_str())
                                .max_width(120.0)
                                .rounding(egui::Rounding::same(8.0)),
                        );
                    }
                    ui.add_space(8.0);
                    // ui.label(
                    //     egui::RichText::new(t!("app_name"))
                    //         .strong()
                    //         .size(16.0)
                    //         .color(ui::theme::c_text_dim()),
                    // );
                    
                    // ui.colored_label(
                    //     egui::Color32::from_rgb(60, 60, 90),
                    //     format!("{}: {}", t!("version"), env!("CARGO_PKG_VERSION")),
                    // );
                });

                ui.add_space(16.0);
                ui.separator();
                ui.add_space(12.0);

                // Adım listesi
                for (i, step) in self.steps.iter().enumerate() {
                    //let label = format!("{}. {}", i + 1, step.name());
                    let label = step.name();

                    egui::Frame::none()
                        .fill(if i == cur {
                            egui::Color32::from_rgba_unmultiplied(0x21, 0x96, 0xF3, 30)
                        } else {
                            egui::Color32::TRANSPARENT
                        })
                        //.rounding(egui::Rounding::same(6.0))
                        .inner_margin(egui::Margin::symmetric(10.0, 5.0))
                        .show(ui, |ui| {
                            ui.set_width(175.0);
                            if i == cur {
                                ui.horizontal(|ui| {
                                    ui.colored_label(ui::theme::c_accent(), "▶");
                                    ui.colored_label(ui::theme::c_sidebar_text(), label);
                                });
                            } else if i < cur {
                                ui.horizontal(|ui| {
                                    ui.colored_label(ui::theme::c_success(), "✅");
                                    ui.colored_label(ui::theme::c_sidebar_text(), label);
                                });
                            } else {
                                ui.colored_label(
                                    egui::Color32::from_rgb(255, 255, 255),
                                    format!("  {}", label),
                                );
                            }
                        });

                    ui.add_space(2.0);
                }

                // Alt kısım: tema değiştirme
                ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| {
                    ui.add_space(6.0);
                    
                    let theme_icon = if self.state.is_dark { "☀" } else { "🌙" };
                    let theme_label = if self.state.is_dark { "Light" } else { "Dark" };
                    if ui.add(
                        egui::Button::new(
                            egui::RichText::new(format!("{} {}", theme_icon, theme_label))
                                .size(12.0)
                        )
                        .rounding(egui::Rounding::same(6.0))
                        .min_size(egui::Vec2::new(100.0, 28.0))
                    ).clicked() {
                        self.state.is_dark = !self.state.is_dark;
                        ui::theme::set_theme_mode(self.state.is_dark);
                        ui::theme::apply(ctx, self.state.is_dark);
                    }
                });
            });

        // ── Alt panel: navigasyon ────────────────────────────
        egui::TopBottomPanel::bottom("footer")
            .frame(egui::Frame::none()
                .fill(ui::theme::c_footer_bg())
                .stroke(egui::Stroke::new(1.0_f32, ui::theme::c_footer_bg())))
            .show(ctx, |ui| {
                ui.add_space(10.0);
                ui.horizontal(|ui| {
                    ui.add_space(8.0);                  

                    ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                        ui.add_space(8.0);

                        let is_valid = self.steps
                            .get(cur)
                            .map(|s| s.is_complete(&self.state))
                            .unwrap_or(false);

                        if !is_finish {
                            if !is_exec || is_valid {
                                let next_label = if is_exec {
                                    t!("finish_next")
                                } else {
                                    t!("next")
                                };
                                // if !is_exec && !is_finish && ui::theme::danger_button(ui, &t!("cancel")).clicked() {
                                //     self.show_cancel_dialog = true;
                                // };
                                let next_clicked = ui::theme::primary_button_enabled(ui, &next_label, is_valid).clicked();
                                if next_clicked {
                                    self.state.current_step += 1;
                                }
                            }

                            if cur > 0 && !is_exec {
                                ui.add_space(8.0);
                                if ui::theme::secondary_button(ui, &t!("back")).clicked() {
                                    self.state.current_step -= 1;
                                }
                            }
                        }
                    });
                });
                ui.add_space(10.0);
            });

        // // ── İptal onay diyaloğu ───────────────────────────────
        // if self.show_cancel_dialog {
        //     egui::Window::new(t!("cancel_confirm_title"))
        //         .collapsible(false)
        //         .resizable(false)
        //         .anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
        //         .show(ctx, |ui| {
        //             ui.label(t!("cancel_confirm_msg"));
        //             ui.add_space(12.0);
        //             ui.horizontal(|ui| {
        //                 if ui.button(t!("cancel_confirm_yes")).clicked() {
        //                     ctx.send_viewport_cmd(egui::ViewportCommand::Close);
        //                 }
        //                 if ui.button(t!("cancel_confirm_no")).clicked() {
        //                     self.show_cancel_dialog = false;
        //                 }
        //             });
        //         });
        // }

        // ── Merkez panel ─────────────────────────────────────
        egui::CentralPanel::default()
            .frame(egui::Frame::none()
                .fill(ui::theme::c_bg_dark())
                .inner_margin(egui::Margin::same(20.0)))
            .show(ctx, |ui| {
                egui::ScrollArea::vertical()
                    .id_source("main_scroll")
                    .show(ui, |ui| {
                        if let Some(step) = self.steps.get_mut(cur) {
                            step.show(ui, &mut self.state);
                        }
                    });
            });
    }
}