use crate::config::ThemeConfig;

/// Available actions for commits in the log view
#[derive(Debug, Clone, PartialEq)]
pub enum LogAction {
    /// Show full commit details
    ShowDetail,
    /// Cherry-pick this commit
    CherryPick,
    /// Revert this commit
    Revert,
    /// Amend this commit (only for HEAD)
    Amend,
    /// Reset to this commit (soft)
    ResetSoft,
    /// Reset to this commit (mixed)
    ResetMixed,
    /// Reset to this commit (hard)
    ResetHard,
    /// Create branch at this commit
    CreateBranch,
    /// Create tag at this commit
    CreateTag,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Action {
    /// Show a confirmation dialog before executing an action.
    ShowConfirm(Box<Action>, String),
    /// Confirm the pending action.
    ConfirmExecute,
    /// Cancel the pending confirmation.
    ConfirmCancel,

    // Interactive rebase (inline) -------------------------------------------
    /// Begin constructing an interactive rebase from selected commits.
    StartInteractiveRebase(Vec<String>), // ordered list of commit hashes (oldest -> newest)
    /// Cycle action for the current rebase entry (pick/reword/edit/squash/fixup/drop).
    RebaseCycleAction,
    /// Set a specific action for the current rebase entry.
    RebaseSetAction(crate::app::state::RebaseAction),
    /// Move current rebase entry up.
    RebaseMoveUp,
    /// Move current rebase entry down.
    RebaseMoveDown,
    /// Select next entry.
    RebaseNext,
    /// Select previous entry.
    RebasePrev,
    /// Save and run the interactive rebase (writes git-rebase-todo).
    RebaseSaveAndRun,
    /// Cancel interactive rebase construction (discard).
    RebaseCancel,
    /// Mark rebase todo as dirty.
    RebaseMarkDirty,
    /// Update rebase todo loaded from disk (e.g., on resume).
    RebaseLoadTodo(Vec<String>),
    /// Set the base commit for the interactive rebase (hash).
    RebaseSetBase(String),
    /// Toggle selection of the current commit in the log for rebase.
    LogToggleSelect,
    /// Set commit message for reword (editorless).
    SetRewordMessage(String),
    /// Save and close the reword modal.
    SaveAndCloseReword(String),
    /// Set reword author name (editorless reword).
    SetRewordAuthorName(String),
    /// Set reword author email (editorless reword).
    SetRewordAuthorEmail(String),
    /// Focus and clear reword author name field.
    FocusAndClearRewordAuthorName,
    /// Focus and clear reword author email field.
    FocusAndClearRewordAuthorEmail,
    /// Focus edit message field.
    FocusEditMessage,
    /// Focus edit author name field.
    FocusEditAuthorName,
    /// Focus edit author email field.
    FocusEditAuthorEmail,
    /// Focus and clear edit author name field.
    FocusAndClearEditAuthorName,
    /// Focus and clear edit author email field.
    FocusAndClearEditAuthorEmail,
    /// Set commit message for edit (editorless).
    SetEditMessage(String),
    /// Save and close the edit modal.
    SaveAndCloseEdit(String),
    /// Set edit author name (editorless edit).
    SetEditAuthorName(String),
    /// Set edit author email (editorless edit).
    SetEditAuthorEmail(String),
    /// Open the edit modal with initial text.
    OpenEditModal(String),
    /// Close the edit modal.
    CloseEditModal,
    /// Abort rebase from builder.
    RebaseAbortFromBuilder,
    /// Set which field is focused in the reword modal.
    SetRewordFocus(crate::app::state::RewordField),
    /// Open the reword modal with initial text.
    OpenRewordModal(String),
    /// Close the reword modal.
    CloseRewordModal,
    /// Request to stop the app.
    Quit, // unit variant: no payload, just the variant itself
    /// A periodic tick (for timers/redraws).
    Tick, // unit variant
    /// Toggle help overlay.
    ToggleHelp,
    /// Load full diff (remove truncation cap).
    LoadFullDiff,
    /// Show theme picker.
    ShowThemePicker,
    /// Hide theme picker.
    HideThemePicker,
    /// Theme picker navigation up.
    ThemePickerUp,
    /// Theme picker navigation down.
    ThemePickerDown,
    /// Apply theme by name.
    ApplyTheme(String),
    /// Set available themes list.
    SetAvailableThemes(Vec<String>),
    /// Reload theme from config/themes.
    ReloadTheme,
    /// Reload all configuration (themes, custom_commands, commit_template, editor_command).
    ReloadConfig,
    /// Focus diff pane for scrolling.
    FocusDiff,
    /// Return focus to status pane.
    FocusStatus,
    /// Begin theme preview (store prior theme).
    ThemePreviewStart(Box<ThemeConfig>),
    /// Apply theme preview on selection.
    ThemePreviewApply(Box<ThemeConfig>),
    /// Cancel theme preview, restore prior theme.
    ThemePreviewCancel,
    /// Set theme preview and selection index.
    ThemePreviewSet(usize, Box<ThemeConfig>),
    /// Update the last status snapshot (raw for now).
    SetStatus(String),
    /// Update parsed status lines for rendering.
    SetStatusLines(Vec<String>),
    /// Update parsed status entries.
    SetStatusEntries(Vec<crate::git::parsers::status::StatusEntry>),
    /// Record last status fetch error (if any).
    SetStatusError(Option<String>),
    /// Set error guidance with actionable suggestions.
    SetErrorGuidance(Option<crate::app::error_guidance::ErrorGuidance>),
    /// Update workflow context.
    UpdateWorkflowContext,
    /// Move selection up in status list.
    StatusUp,
    /// Move selection down in status list.
    StatusDown,
    /// Page up in status list.
    StatusPageUp,
    /// Page down in status list.
    StatusPageDown,
    /// Jump to top of status list.
    StatusTop,
    /// Jump to bottom of status list.
    StatusBottom,
    /// Cycle focus forward.
    FocusNext,
    /// Cycle focus backward.
    FocusPrev,
    /// Record last refreshed timestamp text.
    SetLastRefreshed(Option<String>),
    /// Mark refreshing state.
    SetRefreshing(bool),
    /// Track selected status path detail.
    SetSelectedPath(String),
    /// Store last diff text for selected path.
    SetDiffText(String),
    /// Track which path the last diff came from.
    SetLastDiffPath(String),
    /// Track whether stored diff text was truncated.
    SetLastDiffTruncated(bool),
    /// Track total lines in last diff.
    SetLastDiffTotal(usize),
    /// Toggle diff mode (working vs staged).
    ToggleDiffMode,
    /// Track timestamp for last diff fetch.
    SetLastDiffFetchedAt(Option<String>),
    /// Update structured status summary.
    SetStatusSummary(crate::git::parsers::status::StatusSummary),
    /// Update last diff (raw).
    SetDiff(String),
    /// Update parsed diff (placeholder).
    SetDiffParsed(crate::git::DiffParseResult),
    /// Move help selection up.
    HelpUp,
    /// Move help selection down.
    HelpDown,
    /// Scroll detail pane up.
    DetailScrollUp,
    /// Scroll detail pane down.
    DetailScrollDown,
    /// Reset detail scroll to top.
    DetailScrollReset,
    /// Set current branch name.
    SetCurrentBranch(String),
    /// Toggle file selection for multi-select.
    ToggleFileSelect(String),
    /// Clear all file selections.
    ClearFileSelects,
    /// Set branch list.
    SetBranches(Vec<crate::app::state::BranchEntry>),
    /// Move branch selection up.
    BranchUp,
    /// Move branch selection down.
    BranchDown,
    /// Set commit log.
    SetCommits(Vec<crate::app::state::CommitEntry>),
    /// Move commit selection up.
    CommitUp,
    /// Move commit selection down.
    CommitDown,
    /// Enter commit message mode.
    StartCommit,
    /// Start amend mode (loads last commit info).
    StartAmend,
    /// Load last commit info for amend.
    LoadLastCommitInfo,
    /// Set last commit info.
    SetLastCommitInfo(Option<crate::app::state::LastCommitInfo>),
    /// Set amend author name.
    SetAmendAuthorName(String),
    /// Set amend author email.
    SetAmendAuthorEmail(String),
    /// Switch to editing a specific amend field (Tab navigation).
    SetAmendEditingField(Option<crate::app::state::AmendField>),
    /// Exit commit message mode.
    CancelCommit,
    /// Update commit message input.
    SetCommitInput(String),
    /// Append char to commit input.
    CommitInputChar(char),
    /// Backspace in commit input.
    CommitInputBackspace,
    /// Set feedback message.
    SetFeedback(Option<String>),
    /// Set status filter string.
    SetStatusFilter(String),
    /// Enable/disable filter mode.
    SetFilterMode(bool),
    /// Set per-file scroll offsets.
    SetFileScroll(String, (usize, usize)),
    /// Set stash list.
    SetStashes(Vec<crate::app::state::StashEntry>),
    /// Move stash selection up.
    StashUp,
    /// Move stash selection down.
    StashDown,
    /// Set detail horizontal scroll.
    SetDetailScrollX(usize),
    /// Apply diff scroll reset for path.
    ResetFileScroll(String),
    /// Set ahead/behind info into branches (update entries).
    SetBranchAheadBehind(String, i32, i32),
    /// Start filter mode for status list.
    StartFilter,
    /// Cancel filter mode.
    CancelFilter,
    /// Append char to filter input.
    FilterInputChar(char),
    /// Backspace in filter input.
    FilterInputBackspace,
    /// Horizontal scroll left in detail.
    DetailScrollLeft,
    /// Horizontal scroll right in detail.
    DetailScrollRight,
    /// Start branch create mode.
    StartBranchCreate,
    /// Cancel branch create mode.
    CancelBranchCreate,
    /// Append char to branch name input.
    BranchInputChar(char),
    /// Backspace in branch name input.
    BranchInputBackspace,
    /// Submit branch name for creation.
    BranchSubmit,
    /// Start stash creation mode.
    StartStashCreate,
    /// Cancel stash creation.
    CancelStashCreate,
    /// Add character to stash message input.
    StashInputChar(char),
    /// Remove last character from stash message input.
    StashInputBackspace,
    /// Submit stash creation.
    StashSubmit,
    /// Delete a stash.
    DeleteStash(String),
    /// Execute a custom command from config.
    ExecuteCustomCommand(String),
    /// Set branch selection directly.
    SetBranchSelected(usize),
    /// Set hunks list (start,end indices).
    SetHunks(Vec<(usize, usize)>),
    /// Move to next hunk.
    HunkNext,
    /// Move to previous hunk.
    HunkPrev,
    /// Toggle word diff mode.
    ToggleWordDiff,
    /// Toggle line select mode.
    ToggleLineSelectMode,
    /// Toggle selection of a line in diff.
    ToggleLineSelect(usize),
    /// Clear all line selections.
    ClearLineSelects,
    /// Set tags list.
    SetTags(Vec<crate::app::state::TagEntry>),
    /// Move tag selection up.
    TagUp,
    /// Move tag selection down.
    TagDown,
    /// Toggle delta syntax highlighting.
    ToggleDelta,
    /// Set has_delta availability.
    SetHasDelta(bool),
    /// Increase diff context lines.
    IncreaseContext,
    /// Decrease diff context lines.
    DecreaseContext,
    /// Toggle whitespace ignore.
    ToggleWhitespace,
    /// Toggle side-by-side view.
    ToggleSideBySide,
    /// Toggle tree view.
    ToggleTreeView,
    /// Set reflog entries.
    SetReflog(Vec<crate::app::state::ReflogEntry>),
    /// Move reflog selection up.
    ReflogUp,
    /// Move reflog selection down.
    ReflogDown,
    /// Set commit detail text.
    SetCommitDetail(Option<String>),
    /// Toggle log graph.
    ToggleLogGraph,
    /// Set log graph text.
    SetLogGraphText(String),
    /// Set file history path.
    SetFileHistoryPath(Option<String>),
    /// Set remotes list.
    SetRemotes(Vec<crate::app::state::RemoteEntry>),
    /// Move remote selection up.
    RemoteUp,
    /// Move remote selection down.
    RemoteDown,
    /// Show command palette.
    ShowPalette,
    /// Hide command palette.
    HidePalette,
    /// Update palette filter input.
    SetPaletteInput(String),
    /// Move palette selection up.
    PaletteUp,
    /// Move palette selection down.
    PaletteDown,
    /// Add async task.
    AddAsyncTask(crate::app::state::AsyncTask),
    /// Complete async task.
    CompleteAsyncTask(u64),
    /// Fail async task.
    FailAsyncTask(u64, String),
    /// Remove completed tasks.
    CleanupAsyncTasks,
    /// Commit staged changes with message.
    CommitSubmit,
    /// Amend last commit with new message/content.
    AmendCommit,
    /// Push current branch.
    Push,
    /// Cherry-pick selected commit.
    CherryPickSelected,
    /// Revert selected commit.
    RevertSelected,
    /// Continue rebase.
    RebaseContinue,
    /// Abort rebase.
    RebaseAbort,
    /// Skip current rebase step.
    RebaseSkip,
    /// Show interactive rebase todo list.
    ShowRebaseTodo,
    /// Hide interactive rebase todo list.
    HideRebaseTodo,
    /// Move selection up in rebase todo.
    RebaseTodoUp,
    /// Move selection down in rebase todo.
    RebaseTodoDown,
    /// Set todo contents (no path context).
    SetRebaseTodo(Vec<String>),
    /// Set todo contents with path context.
    SetRebaseTodoWithPath(Vec<String>, String),
    /// Record todo file path.
    SetRebaseTodoPath(String),
    /// Toggle the kind (pick/edit/squash/fixup/drop/reword) of a todo line.
    RebaseTodoToggleKind(usize, String),
    /// Rewrite a todo line with custom text.
    RebaseTodoRewriteLine(usize, String),
    /// Begin editing a todo line with initial text.
    StartRebaseTodoEdit(usize, String),
    /// Update the in-flight todo edit buffer.
    RebaseTodoEditBuffer(String),
    /// Save current todo edits to disk.
    SaveRebaseTodo,
    /// Open todo in editor.
    OpenRebaseTodoInEditor,
    /// Reset hard to selected commit (or HEAD~1).
    ResetHard,
    /// Reset mixed to selected commit (or HEAD~1).
    ResetMixed,
    /// Reset soft to selected commit (or HEAD~1).
    ResetSoft,
    /// Request confirmation for reset hard.
    RequestResetHard,
    /// Request confirmation for reset mixed.
    RequestResetMixed,
    /// Request confirmation for reset soft.
    RequestResetSoft,
    /// Cancel pending reset confirmation.
    CancelReset,
    /// Set current op status text (None clears).
    SetOpStatus(Option<String>),
    /// Append a line to op log ring buffer.
    AppendOpLog(String),
    /// Toggle op log popup.
    ToggleOpLog,
    /// Show op log popup.
    ShowOpLog,
    /// Toggle merge notifier on/off.
    ToggleMergeNotifier,
    /// Set merge base branch name.
    SetMergeBaseBranch(String),
    /// Update merge notifier ahead count (None clears).
    SetMergeAhead(Option<i32>),
    /// Set merge notifier interval seconds.
    SetMergeInterval(u64),
    /// Tick for merge notifier (used by refresh loop timer).
    MergeNotifierTick,
    /// Manually check upstream merge status.
    CheckMergeStatus,
    /// Append a line to merge notifier log.
    AppendMergeLog(String),
    /// Toggle merge notifier log popup.
    ToggleMergeLog,
    /// List merged branches (safe, no delete).
    ListMergedBranches,
    /// Request prune merged branches (confirm step).
    RequestPruneMergedBranches,
    /// Prune merged branches after confirm.
    PruneMergedBranches,
    /// Show remote URL (append to log/feedback).
    ShowRemoteUrl(String),
    /// Set remote URL to SSH form if not already SSH.
    SetRemoteSsh(String),
    /// Request remote prune (confirm step).
    RequestRemotePrune(String),
    /// Remote prune after confirm.
    RemotePrune(String),
    /// Show brief git log.
    ShowLogBrief,
    /// Show git log with stats.
    ShowLogStats,
    /// Pull with ff-only flag.
    Pull,
    /// Pull with rebase (autostash optional).
    PullRebase,
    /// Set pull timeout seconds.
    SetPullTimeout(u64),
    /// Set rebase timeout seconds.
    SetRebaseTimeout(u64),
    /// Toggle ff-only pull (default true).
    ToggleFFOnly,
    /// Toggle autostash for pull --rebase.
    ToggleAutostash,
    /// Toggle auto-fetch cadence.
    ToggleAutoFetch,
    /// Set auto-fetch interval seconds.
    SetAutoFetchInterval(u64),
    /// Set auto-fetch remote name.
    SetAutoFetchRemote(String),
    /// Manually trigger auto-fetch check.
    CheckAutoFetch,
    /// Show PR helper.
    ShowPrHelper,
    /// Hide PR helper.
    HidePrHelper,
    /// Move PR selection up.
    PrHelperUp,
    /// Move PR selection down.
    PrHelperDown,
    /// Open selected PR in browser.
    OpenPrInBrowser(String),
    /// Checkout PR branch.
    CheckoutPr(String),
    /// Set PR list.
    SetPrList(Vec<crate::app::state::PrItem>),
    /// Show only conflicted files in status.
    FilterConflictsOnly,
    /// Clear conflicts-only filter.
    ClearConflictFilter,
    /// Show conflicts popup.
    ShowConflictsPopup,
    /// Hide conflicts popup.
    HideConflictsPopup,
    /// Move selection up in conflicts popup.
    ConflictsPopupUp,
    /// Move selection down in conflicts popup.
    ConflictsPopupDown,
    /// Select a conflict entry by path (sets selection and closes popup).
    SelectConflict(String),
    /// Select a conflict entry and open in editor.
    OpenConflictInEditor(String),
    /// Show guided conflicts helper.
    ShowConflictsGuided,
    /// Hide guided conflicts helper.
    HideConflictsGuided,
    /// Move selection up in guided conflicts.
    ConflictsGuidedUp,
    /// Move selection down in guided conflicts.
    ConflictsGuidedDown,
    /// Open selected conflict in editor (guided).
    OpenGuidedConflictInEditor,
    /// Open selected file in $EDITOR (for conflict resolve).
    OpenInEditor,
    /// Stage current hunk.
    StageCurrentHunk,
    /// Unstage current hunk.
    UnstageCurrentHunk,
    /// Stage selected lines.
    StageSelectedLines,
    /// Unstage selected lines.
    UnstageSelectedLines,
    /// Jump to next conflict.
    StatusNextConflict,
    /// Jump to previous conflict.
    StatusPrevConflict,
    /// Toggle push ff-only guard (on by default).
    TogglePushFFOnly,
    /// Show merge base picker.
    ShowMergeBasePicker,
    /// Hide merge base picker.
    HideMergeBasePicker,
    /// Move selection up in merge base picker.
    MergeBaseUp,
    /// Move selection down in merge base picker.
    MergeBaseDown,
    /// Apply merge base from picker.
    ApplyMergeBase(String),
    /// Set merge base candidates list.
    SetMergeBaseCandidates(Vec<String>),
    /// Stage selected file (handled by command layer).
    StageSelectedFile,
    /// Unstage selected file (handled by command layer).
    UnstageSelectedFile,
    /// Stage all unstaged/untracked files.
    StageAllFiles,
    /// Unstage all staged files.
    UnstageAllFiles,
    /// Jump to next staged file.
    StatusNextStaged,
    /// Jump to previous staged file.
    StatusPrevStaged,
    /// Refresh branches list.
    RefreshBranches,
    /// Checkout branch.
    CheckoutBranch(String),
    /// Checkout remote branch as new local branch.
    CheckoutRemoteBranch(String),
    /// Delete branch (with confirmation).
    DeleteBranch(String),
    /// Merge branch into current.
    MergeBranch(String),
    /// Rebase current branch onto selected branch.
    RebaseBranch(String),
    /// Refresh commits list.
    RefreshCommits,
    /// Show commit detail.
    ShowCommitDetail(String),
    /// Show log action menu for a commit.
    ShowLogActionMenu(String), // hash
    /// Hide log action menu.
    HideLogActionMenu,
    /// Navigate up in log action menu.
    LogActionMenuUp,
    /// Navigate down in log action menu.
    LogActionMenuDown,
    /// Execute selected log action.
    ExecuteLogAction(LogAction),
    /// Cherry-pick commit (with confirmation).
    CherryPickCommit(String),
    /// Revert commit (with confirmation).
    RevertCommit(String),
    /// Refresh status.
    RefreshStatus,
    /// Request refresh with rate limiting and immediate feedback.
    RequestRefreshStatus,
    /// Refresh stashes list.
    RefreshStashes,
    /// Apply stash.
    ApplyStash(String),
    /// Pop stash.
    PopStash(String),
    /// Refresh tags list.
    RefreshTags,
    /// Checkout tag.
    CheckoutTag(String),
    /// Delete tag (with confirmation).
    DeleteTag(String),
    /// Refresh reflog list.
    RefreshReflog,
    /// Set reflog entries.
    CheckoutReflog(String),
}

// Note: SetTags, TagUp, TagDown, ReflogUp, ReflogDown already exist earlier in the enum

// usage

// fn handle(action: Action) {
//     match action {
//         Action::Quit => {
//             println!("quitting");
//         }
//         Action::Tick => {
//             println!("tick");
//         }
//         Action::SetStatus(msg) => {
//             println!("status: {}", msg);
//         }
//         Action::Resize { width, height } => {
//             println!("resize to {}x{}", width, height);
//         }
//     }
// }

// fn main() {
//     handle(Action::Quit);
//     handle(Action::Tick);
//     handle(Action::SetStatus("syncing".to_string()));
//     handle(Action::Resize { width: 120, height: 30 });
// }

// #[repr(u16)]           // optional: fixes the underlying type to u16
// enum Code {
//     Ok = 0,
//     NotFound = 404,
// }

// fn handle(code: Code) {
//     match code {
//         Code::Ok => println!("OK"),
//         Code::NotFound => println!("Not found"),
//     }
// }

// fn main() {
//     handle(Code::Ok);
//     handle(Code::NotFound);
//     // You can also cast to the integer discriminant:
//     let n: u16 = Code::NotFound as u16;
//     println!("Numeric code: {}", n); // prints 404
// }