use eframe::egui;
use sysinfo::System;
use rust_i18n::t;

/// Aktif masaüstü ortamını algılar.
/// Önce `XDG_CURRENT_DESKTOP` ortam değişkenine bakar (normal kullanıcı).
/// sudo ile çalışıldığında env var kaybolur, bu durumda `pgrep` ile
/// çalışan desktop session process'lerini kontrol eder.
pub fn detect_desktop_environment() -> String {
    // 1. XDG_CURRENT_DESKTOP ortam değişkeni
    if let Ok(de) = std::env::var("XDG_CURRENT_DESKTOP") {
        let de = de.trim().to_lowercase();
        if !de.is_empty() {
            return de;
        }
    }

    // 2. sudo ile çalışıldıysa env kaybolur — aktif session process'lerini kontrol et
    let de_map: &[(&str, &[&str])] = &[
        ("plasma",   &["plasmashell", "startplasma"]),
        ("xfce",     &["xfce4-session", "xfdesktop"]),
        ("gnome",    &["gnome-session"]),
        ("cinnamon", &["cinnamon-session"]),
        ("budgie",   &["budgie-wm"]),
        ("lxqt",     &["lxqt-session"]),
        ("mate",     &["mate-session"]),
        ("lumina",   &["lumina-desktop"]),
        ("lxde",     &["lxsession"]),
    ];
    for (de_name, procs) in de_map {
        for proc in *procs {
            if let Ok(out) = std::process::Command::new("pgrep")
                .args(["-x", proc])
                .output()
            {
                if out.status.success() {
                    return de_name.to_string();
                }
            }
        }
    }

    // 3. Hiçbiri bulunamazsa varsayılan
    "plasma".to_string()
}

/// Disk adı ve bölüm numarasından tam aygıt yolunu oluşturur.
///
/// - SATA/SCSI: `/dev/sda`  + 1 → `/dev/sda1`
/// - NVMe:      `/dev/nvme0n1` + 1 → `/dev/nvme0n1p1`
/// - MMC:       `/dev/mmcblk0` + 1 → `/dev/mmcblk0p1`
pub fn part_path(disk: &str, num: u32) -> String {
    let needs_p = disk.contains("nvme") || disk.contains("mmcblk") || disk.contains("loop");
    if needs_p {
        format!("{}p{}", disk, num)
    } else {
        format!("{}{}", disk, num)
    }
}


/// Calamares'in "ViewStep" yapısına benzer bir Trait.
pub trait InstallerStep {
    fn name(&self) -> String;
    fn on_enter(&mut self, _state: &mut GlobalState) {}
    fn show(&mut self, ui: &mut egui::Ui, state: &mut GlobalState);
    fn is_complete(&self, state: &GlobalState) -> bool;
}

// ─────────────────────────────────────────────
// VERİ YAPILARI
// ─────────────────────────────────────────────

#[derive(Clone, Debug)]
pub struct DiskInfo {
    pub name: String,   // ör. "/dev/sda"
    pub vendor: String, // "ATA", "INTEL", vb.
    pub model: String,
    #[allow(dead_code)]
    pub drive_type: String, // "NVMe SSD", "SSD", "HDD", "USB", "MMC/SD", vb.
    pub size_gb: u64,
    pub size_bytes: u64,
}

/// Otomatik bölümleme planı.
/// Disk seçimi yapılınca hesaplanır; Özet ekranında gösterilir.
#[derive(Clone, Debug, Default)]
pub struct PartitionPlan {
    pub disk: String,
    pub table_type: PartitionTableType, // GPT veya MBR
    pub efi_mb: u64,                   // 0 → BIOS, >0 → UEFI
    pub swap_mb: u64,
    pub root_mb: u64,                  // kalan alan
    pub encrypt_root: bool,            // Kök bölümü LUKS ile şifrelensin mi?
    pub luks_password: String,         // LUKS şifresi
}

#[derive(Clone, Debug, Default, PartialEq)]
pub enum PartitionTableType {
    #[default]
    Gpt,
    Mbr,
}

impl std::fmt::Display for PartitionTableType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            PartitionTableType::Gpt => write!(f, "GPT"),
            PartitionTableType::Mbr => write!(f, "MBR"),
        }
    }
}

/// Manuel bölümleme için desteklenen dosya sistemleri.
#[derive(Clone, Debug, PartialEq)]
pub enum FsType {
    Ext4,
    Ext3,
    Btrfs,
    Xfs,
    Fat32,  // EFI bölümü için
    Ntfs,
    Swap,
    Lvm,    // LVM fiziksel bölüm (PV)
    #[allow(dead_code)]
    LvmLv,  // LVM mantıksal bölüm (LV)
}

impl FsType {
    pub fn label(&self) -> &'static str {
        match self {
            FsType::Ext4  => "ext4",
            FsType::Ext3  => "ext3",
            FsType::Btrfs => "btrfs",
            FsType::Xfs   => "xfs",
            FsType::Fat32 => "FAT32 (EFI)",
            FsType::Ntfs  => "NTFS",
            FsType::Swap  => "swap",
            FsType::Lvm   => "LVM PV",
            FsType::LvmLv => "LVM LV",
        }
    }
}

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

/// LVM Volume Group yapılandırması.
#[derive(Clone, Debug, Default)]
pub struct VolumeGroup {
    pub name: String,
    pub pv_devices: Vec<String>,   // PV olarak kullanılacak bölüm aygıtları
    pub size_mb: u64,              // VG toplam boyutu (hesaplanan)
}

/// LVM Logical Volume yapılandırması.
#[derive(Clone, Debug)]
pub struct LogicalVolume {
    pub name: String,
    pub vg_name: String,
    pub size_mb: u64,              // 0 = kalan alan
    pub fstype: FsType,
    #[allow(dead_code)]
    pub mountpoint: String,
}

/// Kullanıcının manuel olarak tanımladığı tek bir bölüm.
#[derive(Clone, Debug)]
pub struct CustomPartition {
    /// Bölüm aygit adı; oluşturulacak (ör. "/dev/sda1")
    pub device: String,
    /// Boyut MB cinsinden; 0 = "kalan alan"
    pub size_mb: u64,
    /// Dosya sistemi
    pub fstype: FsType,
    /// Bağlama noktası; swap için "swap"
    pub mountpoint: String,
    /// LUKS şifreleme aktif mi?
    pub encrypt: bool,
    /// LUKS şifresi
    pub luks_password: String,
    /// LUKS harici adı (ör. "cryptroot")
    pub luks_name: String,
}

/// Kurulum boyunca toplanan tüm veriler.
pub struct GlobalState {
    pub language: String,
    pub timezone: String,
    pub selected_disk: Option<String>,
    pub erase_disk: bool,
    pub partition_plan: Option<PartitionPlan>,
    /// Manuel bölümleme modu için kullanıcının tanımladığı bölümler.
    pub custom_partitions: Vec<CustomPartition>,
    pub volume_groups: Vec<VolumeGroup>,
    pub logical_volumes: Vec<LogicalVolume>,
    pub keyboard_layout: String,
    pub keyboard_variant: String,
    pub real_name: String,
    pub username: String,
    pub password: String,
    pub password_confirm: String,
    pub hostname: String,
    pub current_step: usize,
    pub available_disks: Vec<DiskInfo>,
    pub install_progress: f32,
    pub install_sub_progress: f32,
    pub install_log: Vec<String>,
    pub install_current_file: Option<String>,
    pub demo_mode: bool,
    pub is_dark: bool,
    pub rescue_mode: bool,
    pub bootloader_device: String,
    pub bootloader_timeout: u32,
    pub bootloader_password: String,
    pub kernel_options: String,
    pub root_password: String,
    pub root_password_confirm: String,
    pub display_manager: String,
    pub autologin: bool,
    pub desktop_environment: String,
    pub network_wifi_password: String,
    pub network_http_proxy: String,
    pub network_https_proxy: String,
    pub network_ftp_proxy: String,
    pub use_ntp: bool,
    pub manual_year: i32,
    pub manual_month: u32,
    pub manual_day: u32,
    pub manual_hour: u32,
    pub manual_minute: u32,
    #[allow(dead_code)]
    pub encrypt_root: bool,
    #[allow(dead_code)]
    pub luks_password: String,
    pub oem_mode: bool,
    /// OEM modunda: kullanıcı varsayılan şifreyi değiştirdi mi?
    /// true olmadan kurulum ilerleyemez.
    pub oem_password_changed: bool,
    pub selected_package_groups: Vec<String>,
    /// branding.toml [slides.icons] tablosundan yüklenen ikon → dosya URI eşlemesi.
    /// Slideshow bu map üzerinden çalışma zamanında görsel yollarını çözümler.
    pub branding_icons: std::collections::HashMap<String, String>,
    /// Sidebar için koyu tema logo URI'si.
    pub branding_yali_dark: String,
    pub branding_pisi_dark: String,
    /// Sidebar için açık tema logo URI'si.
    pub branding_yali_light: String,
    pub branding_pisi_light: String,
    /// branding.toml dosyasından yüklenen slaytlar.
    pub branding_slides: Vec<crate::branding::SlideItem>,
}

impl Default for GlobalState {
    fn default() -> Self {
        Self {
            language: "tr".to_string(),
            timezone: "Europe/Istanbul".to_string(),
            selected_disk: None,
            erase_disk: true,
            partition_plan: None,
            custom_partitions: Vec::new(),
            volume_groups: Vec::new(),
            logical_volumes: Vec::new(),
            keyboard_layout: "tr".to_string(),
            keyboard_variant: String::new(),
            real_name: String::new(),
            username: String::new(),
            password: String::new(),
            password_confirm: String::new(),
            hostname: String::new(),
            current_step: 0,
            available_disks: Vec::new(),
            install_progress: 0.0,
            install_sub_progress: 0.0,
            install_log: Vec::new(),
            install_current_file: None,
            demo_mode: false,
            is_dark: true,
            rescue_mode: false,
            bootloader_device: String::new(),
            bootloader_timeout: 5,
            bootloader_password: String::new(),
            kernel_options: String::new(),
            root_password: String::new(),
            root_password_confirm: String::new(),
            network_wifi_password: String::new(),
            network_http_proxy: String::new(),
            network_https_proxy: String::new(),
            network_ftp_proxy: String::new(),
            use_ntp: true,
            manual_year: 2026,
            manual_month: 5,
            manual_day: 26,
            manual_hour: 12,
            manual_minute: 0,
            encrypt_root: false,
            luks_password: String::new(),
            oem_mode: false,
            oem_password_changed: false,
            selected_package_groups: Vec::new(),
            display_manager: "sddm".to_string(),
            autologin: false,
            desktop_environment: detect_desktop_environment(),
            branding_icons: std::collections::HashMap::new(),
            branding_pisi_dark: String::new(),
            branding_pisi_light: String::new(),
            branding_yali_dark: String::new(),
            branding_yali_light: String::new(),
            branding_slides: Vec::new(),
        }
    }
}

// WELCOME STEP  (sistem gereksinimleri + dil seçimi)
// ─────────────────────────────────────────────

use crate::funct::language_selector_ui;
use crate::autoinstall::checker::{CheckResult, CheckStatus, run_all, all_passed};

pub struct WelcomeStep {
    checks:        Vec<CheckResult>,
    checked:       bool,
    last_language: String,
}

impl Default for WelcomeStep {
    fn default() -> Self {
        Self {
            checks:        Vec::new(),
            checked:       false,
            last_language: String::new(),
        }
    }
}

impl InstallerStep for WelcomeStep {
    fn name(&self) -> String { t!("welcome").to_string() }

    fn on_enter(&mut self, state: &mut GlobalState) {
        if !self.checked || self.last_language != state.language {
            rust_i18n::set_locale(&state.language);
            self.checks  = run_all();
            self.checked = true;
            self.last_language = state.language.clone();
        }
    }

    fn show(&mut self, ui: &mut egui::Ui, state: &mut GlobalState) {
        use crate::ui::theme;

        if self.last_language != state.language {
            rust_i18n::set_locale(&state.language);
            self.checks = run_all();
            self.last_language = state.language.clone();
        }

        theme::section_heading(ui, &t!("welcome_title"));

        ui.label( 
            egui::RichText::new(t!("welcome_description"))
                .color(theme::c_text_dim())
                .size(15.0),
        );

        ui.add_space(16.0);

        ui.vertical_centered(|ui| {
            let logo_uri = if state.is_dark {
                &state.branding_pisi_dark
            } else {
                &state.branding_pisi_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);
            let os_name = System::name().unwrap_or_else(|| "Bilinmiyor".to_string());
            ui.label(
                egui::RichText::new(format!("{} : {}", t!("os"), os_name))
                    .strong()
                    .size(16.0)
                    .color(theme::c_text_dim()),
            );
            ui.add_space(4.0);
            let os_version = System::os_version().unwrap_or_else(|| "Bilinmiyor".to_string());
            ui.label(
                egui::RichText::new(format!("{} : {}", t!("version"), os_version))
                    .size(14.0)
                    .color(theme::c_text_dim()),
            );

            let desktop_name = std::env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
            ui.label(
                egui::RichText::new(format!("{} : {}", t!("desktop"), desktop_name))
                    .size(14.0)
                    .color(theme::c_text_dim()),
            );
        });

        

        ui.add_space(12.0);

        // Dil seçimi (Açılır Liste / ComboBox)
        // ui.horizontal(|ui| {
        //     ui.label(t!("select_language"));
        //     let current_lang_label = if state.language == "tr" { "🇹🇷  Türkçe" } else { "🇺🇸  English" };
        //     egui::ComboBox::from_id_source("language_select")
        //         .selected_text(current_lang_label)
        //         .show_ui(ui, |ui| {
        //             ui.selectable_value(&mut state.language, "tr".to_string(), "🇹🇷  Türkçe");
        //             ui.selectable_value(&mut state.language, "en".to_string(), "🇺🇸  English");
        //         });
        // });
        language_selector_ui(ui, state);

        ui.add_space(14.0);
        ui.separator();
        ui.add_space(10.0);

        ui.label(
            egui::RichText::new(t!("system_checks_title"))
                .size(15.0)
                .strong()
                .color(theme::c_text()),
        );
        ui.add_space(10.0);

                // Hata varsa uyarı
        ui.add_space(10.0);
        let has_fail = self.checks.iter().any(|c| c.status == CheckStatus::Fail);
        if has_fail {
            theme::error_box(ui, &t!("check_fail_warning"));
        } else if self.checks.iter().any(|c| c.status == CheckStatus::Warn) {
            theme::warning_box(ui, &t!("check_warn_notice"));
        } else if !self.checks.is_empty() {
            theme::success_box(ui, &t!("check_all_pass"));
        }

        ui.add_space(10.0);

        // Kontrol tablosu
        egui::Grid::new("checks_grid")
            .num_columns(3)
            .spacing([10.0, 6.0])
            .show(ui, |ui| {
                for check in &self.checks {
                    match check.status {
                        CheckStatus::Pass => {
                            ui.add(
                                egui::Image::new(egui::include_image!("../assets/icons/check.svg"))
                                    .max_width(18.0).max_height(18.0)
                                    .tint(theme::c_success())
                            );
                        }
                        CheckStatus::Warn => {
                            ui.add(
                                egui::Image::new(egui::include_image!("../assets/icons/warning-icon.svg"))
                                    .max_width(18.0).max_height(18.0)
                                    .tint(theme::c_warning())
                            );
                        }
                        CheckStatus::Fail => {
                            ui.add(
                                egui::Image::new(egui::include_image!("../assets/icons/fail-icon.svg"))
                                    .max_width(18.0).max_height(18.0)
                                    .tint(theme::c_error())
                            );
                        }
                    }
                    ui.label(egui::RichText::new(&check.name).strong().color(theme::c_text()));
                    ui.label(
                        egui::RichText::new(&check.message)
                            .size(12.0)
                            .color(theme::c_text_dim()),
                    );
                    ui.end_row();
                }
            });

        // Rescue mode butonu
        ui.add_space(10.0);
      
        egui::Frame::none()            
            .rounding(egui::Rounding::same(6.0))
            .inner_margin(egui::Margin::symmetric(8.0, 4.0))
            .show(ui, |ui| {
                ui.horizontal(|ui| {
                    let rescue_available = detect_existing_linux();
                    if rescue_available {
                        if theme::light_gray_btn(ui, &t!("rescue_button")).clicked() {
                            state.rescue_mode = true;
                        }

                        if theme::light_gray_btn(ui, &t!("recheck")).clicked() {
                            self.checked = false;
                            self.on_enter(state);
                        }
                    } else {
                        ui.label(
                            egui::RichText::new(t!("rescue_not_available"))
                                .size(12.0)
                                .color(egui::Color32::from_rgb(120, 120, 140)),
                        );
                    }
                });
            });



       
        
    }

    fn is_complete(&self, state: &GlobalState) -> bool {
        if state.demo_mode {
            return true;
        }
        !self.checks.is_empty() && all_passed(&self.checks)
    }
}



/// Mevcut bir Linux kurulumu olup olmadığını kontrol eder.
/// Basitçe /mnt/etc/fstab varlığına veya blkid ile Linux bölümlerine bakar.
fn detect_existing_linux() -> bool {
    // /etc/fstab veya /mnt/etc/fstab kontrolü
    if std::path::Path::new("/mnt/etc/fstab").exists() {
        return true;
    }
    // blkid ile Linux bölümlerini tara
    if let Ok(out) = std::process::Command::new("blkid")
        .args(["-o", "list"])
        .output()
    {
        let text = String::from_utf8_lossy(&out.stdout);
        text.lines().any(|l| l.contains("ext4") || l.contains("btrfs") || l.contains("xfs"))
    } else {
        false
    }
}

