/* repo_view/rewrite_helpers.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::prelude::*;

use super::{RepoView, RepoViewMsg};
use crate::git;
use crate::stash_switch_dialog::{StashSwitchDialog, StashSwitchDialogInit, StashSwitchDialogOutput};

pub(super) struct RewriteToastLabels<'a> {
    pub completed: &'a str,
    pub completed_with_stash: &'a str,
    pub paused_no_conflicts: &'a str,
    pub paused_no_conflicts_with_stash: &'a str,
}

pub(super) fn rewrite_outcome_toast(
    result: &Result<git::RebaseOutcome, String>,
    stashed: bool,
    labels: RewriteToastLabels<'_>,
) -> String {
    match (result, stashed) {
        (Ok(git::RebaseOutcome::Completed { .. }), false) => labels.completed.to_string(),
        (Ok(git::RebaseOutcome::Completed { .. }), true) => labels.completed_with_stash.to_string(),

        (Ok(git::RebaseOutcome::Paused { has_conflicts: true }), _) => {
            gettext("Conflicts encountered, resolve and continue the rebase")
        }

        (Ok(git::RebaseOutcome::Paused { has_conflicts: false }), false) => labels.paused_no_conflicts.to_string(),
        (Ok(git::RebaseOutcome::Paused { has_conflicts: false }), true) => {
            labels.paused_no_conflicts_with_stash.to_string()
        }

        (Err(msg), false) => msg.clone(),
        (Err(msg), true) => {
            format!("{}; {}", msg, gettext("your changes are stashed, pop them via the Stashes view"))
        }
    }
}

impl RepoView {
    pub(super) fn open_rewrite_stash_choice_dialog<F, G>(
        &mut self,
        body: String,
        summary: git::DirtySummary,
        sender: &ComponentSender<Self>,
        root: &adw::ToastOverlay,
        on_stash: F,
        on_cancel: G,
    ) where
        F: Fn(git::StashPushFlags) -> RepoViewMsg + 'static,
        G: Fn() -> RepoViewMsg + 'static,
    {
        let window = root.ancestor(gtk::Window::static_type()).and_downcast::<gtk::Window>();

        self.stash_switch_dialog = Some(
            StashSwitchDialog::builder()
                .launch(StashSwitchDialogInit {
                    heading: gettext("Uncommitted Changes"),
                    body,
                    proceed_label: String::new(),
                    allow_skip_stash: false,
                    has_tracked_changes: summary.has_tracked_changes,
                    has_untracked: summary.has_untracked,
                    parent_window: window,
                })
                .forward(sender.input_sender(), move |output| match output {
                    StashSwitchDialogOutput::StashTrackedOnly => on_stash(git::StashPushFlags::Default),
                    StashSwitchDialogOutput::StashWithUntracked => on_stash(git::StashPushFlags::IncludeUntracked),
                    StashSwitchDialogOutput::ProceedWithoutStash | StashSwitchDialogOutput::Cancelled => on_cancel(),
                }),
        );
    }
}
