/* working_copy_view/gitignore.rs
 *
 * Copyright 2026 Christian Kruse
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

use adw::prelude::*;
use gettextrs::gettext;
use relm4::gtk;
use relm4::prelude::*;

use super::{RowSection, WorkingCopyView, WorkingCopyViewMsg, WorkingCopyViewOutput};
use crate::git;
use crate::text_prompt_dialog::{TextPromptDialog, TextPromptDialogInit, TextPromptDialogOutput};

#[derive(Debug)]
pub enum GitignoreAction {
    Requested { section: RowSection, idx: usize },
    Confirmed(String),
    Complete(Result<(), String>),
}

impl WorkingCopyView {
    pub(super) fn handle_gitignore_action(
        &mut self,
        action: GitignoreAction,
        sender: &ComponentSender<Self>,
        root: &gtk::Box,
    ) {
        match action {
            GitignoreAction::Requested { section, idx } => {
                let path = {
                    let factory = self.factory_for(section);
                    factory.get(idx).map(|r| r.file().path.clone())
                };

                if let Some(path) = path {
                    let window = root.ancestor(gtk::Window::static_type()).and_downcast::<gtk::Window>();

                    self.text_prompt_dialog = Some(
                        TextPromptDialog::builder()
                            .launch(TextPromptDialogInit {
                                heading: gettext("Add to .gitignore"),
                                body: gettext("The pattern will be appended to the .gitignore file."),
                                placeholder: String::new(),
                                initial: path,
                                confirm_label: gettext("Save"),
                                parent_window: window,
                                validator: None,
                                notice: None,
                            })
                            .forward(sender.input_sender(), |output| match output {
                                TextPromptDialogOutput::Confirmed(pattern) => {
                                    WorkingCopyViewMsg::Gitignore(GitignoreAction::Confirmed(pattern))
                                }

                                TextPromptDialogOutput::Cancelled => WorkingCopyViewMsg::ConfirmDialogDismissed,
                            }),
                    );
                }
            }

            GitignoreAction::Confirmed(pattern) => {
                self.text_prompt_dialog = None;
                let repo_path = self.path.clone();

                sender.spawn_oneshot_command(move || {
                    WorkingCopyViewMsg::Gitignore(GitignoreAction::Complete(git::add_to_gitignore(
                        &repo_path, &pattern,
                    )))
                });
            }

            GitignoreAction::Complete(result) => {
                if let Err(msg) = &result {
                    sender.output(WorkingCopyViewOutput::ShowToast(msg.clone())).ok();
                }

                let selected = self.selected_paths_all();
                self.spawn_refresh(sender, selected);
            }
        }
    }
}
