use std::sync::Arc;
use tokio::sync::mpsc;
use tracing::{info, warn, error};
use chrono::{Utc, Duration};

use dd0c_route::{AppConfig, TelemetryEvent};

mod digest;
mod anomaly;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| "dd0c_route=info".into()),
        )
        .json()
        .init();

    let config = Arc::new(AppConfig::from_env()?);
    info!("Starting dd0c/route worker");

    let ts_pool = sqlx::PgPool::connect(&config.timescale_url).await?;
    let pg_pool = sqlx::PgPool::connect(&config.database_url).await?;

    // Spawn periodic tasks
    let ts1 = ts_pool.clone();
    let pg1 = pg_pool.clone();
    let config1 = config.clone();

    // Hourly: check for cost anomalies
    tokio::spawn(async move {
        let mut interval = tokio::time::interval(std::time::Duration::from_secs(3600));
        loop {
            interval.tick().await;
            if let Err(e) = anomaly::check_anomalies(&ts1, &pg1).await {
                error!(error = %e, "Anomaly check failed");
            }
        }
    });

    // Weekly: generate cost digest emails
    let ts2 = ts_pool.clone();
    let pg2 = pg_pool.clone();
    tokio::spawn(async move {
        // Run every Monday at 9 AM UTC
        loop {
            let now = Utc::now();
            let next_monday = digest::next_monday_9am(now);
            let sleep_duration = (next_monday - now).to_std().unwrap_or(std::time::Duration::from_secs(3600));
            tokio::time::sleep(sleep_duration).await;

            info!("Generating weekly digests");
            if let Err(e) = digest::generate_all_digests(&ts2, &pg2).await {
                error!(error = %e, "Digest generation failed");
            }
        }
    });

    // Cost table refresh: daily at midnight UTC
    let pg3 = pg_pool.clone();
    tokio::spawn(async move {
        let mut interval = tokio::time::interval(std::time::Duration::from_secs(86400));
        loop {
            interval.tick().await;
            info!("Refreshing cost tables");
            // TODO: Fetch latest pricing from provider APIs
        }
    });

    info!("Worker running — anomaly checks hourly, digests weekly");

    // Keep the main task alive
    tokio::signal::ctrl_c().await?;
    info!("Worker shutting down");
    Ok(())
}
