use anyhow::Result;
use clap::{Parser, Subcommand};

/// Top-level CLI parser for the `plane` binary.
/// Parses arguments from stdin and delegates to the matched subcommand handler.
#[derive(Parser)]
#[command(name = "plane", version, about = "A fast, composable CLI for Plane.so")]
pub struct PlaneCli {
    #[command(subcommand)]
    subcommand: PlaneSubcommand,
}

/// Consuming accessor for the parsed CLI invocation
impl PlaneCli {
    /// Extracts the parsed subcommand, transferring ownership of arguments
    /// to the dispatch handler while discarding the top-level wrapper
    pub fn into_subcommand(self) -> PlaneSubcommand {
        self.subcommand
    }
}

/// Available subcommands for the `plane` CLI, each mapping to a distinct workflow.
/// Clap routes user input to the appropriate variant and parses subcommand-specific flags.
#[derive(Subcommand)]
pub enum PlaneSubcommand {
    /// List work items with rich filtering by state, assignee, label, and priority
    Ls(super::ls::ListWorkItemsArgs),
    /// Search work items by title text with case-insensitive substring matching
    Search(super::search::SearchWorkItemsArgs),
    /// Show full detail of a single work item including AC, comments, and activity
    Show(super::show::ShowWorkItemArgs),
    /// Create a new work item with inline flags for all fields
    Create(super::create::CreateWorkItemArgs),
    /// Batch-update fields on an existing work item in a single API call
    Update(super::update::UpdateWorkItemArgs),
    /// Mark a work item done with AC verification and optional completion comment
    Done(super::done::CompleteWorkItemArgs),
    /// Permanently delete a work item with confirmation prompt
    Delete(super::delete::DeleteWorkItemArgs),
    /// Move a work item between cycles or modules atomically
    Mv(super::mv::MoveWorkItemArgs),
    /// Batch-update fields (state, priority, due, assignee, label) on multiple work items
    Bulk(super::bulk::BulkStateTransitionArgs),
    /// Open a work item in the default web browser
    Open(super::open::OpenInBrowserArgs),
    /// List cycles with progress bars showing item completion rates
    Cycles(super::cycles::CycleCommand),
    /// List modules with item counts and status breakdowns
    Modules(super::modules_cmd::ModuleCommandArgs),
    /// Terminal dashboard with items by state, overdue counts, and AC completion rates
    Dashboard(super::dashboard::DashboardOverviewArgs),
    /// List items assigned to the current user across all configured workspaces
    Mine(super::mine::MyWorkItemsArgs),
    /// View, check off, or append acceptance criteria on a work item
    Ac(super::ac::AcceptanceCriteriaArgs),
    /// Create a feature branch from a work item and transition to In Progress
    Start(super::start::StartWorkItemArgs),
    /// List all projects in the active workspace with their identifier slugs
    Projects(super::projects::ListProjectsArgs),
    /// Open a GitHub pull request with title and body prefilled from a work item
    Pr(super::pull_request::OpenPullRequestArgs),
    /// Print current workspace, project, and authentication status
    Me(super::me::SessionStatusArgs),
    /// Print the work item ID inferred from the current git branch (for scripting)
    Id(super::work_item_id::PrintWorkItemIdArgs),
    /// Print the Plane web URL for the work item inferred from the current git branch
    Url(super::work_item_url::PrintWorkItemUrlArgs),
    /// Parse a Plane web URL and print a summary of the referenced entity
    Info(super::url_inspect::InspectUrlArgs),
    /// List, add, or remove relations between work items (blocked-by, relates-to, etc.)
    Relation(super::relation::RelationCommandArgs),
    /// Live-tail a work item, polling for state changes until interrupted
    Watch(super::watch::WatchWorkItemArgs),
    /// Show current user, workspace, and project configuration
    Whoami(super::whoami::WhoamiArgs),
    /// Manage project labels (list, create, delete)
    Labels(super::labels::LabelCommandArgs),
    /// List workflow states and their groups for the active project
    States(super::states::ListStatesArgs),
    /// Post a comment on a work item
    Comment(super::comment::PostCommentArgs),
    /// Set API key, register workspaces, and configure default targeting
    Config(super::configure::ConfigureSettingsArgs),
    /// Switch the active workspace that subsequent commands target
    Workspace(super::workspace::SwitchWorkspaceArgs),
}

/// Routes a parsed subcommand to its execution handler.
/// Each handler independently resolves its own configuration needs —
/// session-requiring commands load the active workspace internally,
/// while setup commands (config, workspace) operate on the settings file directly.
pub async fn dispatch(plane_subcommand: PlaneSubcommand) -> Result<()> {
    match plane_subcommand {
        PlaneSubcommand::Ls(list_work_items) => list_work_items.execute().await,
        PlaneSubcommand::Search(search_work_items) => search_work_items.execute().await,
        PlaneSubcommand::Show(show_work_item) => show_work_item.execute().await,
        PlaneSubcommand::Create(create_work_item) => create_work_item.execute().await,
        PlaneSubcommand::Update(update_work_item) => update_work_item.execute().await,
        PlaneSubcommand::Done(complete_work_item) => complete_work_item.execute().await,
        PlaneSubcommand::Delete(delete_work_item) => delete_work_item.execute().await,
        PlaneSubcommand::Mv(move_work_item) => move_work_item.execute().await,
        PlaneSubcommand::Bulk(bulk_transition) => bulk_transition.execute().await,
        PlaneSubcommand::Open(open_in_browser) => open_in_browser.execute().await,
        PlaneSubcommand::Cycles(list_cycles) => list_cycles.execute().await,
        PlaneSubcommand::Modules(list_modules) => list_modules.execute().await,
        PlaneSubcommand::Dashboard(dashboard_overview) => dashboard_overview.execute().await,
        PlaneSubcommand::Mine(my_work_items) => my_work_items.execute().await,
        PlaneSubcommand::Ac(acceptance_criteria) => acceptance_criteria.execute().await,
        PlaneSubcommand::Start(start_work_item) => start_work_item.execute().await,
        PlaneSubcommand::Projects(list_projects) => list_projects.execute().await,
        PlaneSubcommand::Pr(open_pull_request) => open_pull_request.execute().await,
        PlaneSubcommand::Me(session_status) => session_status.execute().await,
        PlaneSubcommand::Id(print_work_item_id) => print_work_item_id.execute().await,
        PlaneSubcommand::Url(print_work_item_url) => print_work_item_url.execute().await,
        PlaneSubcommand::Info(inspect_url) => inspect_url.execute().await,
        PlaneSubcommand::Relation(relation_command) => relation_command.execute().await,
        PlaneSubcommand::Watch(watch_work_item) => watch_work_item.execute().await,
        PlaneSubcommand::Whoami(whoami_args) => whoami_args.execute().await,
        PlaneSubcommand::Labels(label_command) => label_command.execute().await,
        PlaneSubcommand::States(list_states) => list_states.execute().await,
        PlaneSubcommand::Comment(post_comment) => post_comment.execute().await,
        PlaneSubcommand::Config(configure_settings) => configure_settings.execute().await,
        PlaneSubcommand::Workspace(switch_workspace) => switch_workspace.execute().await,
    }
}
