// src/corporate/helpers.rs
use super::types::*;
use chrono::{Local, NaiveDate};
use std::collections::{HashMap, HashSet};

pub fn event_key(e: &CompanyEvent) -> String {
    format!("{}|{}|{}", e.ticker, e.date, e.time)
}

pub fn detect_changes(old: &CompanyEvent, new: &CompanyEvent, today: &str) -> Vec<CompanyEventChange> {
    let mut changes = Vec::new();
    let ts = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

    if new.date.as_str() <= today { return changes; }

    if old.time != new.time {
        changes.push(CompanyEventChange {
            ticker: new.ticker.clone(),
            date: new.date.clone(),
            field_changed: "time".to_string(),
            old_value: old.time.clone(),
            new_value: new.time.clone(),
            detected_at: ts.clone(),
        });
    }

    if old.eps_forecast != new.eps_forecast {
        changes.push(CompanyEventChange {
            ticker: new.ticker.clone(),
            date: new.date.clone(),
            field_changed: "eps_forecast".to_string(),
            old_value: format!("{:?}", old.eps_forecast),
            new_value: format!("{:?}", new.eps_forecast),
            detected_at: ts.clone(),
        });
    }

    if old.eps_actual != new.eps_actual {
        changes.push(CompanyEventChange {
            ticker: new.ticker.clone(),
            date: new.date.clone(),
            field_changed: "eps_actual".to_string(),
            old_value: format!("{:?}", old.eps_actual),
            new_value: format!("{:?}", new.eps_actual),
            detected_at: ts.clone(),
        });
    }

    // Add similar for revenue if applicable

    changes
}

pub fn price_key(p: &CompanyPrice) -> String {
    if p.time.is_empty() {
        format!("{}|{}", p.ticker, p.date)
    } else {
        format!("{}|{}|{}", p.ticker, p.date, p.time)
    }
}

pub fn parse_float(s: &str) -> Option<f64> {
    s.replace("--", "").replace(",", "").parse::<f64>().ok()
}

pub fn parse_yahoo_date(s: &str) -> anyhow::Result<NaiveDate> {
    NaiveDate::parse_from_str(s, "%B %d, %Y")
        .or_else(|_| NaiveDate::parse_from_str(s, "%b %d, %Y"))
        .map_err(|_| anyhow::anyhow!("Bad date: {s}"))
}