//! CLI argument definitions for cg-ohlc

use crate::error::{CgOhlcError, Result};
use cg_common::resolve_symbol;
use clap::{Parser, ValueEnum};
use std::path::PathBuf;

#[derive(Parser, Debug)]
#[command(name = "cg-ohlc")]
#[command(author, version, about = "Fetch OHLCV candlestick data from CoinGecko", long_about = None)]
pub struct Args {
    /// Coin ID (e.g., "bitcoin") or symbol (e.g., "BTC")
    #[arg(value_name = "COIN")]
    pub coin: Option<String>,

    /// Symbol to resolve (e.g., "BTC", "ETH")
    #[arg(short, long)]
    pub symbol: Option<String>,

    /// Number of days (1, 7, 14, 30, 90, 180, 365, or "max")
    #[arg(short, long, default_value = "30")]
    pub days: String,

    /// Quote currency (usd, eur, btc, eth, etc.)
    #[arg(long, default_value = "usd")]
    pub vs_currency: String,

    /// Output format
    #[arg(short, long, value_enum, default_value = "json")]
    pub format: OutputFormat,

    /// Output file path (outputs to stdout if not specified)
    #[arg(short = 'O', long = "output-file")]
    pub output: Option<PathBuf>,

    /// Enable verbose logging
    #[arg(short, long)]
    pub verbose: bool,
}

#[derive(Debug, Clone, Copy, ValueEnum, PartialEq)]
pub enum OutputFormat {
    /// JSON output format (pretty)
    #[value(name = "json")]
    Json,
    /// Compact JSON (no pretty print)
    #[value(name = "compact")]
    Compact,
}

impl Args {
    /// Resolve the coin identifier from args
    pub fn resolve_coin_id(&self) -> Result<String> {
        let input = self.symbol.as_ref().or(self.coin.as_ref()).ok_or_else(|| {
            CgOhlcError::InvalidInput(
                "No coin specified. Use a positional argument or --symbol flag.".to_string(),
            )
        })?;

        Ok(resolve_symbol(input))
    }

    /// Validate CLI arguments
    pub fn validate(&self) -> Result<()> {
        // Need either coin or symbol
        if self.coin.is_none() && self.symbol.is_none() {
            return Err(CgOhlcError::InvalidInput(
                "No coin specified. Use a positional argument or --symbol.".to_string(),
            ));
        }

        Ok(())
    }
}
