use crate::core::config::OUTPUT_DIR;
use anyhow::{Context, Result};
use serde::Deserialize;
use sqlx::PgPool;
use std::fs;
use std::path::Path;

// --- 結構體定義 (對齊外部處理器產出格式) ---

#[derive(Debug, Deserialize)]
struct AsrSegment {
    start: f64,
    end: f64,
    text: String,
}

#[derive(Debug, Deserialize)]
struct AsrxSegment {
    start: f64,
    end: f64,
    speaker: String,
}

// --- 核心邏輯 ---

/// 執行 Rule 1 入庫
/// 讀取 asr.json 與 asrx.json，合併 Speaker 資訊，寫入 chunks_rule1
pub async fn ingest_rule1(pool: &PgPool, asset_uuid: &str, fps: f64) -> Result<usize> {
    // 1. 讀取檔案
    let asr_path = format!("{}/{}.asr.json", *OUTPUT_DIR, asset_uuid);
    let asrx_path = format!("{}/{}.asrx.json", *OUTPUT_DIR, asset_uuid);

    let asr_content = fs::read_to_string(&asr_path)
        .with_context(|| format!("Failed to read ASR file: {}", asr_path))?;
    let asrx_content = fs::read_to_string(&asrx_path)
        .with_context(|| format!("Failed to read ASRX file: {}", asrx_path))?;

    let asr_segments: Vec<AsrSegment> = serde_json::from_str(&asr_content)?;
    let asrx_segments: Vec<AsrxSegment> = serde_json::from_str(&asrx_content)?;

    let mut count = 0;

    // 2. 交易處理
    let mut tx = pool.begin().await?;

    for seg in &asr_segments {
        // 時間轉幀
        let start_frame = (seg.start * fps).round() as i64;
        let end_frame = (seg.end * fps).round() as i64;

        // 3. 尋找重疊最多的 Speaker
        let mut best_speaker: Option<String> = None;
        let mut max_overlap = 0.0f64;

        for spk in &asrx_segments {
            let overlap = (seg.end.min(spk.end) - seg.start.max(spk.start)).max(0.0);
            if overlap > max_overlap {
                max_overlap = overlap;
                best_speaker = Some(spk.speaker.clone());
            }
        }

        let speaker_id = best_speaker.unwrap_or("UNKNOWN".to_string());

        // 4. 寫入 DB
        sqlx::query!(
            r#"
            INSERT INTO chunks_rule1 (
                id, asset_uuid, start_frame, end_frame, content, speaker_id
            ) VALUES (
                gen_random_uuid(), $1, $2, $3, $4, $5
            )
            "#,
            asset_uuid,
            start_frame,
            end_frame,
            seg.text,
            speaker_id
        )
        .execute(&mut *tx)
        .await?;

        count += 1;

        // 每 100 筆 Commit 一次 (可選優化)
        if count % 500 == 0 {
            tx.commit().await?;
            tx = pool.begin().await?;
        }
    }

    tx.commit().await?;
    Ok(count)
}
