use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "mps", version, about = "Plain-text personal productivity CLI")]
pub struct Cli {
    /// Path to config file (default: ~/.mps_config.yaml)
    #[arg(long, global = true)]
    pub config_path: Option<String>,

    /// Recreate config even if it exists
    #[arg(long, global = true, default_value_t = false)]
    pub force: bool,

    #[command(subcommand)]
    pub command: Option<Commands>,
}

#[derive(Subcommand)]
pub enum Commands {
    /// Open a date's .mps file in $EDITOR (default: today)
    Open {
        /// Date to open (today, yesterday, YYYYMMDD, last friday, …)
        datesign: Option<String>,
    },

    /// List elements for a date as an indented tree
    List {
        /// Date (default: today)
        datesign: Option<String>,
        /// Filter by element type: task, note, log, reminder
        #[arg(short = 't', long)]
        r#type: Option<String>,
        /// Filter by tag name
        #[arg(short = 'g', long)]
        tag: Option<String>,
        /// Filter tasks by status: open, done
        #[arg(short = 's', long)]
        status: Option<String>,
        /// Show elements from SINCE up to DATESIGN
        #[arg(short = 'S', long)]
        since: Option<String>,
        /// Show human-readable ref column (task-1, mps-1.2, …)
        #[arg(short = 'r', long)]
        refs: bool,
        /// List elements across all dates in the archive
        #[arg(short = 'a', long)]
        all: bool,
        /// Filter character entries by person name
        #[arg(short = 'n', long)]
        name: Option<String>,
    },

    /// Append an element to today's file without opening an editor
    Append {
        /// Element type: task, note, log, reminder (aliases from config are resolved)
        kind: String,
        /// Element body text
        body: Vec<String>,
        /// Comma-separated tags (e.g. work,backend)
        #[arg(long)]
        tags: Option<String>,
        /// Task status: open (default) or done
        #[arg(long)]
        status: Option<String>,
        /// Time for reminders (e.g. 5pm, 10:30)
        #[arg(long)]
        at: Option<String>,
        /// Start time for logs (HH:MM)
        #[arg(long)]
        start_time: Option<String>,
        /// End time for logs (HH:MM)
        #[arg(long)]
        end_time: Option<String>,
        /// Person name for character entries
        #[arg(short = 'n', long)]
        name: Option<String>,
    },

    /// Update an element's attributes in-place
    Update {
        /// Element ref: human (task-1) or epoch (20260428.1)
        ref_path: String,
        /// Set task status: open or done
        #[arg(long)]
        status: Option<String>,
        /// Set log start time (HH:MM)
        #[arg(long = "start-time")]
        start_time: Option<String>,
        /// Set log end time (HH:MM)
        #[arg(long = "end-time")]
        end_time: Option<String>,
        /// Set reminder time
        #[arg(long)]
        at: Option<String>,
        /// Date context for human refs (default: today)
        #[arg(short = 'd', long)]
        date: Option<String>,
    },

    /// Edit an element's body text in $EDITOR
    Edit {
        /// Element ref: human (task-1) or epoch (20260428.1)
        ref_path: String,
        /// Date context for human refs (default: today)
        #[arg(short = 'd', long)]
        date: Option<String>,
    },

    /// Delete an element from its file
    Delete {
        /// Element ref: human (task-1) or epoch (20260428.1)
        ref_path: String,
        /// Date context for human refs (default: today)
        #[arg(short = 'd', long)]
        date: Option<String>,
        /// Skip confirmation prompt
        #[arg(short = 'y', long)]
        yes: bool,
    },

    /// Mark a task as done (shorthand for update REFPATH --status done)
    Done {
        /// Element ref: human (task-1) or epoch (20260428.1)
        ref_path: String,
        /// Date context for human refs (default: today)
        #[arg(short = 'd', long)]
        date: Option<String>,
    },

    /// Full-text search across all .mps files
    Search {
        /// Search query
        query: String,
        /// Filter by element type
        #[arg(short = 't', long)]
        r#type: Option<String>,
        /// Filter by tag
        #[arg(short = 'g', long)]
        tag: Option<String>,
        /// Search from this date onward
        #[arg(short = 'S', long)]
        since: Option<String>,
        /// Filter character entries by person name
        #[arg(short = 'n', long)]
        name: Option<String>,
    },

    /// Show element counts and log durations
    Stats {
        /// Date (default: today)
        datesign: Option<String>,
        /// Stats from SINCE up to DATESIGN
        #[arg(short = 'S', long)]
        since: Option<String>,
        /// Stats across all dates in the archive
        #[arg(short = 'a', long)]
        all: bool,
    },

    /// Show tag usage frequency bar chart
    Tags {
        /// Date (default: today)
        datesign: Option<String>,
        /// Filter by element type
        #[arg(short = 't', long)]
        r#type: Option<String>,
        /// Filter tasks by status
        #[arg(short = 's', long)]
        status: Option<String>,
        /// Tags from SINCE up to DATESIGN
        #[arg(short = 'S', long)]
        since: Option<String>,
        /// Count tags across all dates
        #[arg(short = 'a', long)]
        all: bool,
        /// Filter character entries by person name
        #[arg(short = 'n', long)]
        name: Option<String>,
    },

    /// Export elements to JSON or CSV on stdout
    Export {
        /// Date (default: today)
        datesign: Option<String>,
        /// Output format: json (default), csv
        #[arg(short = 'f', long, default_value = "json")]
        format: String,
        /// Filter by element type
        #[arg(short = 't', long)]
        r#type: Option<String>,
        /// Export from SINCE up to DATESIGN
        #[arg(short = 'S', long)]
        since: Option<String>,
    },

    /// View or edit MPS configuration
    Config {
        /// Subcommand: show (default) or edit
        subcommand: Option<String>,
    },

    /// Run git commands inside the storage directory
    Git {
        /// Git subcommand and args (auto = full cycle, autocommit = stage+commit)
        #[arg(trailing_var_arg = true)]
        args: Vec<String>,
    },

    /// Stage, commit, pull, and push (equivalent to git auto)
    Autogit,

    /// Run any shell command inside the storage directory
    Cmd {
        /// Command and arguments
        #[arg(trailing_var_arg = true)]
        args: Vec<String>,
    },

    /// Check for due reminders and open tasks; send desktop notifications
    Notify {
        /// Show what would be sent without actually sending
        #[arg(long)]
        dry_run: bool,
        /// Override the time window in minutes (default: from config)
        #[arg(long)]
        window: Option<u64>,
        /// Fire even if already notified within the window
        #[arg(long)]
        force: bool,
    },

    /// Manage the background notification daemon (systemd user timer)
    Daemon {
        /// Subcommand: install, remove, status, run
        subcommand: String,
    },

    /// Inspect or edit the .mps.meta sidecar config file
    Meta {
        /// Subcommand: show (default), clear, edit, sync up, sync down
        #[arg(trailing_var_arg = true)]
        args: Vec<String>,
    },

    /// Start the HTTP API server
    Serve {
        /// TCP port to listen on (default: 3000)
        #[arg(short = 'p', long)]
        port: Option<u16>,
        /// Host address to bind (default: 127.0.0.1)
        #[arg(long)]
        host: Option<String>,
        /// Bearer token for API auth (empty = no auth)
        #[arg(short = 't', long)]
        token: Option<String>,
    },

    /// Print version
    Version,
}
