// SPDX-FileCopyrightText: 2024 Andrey Kutejko <andy128k@gmail.com>
// SPDX-FileCopyrightText: 2026 Wladimir Palant https://palant.info/
//
// SPDX-License-Identifier: GPL-3.0-or-later

use crate::{
    layout::color_themes::ColorTheme,
    utils::{SenderExt, WindowExt},
};
use gettextrs::gettext;
use gtk::prelude::*;

pub async fn edit_colors(parent_window: &gtk::Window, theme: ColorTheme) -> Option<ColorTheme> {
    let dialog = gtk::Window::builder()
        .transient_for(parent_window)
        .modal(true)
        .title(gettext("Edit Colors…"))
        .resizable(false)
        .build();
    dialog.add_css_class("dialog");

    let grid = gtk::Grid::builder().build();
    dialog.set_child(Some(&grid));

    let color_dialog = gtk::ColorDialog::builder().modal(true).build();

    let default_fg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.norm_fg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&default_fg, 1, 1, 1, 1);

    let default_bg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.norm_bg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&default_bg, 2, 1, 1, 1);

    let alternate_fg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.alt_fg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&alternate_fg, 1, 2, 1, 1);

    let alternate_bg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.alt_bg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&alternate_bg, 2, 2, 1, 1);

    let selected_fg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.sel_fg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&selected_fg, 1, 3, 1, 1);

    let selected_bg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.sel_bg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&selected_bg, 2, 3, 1, 1);

    let cursor_fg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.curs_fg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&cursor_fg, 1, 4, 1, 1);

    let cursor_bg = gtk::ColorDialogButton::builder()
        .halign(gtk::Align::Center)
        .rgba(&theme.curs_bg)
        .dialog(&color_dialog)
        .build();
    grid.attach(&cursor_bg, 2, 4, 1, 1);

    let label_foreground = gtk::Label::builder()
        .label(gettext("Foreground"))
        .hexpand(true)
        .halign(gtk::Align::Center)
        .build();
    grid.attach(&label_foreground, 1, 0, 1, 1);

    let label_background = gtk::Label::builder()
        .label(gettext("Background"))
        .hexpand(true)
        .halign(gtk::Align::Center)
        .build();
    grid.attach(&label_background, 2, 0, 1, 1);

    let label_default = gtk::Label::builder()
        .label(gettext("Default:"))
        .halign(gtk::Align::Start)
        .build();
    grid.attach(&label_default, 0, 1, 1, 1);
    if let Some(button) = default_fg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_default.upcast_ref(),
            label_foreground.upcast_ref(),
        ])]);
    }
    if let Some(button) = default_bg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_default.upcast_ref(),
            label_background.upcast_ref(),
        ])]);
    }

    let label_alternatve = gtk::Label::builder()
        .label(gettext("Alternate:"))
        .halign(gtk::Align::Start)
        .build();
    grid.attach(&label_alternatve, 0, 2, 1, 1);
    if let Some(button) = alternate_fg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_alternatve.upcast_ref(),
            label_foreground.upcast_ref(),
        ])]);
    }
    if let Some(button) = alternate_bg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_alternatve.upcast_ref(),
            label_background.upcast_ref(),
        ])]);
    }

    let label_selected = gtk::Label::builder()
        .label(gettext("Selected file:"))
        .halign(gtk::Align::Start)
        .build();
    grid.attach(&label_selected, 0, 3, 1, 1);
    if let Some(button) = selected_fg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_selected.upcast_ref(),
            label_foreground.upcast_ref(),
        ])]);
    }
    if let Some(button) = selected_bg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_selected.upcast_ref(),
            label_background.upcast_ref(),
        ])]);
    }

    let label_cursor = gtk::Label::builder()
        .label(gettext("Cursor:"))
        .halign(gtk::Align::Start)
        .build();
    grid.attach(&label_cursor, 0, 4, 1, 1);
    if let Some(button) = cursor_fg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_cursor.upcast_ref(),
            label_foreground.upcast_ref(),
        ])]);
    }
    if let Some(button) = cursor_bg.first_child() {
        button.update_relation(&[gtk::accessible::Relation::DescribedBy(&[
            label_cursor.upcast_ref(),
            label_background.upcast_ref(),
        ])]);
    }

    let close_button = gtk::Button::builder()
        .label(gettext("_Close"))
        .use_underline(true)
        .hexpand(true)
        .halign(gtk::Align::Center)
        .build();
    grid.attach(&close_button, 0, 5, 3, 1);

    let (sender, receiver) = async_channel::bounded::<()>(1);
    close_button.connect_clicked(glib::clone!(
        #[strong]
        sender,
        move |_| sender.toss(())
    ));
    dialog.set_cancel_widget(&close_button);

    dialog.present();
    let ok = receiver.recv().await == Ok(());

    let theme = ok.then(|| ColorTheme {
        norm_fg: default_fg.rgba(),
        norm_bg: default_bg.rgba(),
        alt_fg: alternate_fg.rgba(),
        alt_bg: alternate_bg.rgba(),
        sel_fg: selected_fg.rgba(),
        sel_bg: selected_bg.rgba(),
        curs_fg: cursor_fg.rgba(),
        curs_bg: cursor_bg.rgba(),
    });

    dialog.close();

    theme
}
