use std::sync::Arc;

use anyhow::Result;

use crate::scrape::athena::DexterAthena;

use super::config::TaxHarvestConfig;
use super::db::{TaxDatabaseInserter, TaxInsertStats};
use super::fetch::fetch_tax_source_entries;
use super::mapping::normalize_tax_entries;

#[derive(Debug, Clone, Default)]
pub struct TaxHarvestSummary {
    pub source_entries: usize,
    pub normalized_tax_types: usize,
    pub normalized_tax_rates: usize,
    pub normalized_tax_due_dates: usize,
    pub insert_stats: Option<TaxInsertStats>,
}

pub async fn run_tax_harvest(
    http: &reqwest::Client,
    dexter: Option<Arc<DexterAthena>>,
    cfg: &TaxHarvestConfig,
) -> Result<TaxHarvestSummary> {
    let entries = fetch_tax_source_entries(http, cfg).await?;
    let batch = normalize_tax_entries(entries.clone(), &cfg.country_code, cfg.tax_year)?;

    let mut summary = TaxHarvestSummary {
        source_entries: entries.len(),
        normalized_tax_types: batch.tax_types.len(),
        normalized_tax_rates: batch.tax_rates.len(),
        normalized_tax_due_dates: batch.tax_due_dates.len(),
        insert_stats: None,
    };

    tracing::info!(
        "Tax normalization: {} entries -> {} tax_types, {} tax_rates, {} tax_due_dates",
        summary.source_entries,
        summary.normalized_tax_types,
        summary.normalized_tax_rates,
        summary.normalized_tax_due_dates
    );

    if !cfg.insert {
        return Ok(summary);
    }

    let dexter = dexter.ok_or_else(|| {
        anyhow::anyhow!("insert mode requires a configured Athena gateway client")
    })?;
    if batch.is_empty() {
        tracing::warn!("No normalized tax rows to insert.");
        return Ok(summary);
    }

    let inserter = TaxDatabaseInserter::new(dexter, cfg.max_workers);
    let insert_stats = inserter.insert_batch(batch).await;
    summary.insert_stats = Some(insert_stats);
    Ok(summary)
}
