// src/corporate/types.rs
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CompanyEvent {
    pub ticker: String,
    pub date: String,                    // YYYY-MM-DD
    pub time: String,                    // "AMC", "BMO", "TAS", or ""
    pub period: String,                  // "Q1 2025", "FY 2024"
    pub eps_forecast: Option<f64>,
    pub eps_actual: Option<f64>,
    pub revenue_forecast: Option<f64>,
    pub revenue_actual: Option<f64>,
    pub surprise_pct: Option<f64>,       // (actual - forecast) / |forecast|
    pub source: String,                  // "Yahoo"
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompanyPrice {
    pub ticker: String,
    pub date: String,                    // YYYY-MM-DD
    pub time: String,                    // HH:MM:SS for intraday, "" for daily
    pub open: f64,
    pub high: f64,
    pub low: f64,
    pub close: f64,
    pub adj_close: f64,
    pub volume: u64,
    pub currency: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompanyEventChange {
    pub ticker: String,
    pub date: String,
    pub field_changed: String,           // "time", "eps_forecast", "eps_actual", "new_event"
    pub old_value: String,
    pub new_value: String,
    pub detected_at: String,
}

/// Figi Info based on API calls [https://www.openfigi.com/]
/// # Attributes
/// isin: ISIN belonging to this legal entity from lei
/// 
/// # Comments
/// Use Mapping the Object List onto Figi Properties
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FigiInfo {
    pub isin: String,
    pub figi: String,
    pub name: String,
    pub ticker: String,
    pub mic_code: String,
    pub currency: String,
    pub compositeFIGI: String,
    pub securityType: String,
    pub marketSector: String,
    pub shareClassFIGI: String,
    pub securityType2: String,
    pub securityDescription: String,
}

/// Company Meta Data
/// # Attributes
/// * lei: Structuring the companies by legal dependencies [LEI -> Vec<ISIN>]
/// * figi: metadata with ISIN as key
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompanyMetadata {
    pub lei: String,
    pub figi: Option<Vec<FigiInfo>>,
}

/// Company Info
/// # Attributes
/// * Name as primary key (for one instition) -> might have to changed when first FigiInfo is coming in
/// * ISIN as the most liquid / preferred traded security (used for fallback)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompanyInfo{
    pub name: String,
    pub primary_isin: String,
    pub securities: Vec<FigiInfo>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PrimaryInfo {
    pub isin: String,
    pub name: String,
    pub exchange_mic: String,
    pub currency: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AvailableExchange {
    pub exchange_mic: String,
    pub ticker: String,
    pub has_daily: bool,
    pub has_5min: bool,
    pub last_successful_fetch: Option<String>, // YYYY-MM-DD
    #[serde(default)]
    pub currency: String,
    #[serde(default)]
    pub discovered_at: Option<String>,   // When this exchange was first discovered
    #[serde(default)]
    pub fetch_count: u32,                // How many times successfully fetched
}

impl AvailableExchange {
    pub fn new(ticker: String, exchange_mic: String, currency: String) -> Self {
        Self {
            exchange_mic,
            ticker,
            has_daily: false,
            has_5min: false,
            last_successful_fetch: None,
            currency,
            discovered_at: Some(chrono::Local::now().format("%Y-%m-%d").to_string()),
            fetch_count: 0,
        }
    }
    
    pub fn record_success(&mut self, has_daily: bool, has_5min: bool) {
        let today = chrono::Local::now().format("%Y-%m-%d").to_string();
        
        self.has_daily |= has_daily;
        self.has_5min |= has_5min;
        self.last_successful_fetch = Some(today);
        self.fetch_count += 1;
    }
}