use secrecy::{SecretString, ExposeSecret};
use serde::Deserialize;

use crate::error::Result;

const DEFAULT_BASE_URL: &str = "https://www.alphavantage.co";

#[derive(Clone)]
pub struct AlphaVantageHttpClient {
    client: reqwest::Client,
    base_url: String,
    api_key: SecretString,
}

impl AlphaVantageHttpClient {
    pub fn new(api_key: SecretString) -> Self {
        Self {
            client: reqwest::Client::new(),
            base_url: DEFAULT_BASE_URL.to_string(),
            api_key,
        }
    }

    pub async fn fetch_overview(&self, symbol: &str) -> Result<AvOverview> {
        let url = format!("{}/query", self.base_url);
        let resp = self
            .client
            .get(&url)
            .query(&[
                ("function", "OVERVIEW"),
                ("symbol", symbol),
                ("apikey", self.api_key.expose_secret()),
            ])
            .send()
            .await?
            .error_for_status()?
            .json::<AvOverview>()
            .await?;
        Ok(resp)
    }

    pub async fn fetch_global_quote(&self, symbol: &str) -> Result<AvGlobalQuoteEnvelope> {
        let url = format!("{}/query", self.base_url);
        let resp = self
            .client
            .get(&url)
            .query(&[
                ("function", "GLOBAL_QUOTE"),
                ("symbol", symbol),
                ("apikey", self.api_key.expose_secret()),
            ])
            .send()
            .await?
            .error_for_status()?
            .json::<AvGlobalQuoteEnvelope>()
            .await?;
        Ok(resp)
    }
}

// --- Alpha Vantage Models (subset, strong-typed) ---

#[derive(Debug, Deserialize)]
pub struct AvOverview {
    #[serde(rename = "Symbol")]
    pub symbol: String,
    #[serde(rename = "Name")]
    pub name: String,
    #[serde(rename = "Industry")]
    pub industry: String,
    #[serde(rename = "Exchange")]
    pub exchange: String,
    #[serde(rename = "Currency")]
    pub currency: String,
    #[serde(rename = "Country")]
    pub country: String,
    #[serde(rename = "Sector")]
    pub sector: String,
    #[serde(rename = "MarketCapitalization")]
    pub market_capitalization: Option<String>,
    #[serde(rename = "PERatio")]
    pub pe_ratio: Option<String>,
    #[serde(rename = "Beta")]
    pub beta: Option<String>,
    #[serde(rename = "Description")]
    pub description: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct AvGlobalQuoteEnvelope {
    #[serde(rename = "Global Quote")]
    pub global_quote: AvGlobalQuote,
}

#[derive(Debug, Deserialize)]
pub struct AvGlobalQuote {
    #[serde(rename = "01. symbol")]
    pub symbol: String,
    #[serde(rename = "02. open")]
    pub open: Option<String>,
    #[serde(rename = "03. high")]
    pub high: Option<String>,
    #[serde(rename = "04. low")]
    pub low: Option<String>,
    #[serde(rename = "05. price")]
    pub price: Option<String>,
    #[serde(rename = "06. volume")]
    pub volume: Option<String>,
    #[serde(rename = "07. latest trading day")]
    pub latest_trading_day: Option<String>,
    #[serde(rename = "08. previous close")]
    pub previous_close: Option<String>,
    #[serde(rename = "09. change")]
    pub change: Option<String>,
    #[serde(rename = "10. change percent")]
    pub change_percent: Option<String>,
}


