use serde::{Deserialize, Serialize};

/// Period for financial statement queries.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Period {
    Annual,
    Quarterly,
}

impl Period {
    pub fn as_str(&self) -> &'static str {
        match self {
            Period::Annual => "annual",
            Period::Quarterly => "quarterly",
        }
    }
}

/// Financial statement type.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StatementType {
    IncomeStatement,
    BalanceSheet,
    CashFlow,
}

impl StatementType {
    pub fn as_str(&self) -> &'static str {
        match self {
            StatementType::IncomeStatement => "income-statement",
            StatementType::BalanceSheet => "balance-sheet",
            StatementType::CashFlow => "cash-flow-statement",
        }
    }
}

/// A single cell in a financial statement row (one period column).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FinancialCell {
    /// Period label, e.g. "Dec 2025" or "TTM".
    pub period: String,
    /// Raw numeric value (None if locked on free tier or genuinely absent).
    pub raw_value: Option<f64>,
    /// Display-formatted value, e.g. "50.7" (empty string if locked).
    pub value: String,
    /// Year-over-year change string, e.g. "638.14%" or "(26.87%)".
    #[serde(skip_serializing_if = "Option::is_none")]
    pub yoy_value: Option<String>,
    /// True if this cell is paywalled on the free tier ("archive-lock").
    pub locked: bool,
}

/// A single line-item row in a financial statement.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FinancialRow {
    /// Internal field name, e.g. "revenues".
    pub name: String,
    /// Display label, e.g. "Revenues".
    pub label: String,
    /// True for subtotals and section headers.
    pub bold: bool,
    /// Values per period column.
    pub cells: Vec<FinancialCell>,
}

/// A complete parsed financial statement.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FinancialStatement {
    pub ticker: String,
    pub statement_type: String,
    pub period: String,
    pub rows: Vec<FinancialRow>,
}

/// Live quote data for a ticker.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Quote {
    pub ticker: String,
    /// Current/last price (USD).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub price: Option<f64>,
    /// Previous close price.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub close: Option<f64>,
    /// 52-week high.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub high_52w: Option<f64>,
    /// 52-week low.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub low_52w: Option<f64>,
    /// Market capitalization (USD).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub market_cap: Option<f64>,
    /// Trailing P/E ratio (null for loss-making companies).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pe_ratio: Option<f64>,
    /// Diluted EPS (TTM).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub eps: Option<f64>,
    /// Today's return as a fraction (e.g. -0.109 = -10.9%).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub today_return: Option<f64>,
    /// Average daily share volume (1 month).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avg_volume_1m: Option<f64>,
}

/// A news or analysis article from SeekingAlpha.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Article {
    pub id: String,
    pub title: String,
    pub author: String,
    pub published_at: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub summary: Option<String>,
    pub url: String,
    pub premium: bool,
    pub article_type: String,
}

/// Full article content retrieved by ID.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArticleContent {
    pub id: String,
    pub title: String,
    pub author: String,
    pub published_at: String,
    pub content: String,
    pub url: String,
    pub premium: bool,
    pub truncated: bool,
}
