use crate::config::get_config;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct IdentitySearchRequest {
    pub query: Option<String>,
    pub file_uuid: Option<String>,
    pub limit: Option<usize>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct IdentityResponse {
    pub success: bool,
    pub total: usize,
    pub identities: Vec<IdentityItem>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct IdentityItem {
    pub id: i32,
    pub person_id: String,
    pub face_identity_id: Option<i32>,
    pub file_uuid: String,
    pub profile: IdentityProfile,
    pub stats: IdentityStats,
    pub is_confirmed: bool,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct IdentityProfile {
    pub name: Option<String>,
    pub original_name: Option<String>,
    pub character_name: Option<String>,
    pub speaker_id: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct IdentityStats {
    pub appearance_count: i32,
    pub total_duration: f64,
    pub first_appearance: Option<f64>,
    pub last_appearance: Option<f64>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RegisterResponse {
    pub success: bool,
    pub message: String,
    pub person_id: String,
    pub name: String,
    pub face_identity_id: i32,
}

#[tauri::command]
pub async fn list_identities(
    query: Option<String>,
    file_uuid: Option<String>,
) -> Result<IdentityResponse, String> {
    let config = get_config();
    let client = reqwest::Client::new();

    let request_body = IdentitySearchRequest {
        query,
        file_uuid,
        limit: Some(50),
    };

    let response = client
        .post(&format!("{}/api/v1/identities/search", config.api_base_url))
        .header("Content-Type", "application/json")
        .header("x-api-key", &config.api_key)
        .json(&request_body)
        .send()
        .await
        .map_err(|e| format!("Request failed: {}", e))?;

    if !response.status().is_success() {
        return Err(format!("API error: {}", response.status()));
    }

    let result: IdentityResponse = response
        .json()
        .await
        .map_err(|e| format!("Failed to parse response: {}", e))?;

    Ok(result)
}

#[tauri::command]
pub async fn register_identity(
    person_id: String,
    file_uuid: String,
) -> Result<RegisterResponse, String> {
    let config = get_config();
    let client = reqwest::Client::new();

    let url = format!(
        "{}/api/v1/person/{}/register?file_uuid={}",
        config.api_base_url, person_id, file_uuid
    );

    let response = client
        .post(&url)
        .header("x-api-key", &config.api_key)
        .send()
        .await
        .map_err(|e| format!("Request failed: {}", e))?;

    if !response.status().is_success() {
        return Err(format!("API error: {}", response.status()));
    }

    let result: RegisterResponse = response
        .json()
        .await
        .map_err(|e| format!("Failed to parse response: {}", e))?;

    Ok(result)
}

#[tauri::command]
pub async fn get_identity_videos(identity_id: i32) -> Result<serde_json::Value, String> {
    let config = get_config();
    let client = reqwest::Client::new();

    let url = format!(
        "{}/api/v1/identities/{}/videos",
        config.api_base_url, identity_id
    );

    let response = client
        .get(&url)
        .header("x-api-key", &config.api_key)
        .send()
        .await
        .map_err(|e| format!("Request failed: {}", e))?;

    if !response.status().is_success() {
        return Err(format!("API error: {}", response.status()));
    }

    let result: serde_json::Value = response
        .json()
        .await
        .map_err(|e| format!("Failed to parse response: {}", e))?;

    Ok(result)
}
