// SPDX-License-Identifier: GPL-3.0-or-later
// Renders the settings and onboarding screens.
// File: ./src/gui/view/settings.rs
use crate::config::{AppTheme, LogLevel};
use crate::gui::icon;
use crate::gui::message::Message;
use crate::gui::state::{AppState, GuiApp};
use crate::storage::LOCAL_CALENDAR_HREF;

use iced::widget::{
    MouseArea, Space, button, checkbox, column, container, row, scrollable, text, text_input,
    tooltip,
};
use iced::{Color, Element, Length, Theme};
#[cfg(feature = "gui")]
use iced_aw::color_picker;
use strum::IntoEnumIterator;

#[derive(Debug, Clone, PartialEq, Eq)]
struct LangOption {
    code: String,
    label: String,
}

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

// Dynamically maps ISO codes to their native names using `isolang`
fn get_native_language_name(code: &str) -> String {
    // Extract base code (e.g., "pt" from "pt-BR") for the lookup
    let base_code = code.split(&['-', '_'][..]).next().unwrap_or(code);

    if let Some(lang) = isolang::Language::from_639_1(base_code) {
        // Prefer the autonym (native name), fallback to English name
        let raw_name = lang.to_autonym().unwrap_or_else(|| lang.to_name());

        // Capitalize the first letter nicely for UI presentation
        let mut chars = raw_name.chars();
        match chars.next() {
            None => String::new(),
            Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
        }
    } else {
        code.to_string() // Fallback to raw code if completely unknown
    }
}

pub fn view_settings(app: &GuiApp) -> Element<'_, Message> {
    let is_settings = matches!(app.state, AppState::Settings);

    // --- Header with Back Button ---
    let title_text = text(if is_settings {
        rust_i18n::t!("settings")
    } else {
        rust_i18n::t!("welcome_title")
    })
    .size(40);

    let title_row = if is_settings {
        row![
            button(icon::icon(icon::ARROW_LEFT).size(24))
                .style(button::text)
                .on_press(Message::CancelSettings),
            title_text,
            Space::new().width(Length::Fill)
        ]
        .spacing(20)
        .align_y(iced::Alignment::Center)
    } else {
        row![title_text, Space::new().width(Length::Fill)]
    };

    let title_drag_area: Element<_> =
        MouseArea::new(container(title_row).width(Length::Fill).padding(20))
            .on_press(Message::WindowDragged)
            .into();

    let error = if let Some(e) = &app.error_msg {
        text(e).color(Color::from_rgb(1.0, 0.0, 0.0))
    } else if let Some(Some(warn)) = crate::system::KEYRING_WARNING.get() {
        text(warn).color(Color::from_rgb(1.0, 0.6, 0.0))
    } else {
        text("")
    };

    if app.config_was_corrupted {
        let error_text = app.error_msg.clone().unwrap_or_default();

        return container(
            column![
                icon::icon(icon::TRASH)
                    .size(40)
                    .color(Color::from_rgb(0.8, 0.2, 0.2)),
                text(rust_i18n::t!("config_error_title")).size(24),
                text(rust_i18n::t!("config_error_corrupted")).size(16),
                container(
                    text(error_text)
                        .size(14)
                        .font(iced::Font::MONOSPACE)
                        .color(Color::from_rgb(0.8, 0.1, 0.1))
                )
                .padding(10)
                .style(container::rounded_box),
                text(rust_i18n::t!("config_error_fix_remove")),
                button(text(rust_i18n::t!("quit_application")))
                    .style(button::danger)
                    .on_press(Message::CloseWindow)
            ]
            .spacing(20)
            .align_x(iced::Alignment::Center),
        )
        .width(Length::Fill)
        .height(Length::Fill)
        .center_x(Length::Fill)
        .center_y(Length::Fill)
        .into();
    }

    #[derive(Debug, Clone, PartialEq, Eq)]
    struct CalOption {
        name: String,
        href: String,
    }
    impl std::fmt::Display for CalOption {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "{}", self.name)
        }
    }

    let cal_options: Vec<CalOption> = app
        .calendars
        .iter()
        .filter(|c| c.href != crate::storage::LOCAL_TRASH_HREF && c.href != "local://recovery")
        .map(|c| CalOption {
            name: c.name.clone(),
            href: c.href.clone(),
        })
        .collect();

    let current_cal_opt = cal_options
        .iter()
        .find(|o| {
            Some(&o.href) == app.ob_default_cal.as_ref()
                || Some(&o.name) == app.ob_default_cal.as_ref()
        })
        .cloned();

    let picker: Element<_> = if !cal_options.is_empty() && is_settings {
        column![
            text(rust_i18n::t!("default_collection")),
            iced::widget::pick_list(cal_options, current_cal_opt, |opt| {
                Message::ObDefaultCalChanged(opt.href)
            })
            .width(Length::Fill)
            .padding(10)
        ]
        .spacing(5)
        .into()
    } else {
        Space::new().width(0).into()
    };

    // Language selector: Auto-detects available locales from rust_i18n
    let lang_picker: Element<_> = if is_settings {
        let mut lang_options = vec![LangOption {
            code: "auto".to_string(),
            label: rust_i18n::t!("language_system").to_string(),
        }];

        // Dynamically populate from the locales/ folder
        let mut available = rust_i18n::available_locales!().to_vec();
        available.sort(); // Keep the dropdown alphabetical by code

        for loc in available {
            lang_options.push(LangOption {
                code: loc.to_string(),
                label: get_native_language_name(&loc),
            });
        }

        let current_lang_code = app.language.clone().unwrap_or_else(|| "auto".to_string());
        let current_lang_opt = lang_options
            .iter()
            .find(|o| o.code == current_lang_code)
            .cloned()
            .unwrap_or_else(|| lang_options[0].clone());

        let lang_picker_row = row![
            text(rust_i18n::t!("language_select")),
            iced::widget::pick_list(lang_options, Some(current_lang_opt), |opt| {
                Message::SetLanguage(opt.code)
            })
        ]
        .spacing(10)
        .align_y(iced::Alignment::Center);

        column![
            lang_picker_row,
            button(
                text(rust_i18n::t!(
                    "translation_help",
                    url = "translate.codeberg.org"
                ))
                .size(12)
                .style(|theme: &Theme| text::Style {
                    color: Some(theme.extended_palette().primary.base.color)
                })
            )
            .style(button::text)
            .padding(0)
            .on_press(Message::OpenUrl(
                "https://translate.codeberg.org/projects/cfait/".to_string()
            ))
        ]
        .spacing(5)
        .into()
    } else {
        Space::new().width(0).into()
    };

    // Theme selection UI
    let theme_picker: Element<_> = if is_settings {
        container(
            column![
                row![
                    text(rust_i18n::t!("app_theme")),
                    iced::widget::pick_list(
                        AppTheme::iter().collect::<Vec<_>>(),
                        Some(app.current_theme),
                        Message::ThemeChanged
                    )
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
            ]
            .spacing(10),
        )
        .into()
    } else {
        Space::new().width(0).into()
    };

    let notifications_ui: Element<_> = if is_settings {
        column![
            text(rust_i18n::t!("notifications_and_reminders")).size(20),
            checkbox::<Message, iced::Theme, iced::Renderer>(app.auto_reminders)
                .label(rust_i18n::t!("auto_remind_on_due_start_label"))
                .on_toggle(Message::SetAutoReminders),
            row![
                text(rust_i18n::t!("default_time_label")).width(Length::Fixed(200.0)),
                text_input("09:00", &app.default_reminder_time)
                    .on_input(Message::SetDefaultReminderTime)
                    .width(Length::Fixed(80.0))
                    .padding(5)
            ]
            .spacing(10)
            .align_y(iced::Alignment::Center),
            text(rust_i18n::t!("snooze_presets")).size(14),
            row![
                text(rust_i18n::t!("short_label")),
                text_input("1h", &app.ob_snooze_short_input)
                    .on_input(Message::SetSnoozeShort)
                    .width(Length::Fixed(60.0))
                    .padding(5),
                text(rust_i18n::t!("long_label")),
                text_input("1d", &app.ob_snooze_long_input)
                    .on_input(Message::SetSnoozeLong)
                    .width(Length::Fixed(60.0))
                    .padding(5)
            ]
            .spacing(10)
            .align_y(iced::Alignment::Center),
            row![
                text(rust_i18n::t!("sync_interval_label")).width(Length::Fixed(200.0)),
                text_input("30m", &app.ob_auto_refresh_input)
                    .on_input(Message::SetAutoRefreshInterval)
                    .width(Length::Fixed(60.0))
                    .padding(5)
            ]
            .spacing(10)
            .align_y(iced::Alignment::Center),
            text("").size(5),
            text(rust_i18n::t!("calendar_integration")).size(20),
            {
                let cb =
                    checkbox::<Message, iced::Theme, iced::Renderer>(app.create_events_for_tasks)
                        .label(rust_i18n::t!("create_calendar_events_for_tasks_with_dates"));
                if !app.deleting_events {
                    cb.on_toggle(Message::SetCreateEventsForTasks)
                } else {
                    cb
                }
            },
            text(rust_i18n::t!("create_calendar_events_note"))
                .size(12)
                .color(Color::from_rgb(0.6, 0.6, 0.6)),
            text("").size(5),
            {
                let cb = checkbox::<Message, iced::Theme, iced::Renderer>(
                    app.delete_events_on_completion,
                )
                .label(rust_i18n::t!("delete_calendar_events_on_completion_label"));
                if !app.deleting_events {
                    cb.on_toggle(Message::SetDeleteEventsOnCompletion)
                } else {
                    cb
                }
            },
            text(rust_i18n::t!("events_deleted_on_task_delete"))
                .size(12)
                .color(Color::from_rgb(0.6, 0.6, 0.6)),
            {
                let btn = button(text(rust_i18n::t!("delete_all_calendar_events")));
                if !app.deleting_events {
                    btn.on_press(Message::DeleteAllCalendarEvents)
                } else {
                    btn
                }
            },
            if app.deleting_events {
                text(rust_i18n::t!("export_debug_status_exporting"))
                    .size(12)
                    .color(Color::from_rgb(0.6, 0.6, 0.6))
            } else {
                text(rust_i18n::t!("calendar_events_reversible_note"))
                    .size(12)
                    .color(Color::from_rgb(0.6, 0.6, 0.6))
            },
        ]
        .spacing(10)
        .into()
    } else {
        Space::new().width(0).into()
    };

    let advanced_ui: Element<_> = if is_settings {
        let content = if app.show_advanced_settings {
            let hide_fully_ui: Element<_> = if !app.hide_completed {
                checkbox::<Message, iced::Theme, iced::Renderer>(app.hide_fully_completed_tags)
                    .label(rust_i18n::t!("hide_fully_completed_tags"))
                    .on_toggle(Message::ToggleHideFullyCompletedTags)
                    .into()
            } else {
                Space::new().width(0).into()
            };

            column![
                text(rust_i18n::t!("sorting_and_visibility")).size(20),
                checkbox::<Message, iced::Theme, iced::Renderer>(app.hide_completed)
                    .label(rust_i18n::t!("hide_completed_and_canceled_tasks"))
                    .on_toggle(Message::ToggleHideCompleted),
                hide_fully_ui,
                tooltip(
                    checkbox::<Message, iced::Theme, iced::Renderer>(app.hide_aliases_in_sidebar)
                        .label(rust_i18n::t!("hide_aliases_in_sidebar"))
                        .on_toggle(Message::ToggleHideAliasesInSidebar),
                    text(rust_i18n::t!("hide_aliases_in_sidebar_tooltip")).size(12),
                    tooltip::Position::Top
                )
                .style(crate::gui::view::tooltip_style)
                .delay(std::time::Duration::from_millis(700)),
                checkbox::<Message, iced::Theme, iced::Renderer>(app.show_priority_numbers)
                    .label(rust_i18n::t!("show_priority_numbers"))
                    .on_toggle(Message::SetShowPriorityNumbers),
                checkbox::<Message, iced::Theme, iced::Renderer>(app.strikethrough_completed)
                    .label(rust_i18n::t!("strikethrough_completed"))
                    .on_toggle(Message::SetStrikethroughCompleted),
                checkbox::<Message, iced::Theme, iced::Renderer>(app.sort_standard_by_priority)
                    .label(rust_i18n::t!("sort_standard_by_priority_label"))
                    .on_toggle(Message::ToggleSortStandardByPriority),
                Space::new().height(10),
                row![
                    text(rust_i18n::t!("sorting_preset_label")).width(Length::Fixed(200.0)),
                    iced::widget::pick_list(
                        crate::config::SortPreset::iter().collect::<Vec<_>>(),
                        Some(app.sort_preset),
                        Message::SetSortPreset
                    )
                    .width(Length::Fill)
                    .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                Space::new().height(10),
                text(rust_i18n::t!("priority_rules")).size(16),
                row![
                    text(rust_i18n::t!("due_within_days")).width(Length::Fixed(150.0)),
                    text_input("1", &app.ob_urgent_days_input)
                        .on_input(Message::ObUrgentDaysChanged)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                row![
                    text(rust_i18n::t!("priority_le")).width(Length::Fixed(150.0)),
                    text_input("1", &app.ob_urgent_prio_input)
                        .on_input(Message::ObUrgentPrioChanged)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                row![
                    text(rust_i18n::t!("default_priority_label")).width(Length::Fixed(150.0)),
                    text_input("5", &app.ob_default_priority_input)
                        .on_input(Message::ObDefaultPriorityChanged)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                Space::new().height(10),
                text(rust_i18n::t!("sorting_timeframes")).size(16),
                row![
                    text(rust_i18n::t!("start_grace_days")).width(Length::Fixed(150.0)),
                    text_input("1", &app.ob_start_grace_input)
                        .on_input(Message::ObStartGraceChanged)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                row![
                    text(rust_i18n::t!("priority_cutoff_months")).width(Length::Fixed(150.0)),
                    text_input("6", &app.ob_sort_months_input)
                        .on_input(Message::ObSortMonthsChanged)
                        .width(Length::Fixed(100.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                Space::new().height(10),
                text(rust_i18n::t!("display_limits")).size(16),
                row![
                    text(rust_i18n::t!("max_completed_tasks_root")).width(Length::Fixed(200.0)),
                    text_input("20", &app.ob_max_done_roots_input)
                        .on_input(Message::SetMaxDoneRoots)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                text(rust_i18n::t!("max_completed_tasks_root_explain"))
                    .size(12)
                    .color(Color::from_rgb(0.6, 0.6, 0.6)),
                Space::new().height(10),
                row![
                    text(rust_i18n::t!("max_completed_subtasks")).width(Length::Fixed(200.0)),
                    text_input("5", &app.ob_max_done_subtasks_input)
                        .on_input(Message::SetMaxDoneSubtasks)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                text(rust_i18n::t!("max_completed_subtasks_explain"))
                    .size(12)
                    .color(Color::from_rgb(0.6, 0.6, 0.6)),
                Space::new().height(10),
                text(rust_i18n::t!("pinned_actions_label")).size(16),
                {
                    let mut action_col = column![].spacing(2);
                    for action in crate::config::TaskAction::ALL {
                        let is_pinned = app.pinned_actions.contains(action);
                        let action_val = *action; // Copy for closure

                        let icon_char = match action_val {
                            crate::config::TaskAction::CompleteAndShift => icon::REPEAT,
                            crate::config::TaskAction::ToggleDetails => icon::INFO,
                            crate::config::TaskAction::ToggleTimer => icon::PLAY,
                            crate::config::TaskAction::StopTimer => icon::DEBUG_STOP,
                            crate::config::TaskAction::AddSession => icon::TIMER_PLUS,
                            crate::config::TaskAction::IncreasePriority => icon::PLUS,
                            crate::config::TaskAction::DecreasePriority => icon::MINUS,
                            crate::config::TaskAction::Cancel => icon::CROSS,
                            crate::config::TaskAction::Edit => icon::EDIT,
                            crate::config::TaskAction::Delete
                            | crate::config::TaskAction::DeleteTree => icon::TRASH,
                            crate::config::TaskAction::Yank => icon::LINK,
                            crate::config::TaskAction::ExtractSubtasks => {
                                icon::get_extract_subtasks_icon()
                            }
                            crate::config::TaskAction::TogglePin => icon::THUMB_TACK,
                            crate::config::TaskAction::CreateSubtask => icon::CREATE_CHILD,
                            crate::config::TaskAction::DuplicateTree => icon::CLONE,
                            crate::config::TaskAction::Promote => icon::ELEVATOR_UP,
                            crate::config::TaskAction::Move => icon::MOVE,
                            crate::config::TaskAction::OpenCoordinates => icon::MAP_LOCATION_DOT,
                            crate::config::TaskAction::OpenLocations => icon::MAP_MARKER_MULTIPLE,
                            crate::config::TaskAction::OpenUrl => icon::URL_CHECK,
                        };

                        let check_icon = if is_pinned {
                            icon::CHECK_SQUARE
                        } else {
                            icon::SQUARE
                        };

                        let toggle_row = row![
                            icon::icon(check_icon).size(16),
                            icon::icon(icon_char).size(14).width(Length::Fixed(20.0)),
                            text(action.label()).size(14)
                        ]
                        .spacing(8)
                        .align_y(iced::Alignment::Center);

                        let row_btn = button(toggle_row)
                            .style(iced::widget::button::text)
                            .padding(4)
                            .width(Length::Fill)
                            .on_press(Message::TogglePinnedAction(action_val, !is_pinned));

                        action_col = action_col.push(row_btn);
                    }
                    action_col
                },
                Space::new().height(10),
                text(rust_i18n::t!("data_management")).size(16),
                row![
                    text(rust_i18n::t!("trash_retention_days_label")).width(Length::Fixed(200.0)),
                    text_input("14", &app.ob_trash_retention_input)
                        .on_input(Message::SetTrashRetention)
                        .width(Length::Fixed(60.0))
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                text(rust_i18n::t!("trash_retention_explain"))
                    .size(12)
                    .color(Color::from_rgb(0.6, 0.6, 0.6)),
                Space::new().height(10),
                text(rust_i18n::t!("logging_label")).size(16),
                row![
                    text(rust_i18n::t!("log_level_label")).width(Length::Fixed(200.0)),
                    iced::widget::pick_list(
                        LogLevel::ALL.to_vec(),
                        Some(app.log_level),
                        Message::SetLogLevel
                    )
                    .width(Length::Fixed(120.0))
                    .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                text(rust_i18n::t!("log_level_explain"))
                    .size(12)
                    .color(Color::from_rgb(0.6, 0.6, 0.6)),
                Space::new().height(10),
                text(rust_i18n::t!("quick_filter_title")).size(16),
                checkbox::<Message, iced::Theme, iced::Renderer>(app.show_quick_filter)
                    .label(rust_i18n::t!("quick_filter_show_button"))
                    .on_toggle(Message::SetShowQuickFilter),
                row![
                    text(rust_i18n::t!("quick_filter_search_term")).width(Length::Fixed(150.0)),
                    text_input("is:ready", &app.ob_quick_filter_term_input)
                        .on_input(Message::SetQuickFilterTerm)
                        .width(Length::Fill)
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
                row![
                    text(rust_i18n::t!("quick_filter_icon")).width(Length::Fixed(150.0)),
                    text_input("f0fa9", &app.ob_quick_filter_icon_input)
                        .on_input(Message::SetQuickFilterIcon)
                        .width(Length::Fill)
                        .padding(5)
                ]
                .spacing(10)
                .align_y(iced::Alignment::Center),
            ]
            .spacing(5)
            .padding(10)
        } else {
            column![]
        };

        column![
            button(
                row![
                    text(rust_i18n::t!("advanced_settings_button")).size(16),
                    Space::new().width(Length::Fill),
                    icon::icon(if app.show_advanced_settings {
                        icon::ARROW_EXPAND_UP
                    } else {
                        icon::ARROW_EXPAND_DOWN
                    })
                    .size(14)
                ]
                .align_y(iced::Alignment::Center)
            )
            .width(Length::Fill)
            .style(iced::widget::button::text)
            .on_press(Message::ToggleAdvancedSettings(!app.show_advanced_settings)),
            content
        ]
        .spacing(5)
        .into()
    } else {
        Space::new().width(0).into()
    };

    let aliases_ui: Element<_> = if is_settings {
        let input_row = row![
            text_input(&rust_i18n::t!("alias_key_label"), &app.alias_input_key)
                .on_input(Message::AliasKeyInput)
                .padding(5)
                .width(Length::FillPortion(1)),
            text_input(&rust_i18n::t!("alias_value_label"), &app.alias_input_values)
                .on_input(Message::AliasValueInput)
                .on_submit(Message::AddAlias)
                .padding(5)
                .width(Length::FillPortion(2)),
            if app.editing_alias_key.is_some() {
                row![
                    button(icon::icon(icon::CHECK).size(14))
                        .style(button::success)
                        .padding(6)
                        .on_press(Message::AddAlias),
                    button(icon::icon(icon::CROSS).size(14))
                        .style(button::danger)
                        .padding(6)
                        .on_press(Message::CancelEditAlias)
                ]
                .spacing(5)
            } else {
                row![
                    button(text(rust_i18n::t!("add")))
                        .padding(5)
                        .on_press(Message::AddAlias)
                ]
            }
        ]
        .spacing(10)
        .align_y(iced::Alignment::Center);

        let mut list_col = column![
            text(rust_i18n::t!("tag_aliases")).size(20),
            input_row,
            iced::widget::rule::horizontal(1)
        ]
        .spacing(10);

        let mut sorted_aliases: Vec<_> = app.tag_aliases.iter().collect();
        sorted_aliases.sort_by_key(|(k, _)| k.to_string());

        for (key, vals) in sorted_aliases {
            let val_str = vals.join(", ");
            let is_editing_this = app.editing_alias_key.as_ref() == Some(key);

            let key_text = text(if key.starts_with("@@") {
                key.to_string()
            } else {
                format!("#{}", key)
            })
            .width(Length::FillPortion(1))
            .wrapping(iced::widget::text::Wrapping::Glyph)
            .style(if is_editing_this {
                |theme: &Theme| text::Style {
                    color: Some(theme.extended_palette().primary.base.color),
                }
            } else {
                |_: &Theme| text::Style::default()
            });

            let val_text = text(val_str.clone())
                .width(Length::FillPortion(2))
                .wrapping(iced::widget::text::Wrapping::Glyph)
                .style(if is_editing_this {
                    |theme: &Theme| text::Style {
                        color: Some(theme.extended_palette().primary.base.color),
                    }
                } else {
                    |_: &Theme| text::Style::default()
                });

            let row_item = row![
                key_text,
                text("->").width(Length::Fixed(20.0)),
                val_text,
                button(icon::icon(icon::EDIT).size(12))
                    .style(button::secondary)
                    .padding(5)
                    .on_press(Message::EditAlias(key.clone(), val_str)),
                button(icon::icon(icon::CROSS).size(12))
                    .style(button::danger)
                    .padding(5)
                    .on_press(Message::RemoveAlias(key.clone()))
            ]
            .spacing(10)
            .align_y(iced::Alignment::Center);
            list_col = list_col.push(row_item);
        }

        let area = container(list_col).padding(10).style(|_| container::Style {
            border: iced::Border {
                radius: 4.0.into(),
                width: 1.0,
                color: Color::from_rgb(0.3, 0.3, 0.3),
            },
            ..Default::default()
        });
        area.into()
    } else {
        Space::new().width(0).into()
    };

    let cal_mgmt_ui: Element<_> =
        if is_settings && (!app.calendars.is_empty() || !app.remote_cals_editing.is_empty()) {
            let mut col = column![text(rust_i18n::t!("remote_collections")).size(20)].spacing(10);

            for cal in &app.remote_cals_editing {
                let cal_href = cal.href.clone();
                let is_enabled = !app.disabled_calendars.contains(&cal_href);

                let checkbox_elem = {
                    let href = cal_href.clone();
                    checkbox::<Message, iced::Theme, iced::Renderer>(is_enabled)
                        .label("")
                        .on_toggle(move |v| Message::ToggleCalendarDisabled(href.clone(), !v))
                };

                let name_input = {
                    let href = cal_href.clone();
                    text_input(&rust_i18n::t!("name_label"), &cal.name)
                        .on_input(move |s| Message::RemoteCalendarNameChanged(href.clone(), s))
                        .padding(5)
                        .width(Length::Fill)
                };

                let original_cal = app.calendars.iter().find(|c| c.href == cal_href);
                let has_changes = original_cal
                    .is_none_or(|orig| orig.name != cal.name || orig.color != cal.color);

                let current_color = cal
                    .color
                    .as_ref()
                    .and_then(|h| crate::color_utils::parse_hex_to_floats(h))
                    .map(|(r, g, b)| Color::from_rgb(r, g, b))
                    .unwrap_or(Color::from_rgb(0.5, 0.5, 0.5));

                let color_btn = {
                    let href = cal_href.clone();
                    button(
                        text(icon::PALETTE_COLOR.to_string())
                            .font(icon::FONT)
                            .size(16)
                            .color(current_color),
                    )
                    .padding(5)
                    .style(button::text)
                    .on_press(Message::OpenColorPicker(href.clone(), current_color))
                };

                let color_widget: Element<_> =
                    if app.color_picker_active_href.as_ref() == Some(&cal_href) {
                        color_picker::ColorPicker::new(
                            true,
                            current_color,
                            color_btn,
                            Message::CancelColorPicker,
                            Message::SubmitColorPicker,
                        )
                        .into()
                    } else {
                        color_btn.into()
                    };

                let save_btn: Element<_> = if has_changes {
                    let h = cal.href.clone();
                    button(
                        icon::icon(icon::CHECK)
                            .size(16)
                            .color(app.theme().extended_palette().primary.base.color),
                    )
                    .style(button::text)
                    .padding(5)
                    .on_press(Message::SubmitRemoteCalendar(h))
                    .into()
                } else {
                    Space::new().width(Length::Fixed(26.0)).into()
                };

                col = col.push(
                    row![checkbox_elem, name_input, color_widget, save_btn]
                        .spacing(5)
                        .align_y(iced::Alignment::Center),
                );
            }

            col = col.push(
                button(text(rust_i18n::t!("create_new_remote_calendar")))
                    .style(button::secondary)
                    .on_press(Message::AddRemoteCalendar),
            );

            container(col)
                .padding(10)
                .style(|_| container::Style {
                    border: iced::Border {
                        radius: 4.0.into(),
                        width: 1.0,
                        color: Color::from_rgb(0.3, 0.3, 0.3),
                    },
                    ..Default::default()
                })
                .into()
        } else {
            Space::new().width(0).into()
        };

    let local_cal_ui: Element<_> = if is_settings {
        let mut local_cal_col = column![
            text(rust_i18n::t!("local_collections")).size(20),
            text(rust_i18n::t!("local_collections_explain"))
                .size(12)
                .color(Color::from_rgb(0.6, 0.6, 0.6)),
        ]
        .spacing(10);

        for cal in &app.local_cals_editing {
            let href = cal.href.clone();
            let is_default = href == LOCAL_CALENDAR_HREF;

            let name_input = text_input(&rust_i18n::t!("name_label"), &cal.name)
                .on_input(move |s| Message::LocalCalendarNameChanged(href.clone(), s))
                .padding(5)
                .width(Length::FillPortion(3));

            let export_href = cal.href.clone();
            let export_btn = button(
                row![
                    icon::icon(icon::EXPORT).size(14),
                    text(rust_i18n::t!("export")).size(10)
                ]
                .spacing(3)
                .align_y(iced::Alignment::Center),
            )
            .padding(5)
            .style(button::secondary)
            .on_press(Message::ExportLocalIcs(export_href));

            let import_href = cal.href.clone();
            let import_btn = button(
                row![
                    icon::icon(icon::IMPORT).size(14),
                    text(rust_i18n::t!("import_action")).size(10)
                ]
                .spacing(3)
                .align_y(iced::Alignment::Center),
            )
            .padding(5)
            .style(button::secondary)
            .on_press(Message::ImportLocalIcs(import_href));

            let current_color = cal
                .color
                .as_ref()
                .and_then(|h| crate::color_utils::parse_hex_to_floats(h))
                .map(|(r, g, b)| Color::from_rgb(r, g, b))
                .unwrap_or(Color::from_rgb(0.5, 0.5, 0.5));

            let color_btn = button(
                text(icon::PALETTE_COLOR.to_string())
                    .font(icon::FONT)
                    .size(16)
                    .color(current_color),
            )
            .padding(5)
            .style(button::text)
            .on_press(Message::OpenColorPicker(cal.href.clone(), current_color));

            let color_widget: Element<_> =
                if app.color_picker_active_href.as_ref() == Some(&cal.href) {
                    color_picker::ColorPicker::new(
                        true,
                        current_color,
                        color_btn,
                        Message::CancelColorPicker,
                        Message::SubmitColorPicker,
                    )
                    .into()
                } else {
                    color_btn.into()
                };

            let delete_btn: Element<_> = if !is_default {
                let h = cal.href.clone();
                button(icon::icon(icon::TRASH).size(14))
                    .style(button::danger)
                    .padding(5)
                    .on_press(Message::DeleteLocalCalendar(h))
                    .into()
            } else {
                Space::new().width(Length::Fixed(22.0)).into()
            };

            local_cal_col = local_cal_col.push(
                row![name_input, export_btn, import_btn, color_widget, delete_btn]
                    .spacing(5)
                    .align_y(iced::Alignment::Center),
            );
        }

        local_cal_col = local_cal_col.push(
            button(text(rust_i18n::t!("create_new_local_calendar")))
                .style(button::secondary)
                .on_press(Message::AddLocalCalendar),
        );

        container(local_cal_col)
            .padding(10)
            .style(|_| container::Style {
                border: iced::Border {
                    radius: 6.0.into(),
                    width: 1.0,
                    color: Color::from_rgba(0.5, 0.5, 0.5, 0.2),
                },
                ..Default::default()
            })
            .into()
    } else {
        Space::new().width(0).into()
    };

    let save_connect_btn = button(text(if is_settings {
        rust_i18n::t!("save_and_connect")
    } else {
        rust_i18n::t!("connect")
    }))
    .padding(10)
    .width(Length::Fill)
    .on_press(Message::ObSubmit);

    let insecure_check = checkbox::<Message, iced::Theme, iced::Renderer>(app.ob_insecure)
        .label(rust_i18n::t!("allow_insecure_ssl"))
        .on_toggle(Message::ObInsecureToggled)
        .size(16)
        .text_size(14);

    let offline_button_or_space: Element<_> = if !is_settings {
        button(text(rust_i18n::t!("local_label")))
            .padding(10)
            .style(button::secondary)
            .on_press(Message::ObSubmitOffline)
            .into()
    } else {
        Space::new().height(0).into()
    };

    // --- FORM LAYOUT ---
    let form = column![
        // 1. Connection Section
        container(
            column![
                text(rust_i18n::t!("server_connection")).size(20),
                text(rust_i18n::t!("caldav_url")),
                text_input("https://...", &app.ob_url)
                    .on_input(Message::ObUrlChanged)
                    .padding(10),
                text(rust_i18n::t!("username")),
                text_input(&rust_i18n::t!("username"), &app.ob_user)
                    .on_input(Message::ObUserChanged)
                    .padding(10),
                text(rust_i18n::t!("password")),
                row![
                    text_input(&rust_i18n::t!("password"), &app.ob_pass)
                        .on_input(Message::ObPassChanged)
                        .secure(!app.ob_password_visible)
                        .padding(10)
                        .width(Length::Fill),
                    button(
                        icon::icon(if app.ob_password_visible {
                            icon::EYE_CLOSED
                        } else {
                            icon::EYE
                        })
                        .size(20)
                    )
                    .style(button::text)
                    .padding(10)
                    .on_press(Message::ToggleObPasswordVisibility)
                ]
                .spacing(8)
                .align_y(iced::Alignment::Center),
                insecure_check,
                checkbox::<Message, iced::Theme, iced::Renderer>(app.sync_settings)
                    .label(rust_i18n::t!("sync_settings"))
                    .on_toggle(Message::SetSyncSettings),
                save_connect_btn
            ]
            .spacing(15)
        )
        .padding(10)
        .style(|_| container::Style {
            border: iced::Border {
                radius: 6.0.into(),
                width: 1.0,
                color: Color::from_rgba(0.5, 0.5, 0.5, 0.2)
            },
            ..Default::default()
        }),
        // 2. Preferences
        lang_picker,  // <-- language picker added to the form layout
        theme_picker, // <-- theme picker added to the form layout
        picker,
        cal_mgmt_ui,
        local_cal_ui,
        notifications_ui,
        aliases_ui,
        advanced_ui,
        // 3. Bottom Actions
        offline_button_or_space,
    ]
    .spacing(20)
    .max_width(500);

    let scrollable_content = column![error, form]
        .spacing(20)
        .align_x(iced::Alignment::Center);

    let main_col = column![
        title_drag_area,
        scrollable(
            container(scrollable_content)
                .width(Length::Fill)
                .padding(20)
                .center_x(Length::Fill),
        )
    ]
    .width(Length::Fill)
    .height(Length::Fill);

    container(main_col)
        .width(Length::Fill)
        .height(Length::Fill)
        .into()
}
