use crate::model::{self, FollowUp, LaunchQuantization, PatternSpeed, SyncMode};
use crate::state::editor::{EuclideanField, PatternField, PatternPropsField, ScriptField};
use crate::state::file_browser::FileBrowserState;

#[derive(Clone, PartialEq, Eq)]
pub enum ConfirmAction {
    Quit,
    DeleteStep { bank: usize, pattern: usize, step: usize },
    DeleteSteps { bank: usize, pattern: usize, steps: Vec<usize> },
    ResetPattern { bank: usize, pattern: usize },
    ResetBank { bank: usize },
    ResetPatterns { bank: usize, patterns: Vec<usize> },
    ResetBanks { banks: Vec<usize> },
    ImportBank { bank: usize },
}

impl ConfirmAction {
    pub fn message(&self) -> String {
        match self {
            Self::Quit => "Quit?".into(),
            Self::DeleteStep { step, .. } => format!("Delete step {}?", step + 1),
            Self::DeleteSteps { steps, .. } => {
                let nums: Vec<String> = steps.iter().map(|s| format!("{:02}", s + 1)).collect();
                format!("Delete steps {}?", nums.join(", "))
            }
            Self::ResetPattern { pattern, .. } => format!("Reset pattern {}?", pattern + 1),
            Self::ResetBank { bank } => format!("Reset bank {}?", bank + 1),
            Self::ResetPatterns { patterns, .. } => format!("Reset {} patterns?", patterns.len()),
            Self::ResetBanks { banks } => format!("Reset {} banks?", banks.len()),
            Self::ImportBank { bank } => format!("Import bank from clipboard? (replaces bank {:02})", bank + 1),
        }
    }
}

#[derive(Clone, PartialEq, Eq)]
pub enum RenameTarget {
    Bank { bank: usize },
    Pattern { bank: usize, pattern: usize },
    Step { bank: usize, pattern: usize, step: usize },
    DescribePattern { bank: usize, pattern: usize },
}

impl RenameTarget {
    pub fn title(&self) -> String {
        match self {
            Self::Bank { bank } => format!("Rename Bank {:02}", bank + 1),
            Self::Pattern { bank, pattern } => format!("Rename {}", model::bp_label(*bank, *pattern)),
            Self::Step { step, .. } => format!("Name Step {:02}", step + 1),
            Self::DescribePattern { bank, pattern } => {
                format!("Describe {}", model::bp_label(*bank, *pattern))
            }
        }
    }
}

#[derive(Clone, PartialEq, Eq)]
pub enum Modal {
    None,
    Confirm {
        action: ConfirmAction,
        selected: bool,
    },
    FileBrowser(Box<FileBrowserState>),
    Rename {
        target: RenameTarget,
        name: String,
    },
    SetPattern {
        field: PatternField,
        input: String,
    },
    SetScript {
        field: ScriptField,
        input: String,
    },
    SetTempo(String),
    JumpToStep(String),
    AddSamplePath(Box<FileBrowserState>),
    Editor,
    PatternProps {
        bank: usize,
        pattern: usize,
        field: PatternPropsField,
        name: String,
        description: String,
        length: String,
        speed: PatternSpeed,
        quantization: LaunchQuantization,
        sync_mode: SyncMode,
        follow_up: FollowUp,
    },
    KeybindingsHelp {
        scroll: usize,
    },
    EuclideanDistribution {
        bank: usize,
        pattern: usize,
        source_step: usize,
        field: EuclideanField,
        pulses: String,
        steps: String,
        rotation: String,
    },
    Onboarding { page: usize },
}
