use std::collections::HashMap;
use std::path::Path;
use tokio::sync::Mutex;
use tauri::State;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use chrono;
use veo3_scene_writer::{Veo3ActorDefine, Veo3SceneWriter};
use crate::infrastructure::tolerant_json_parser::TolerantJsonParser;

/// VEO3 角色定义响应结构
#[derive(Debug, Serialize, Deserialize)]
pub struct Veo3ActorDefineResponse {
    pub success: bool,
    pub content: String,
    pub error: Option<String>,
    pub conversation_history: Option<Vec<String>>,
}

/// VEO3 角色定义会话管理器
pub type Veo3ActorDefineSessionManager = Mutex<HashMap<String, Veo3ActorDefine>>;

/// VEO3 场景写作会话管理器
pub type Veo3SceneWriterSessionManager = Mutex<HashMap<String, Veo3SceneWriter>>;

/// 检查 VEO3 角色定义服务可用性
#[tauri::command]
pub async fn veo3_actor_define_check_availability() -> Result<(), String> {
    // 尝试创建一个实例来检查服务是否可用
    match Veo3ActorDefine::new().await {
        Ok(_) => Ok(()),
        Err(e) => Err(format!("VEO3 角色定义服务不可用: {}", e)),
    }
}

/// 发送消息到 VEO3 角色定义工具
#[tauri::command]
pub async fn veo3_actor_define_send_message(
    session_id: String,
    message: String,
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<Veo3ActorDefineResponse, String> {
    // 检查会话是否存在，如果不存在则创建
    let session_exists = {
        let sessions = session_manager.lock().await;
        sessions.contains_key(&session_id)
    };

    if !session_exists {
        let new_actor_define = Veo3ActorDefine::new()
            .await
            .map_err(|e| format!("创建 VEO3 角色定义实例失败: {}", e))?;

        let mut sessions = session_manager.lock().await;
        sessions.insert(session_id.clone(), new_actor_define);
    }

    // 发送消息
    let (response_result, conversation_history) = {
        let mut sessions = session_manager.lock().await;
        let actor_define = sessions.get_mut(&session_id).unwrap();

        let response = actor_define.send_message(&message).await;
        let history = actor_define.get_conversation_history().clone();
        (response, history)
    };

    match response_result {
        Ok(response) => Ok(Veo3ActorDefineResponse {
            success: true,
            content: response,
            error: None,
            conversation_history: Some(conversation_history),
        }),
        Err(e) => Ok(Veo3ActorDefineResponse {
            success: false,
            content: String::new(),
            error: Some(format!("发送消息失败: {}", e)),
            conversation_history: None,
        }),
    }
}

/// 发送带附件的消息到 VEO3 角色定义工具
#[tauri::command]
pub async fn veo3_actor_define_send_message_with_attachments(
    session_id: String,
    message: String,
    attachment_paths: Vec<String>,
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<Veo3ActorDefineResponse, String> {
    // 检查会话是否存在，如果不存在则创建
    let session_exists = {
        let sessions = session_manager.lock().await;
        sessions.contains_key(&session_id)
    };

    if !session_exists {
        let new_actor_define = Veo3ActorDefine::new()
            .await
            .map_err(|e| format!("创建 VEO3 角色定义实例失败: {}", e))?;

        let mut sessions = session_manager.lock().await;
        sessions.insert(session_id.clone(), new_actor_define);
    }

    // 转换路径为字符串引用
    let attachment_refs: Vec<&str> = attachment_paths.iter().map(|s| s.as_str()).collect();

    // 发送带附件的消息
    let (response_result, conversation_history) = {
        let mut sessions = session_manager.lock().await;
        let actor_define = sessions.get_mut(&session_id).unwrap();

        let response = actor_define.send_message_with_attachments(&message, attachment_refs).await;
        let history = actor_define.get_conversation_history().clone();
        (response, history)
    };

    match response_result {
        Ok(response) => Ok(Veo3ActorDefineResponse {
            success: true,
            content: response,
            error: None,
            conversation_history: Some(conversation_history),
        }),
        Err(e) => Ok(Veo3ActorDefineResponse {
            success: false,
            content: String::new(),
            error: Some(format!("发送带附件消息失败: {}", e)),
            conversation_history: None,
        }),
    }
}

/// 获取 VEO3 角色定义会话历史记录
#[tauri::command]
pub async fn veo3_actor_define_get_conversation_history(
    session_id: String,
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<Vec<String>, String> {
    let sessions = session_manager.lock().await;
    
    if let Some(actor_define) = sessions.get(&session_id) {
        Ok(actor_define.get_conversation_history().clone())
    } else {
        Ok(Vec::new())
    }
}

/// 清除 VEO3 角色定义会话历史记录
#[tauri::command]
pub async fn veo3_actor_define_clear_conversation(
    session_id: String,
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<(), String> {
    let mut sessions = session_manager.lock().await;
    
    if let Some(actor_define) = sessions.get_mut(&session_id) {
        actor_define.clear_conversation();
    }
    
    Ok(())
}

/// 删除 VEO3 角色定义会话
#[tauri::command]
pub async fn veo3_actor_define_remove_session(
    session_id: String,
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<(), String> {
    let mut sessions = session_manager.lock().await;
    sessions.remove(&session_id);
    Ok(())
}

/// 获取所有活跃的 VEO3 角色定义会话ID
#[tauri::command]
pub async fn veo3_actor_define_get_active_sessions(
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<Vec<String>, String> {
    let sessions = session_manager.lock().await;
    Ok(sessions.keys().cloned().collect())
}

/// 创建角色文件请求结构
#[derive(Debug, Deserialize)]
pub struct CreateActorFileRequest {
    pub session_id: String,
    pub file_path: String,
    pub file_name: Option<String>,
}

/// 创建角色文件响应结构
#[derive(Debug, Serialize)]
pub struct CreateActorFileResponse {
    pub success: bool,
    pub file_path: Option<String>,
    pub extracted_json: Option<Value>,
    pub error: Option<String>,
}

/// 创建角色文件 - 从最近一次对话中提取JSON并保存
#[tauri::command]
pub async fn veo3_actor_define_create_actor_file(
    request: CreateActorFileRequest,
    session_manager: State<'_, Veo3ActorDefineSessionManager>,
) -> Result<CreateActorFileResponse, String> {
    // 获取最近一次助手回复
    let last_assistant_message = {
        let sessions = session_manager.lock().await;
        if let Some(actor_define) = sessions.get(&request.session_id) {
            let history = actor_define.get_conversation_history();

            // 查找最后一条助手消息
            history.iter()
                .rev()
                .find(|msg| msg.starts_with("助手: "))
                .map(|msg| msg.strip_prefix("助手: ").unwrap_or(msg).to_string())
        } else {
            None
        }
    };

    let assistant_message = match last_assistant_message {
        Some(msg) => msg,
        None => {
            return Ok(CreateActorFileResponse {
                success: false,
                file_path: None,
                extracted_json: None,
                error: Some("未找到助手回复消息".to_string()),
            });
        }
    };

    // 使用容错JSON解析器提取JSON
    let mut parser = match TolerantJsonParser::new(None) {
        Ok(p) => p,
        Err(e) => {
            return Ok(CreateActorFileResponse {
                success: false,
                file_path: None,
                extracted_json: None,
                error: Some(format!("创建JSON解析器失败: {}", e)),
            });
        }
    };

    let json_data = match parser.parse(&assistant_message) {
        Ok((data, _statistics)) => data,
        Err(e) => {
            return Ok(CreateActorFileResponse {
                success: false,
                file_path: None,
                extracted_json: None,
                error: Some(format!("JSON解析失败: {}", e)),
            });
        }
    };

    // 生成文件名
    let file_name = request.file_name.unwrap_or_else(|| {
        let timestamp = chrono::Utc::now().format("%Y%m%d_%H%M%S");
        format!("veo3_actor_{}.json", timestamp)
    });

    // 确保文件路径存在
    let full_path = Path::new(&request.file_path).join(&file_name);

    if let Some(parent_dir) = full_path.parent() {
        if let Err(e) = std::fs::create_dir_all(parent_dir) {
            return Ok(CreateActorFileResponse {
                success: false,
                file_path: None,
                extracted_json: Some(json_data),
                error: Some(format!("创建目录失败: {}", e)),
            });
        }
    }

    // 保存JSON文件
    let json_string = match serde_json::to_string_pretty(&json_data) {
        Ok(s) => s,
        Err(e) => {
            return Ok(CreateActorFileResponse {
                success: false,
                file_path: None,
                extracted_json: Some(json_data),
                error: Some(format!("JSON序列化失败: {}", e)),
            });
        }
    };

    match std::fs::write(&full_path, json_string) {
        Ok(_) => Ok(CreateActorFileResponse {
            success: true,
            file_path: Some(full_path.to_string_lossy().to_string()),
            extracted_json: Some(json_data),
            error: None,
        }),
        Err(e) => Ok(CreateActorFileResponse {
            success: false,
            file_path: None,
            extracted_json: Some(json_data),
            error: Some(format!("文件保存失败: {}", e)),
        }),
    }
}

// ==================== VEO3 场景写作命令 ====================

/// 检查 VEO3 场景写作服务可用性
#[tauri::command]
pub async fn veo3_scene_writer_check_availability() -> Result<(), String> {
    // 尝试创建一个实例来检查服务是否可用
    match Veo3SceneWriter::new().await {
        Ok(_) => Ok(()),
        Err(e) => Err(format!("VEO3 场景写作服务不可用: {}", e)),
    }
}

/// 发送消息到 VEO3 场景写作工具
#[tauri::command]
pub async fn veo3_scene_writer_send_message(
    session_id: String,
    message: String,
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<Veo3ActorDefineResponse, String> {
    // 检查会话是否存在，如果不存在则创建
    let session_exists = {
        let sessions = session_manager.lock().await;
        sessions.contains_key(&session_id)
    };

    if !session_exists {
        let new_scene_writer = Veo3SceneWriter::new()
            .await
            .map_err(|e| format!("创建 VEO3 场景写作实例失败: {}", e))?;

        let mut sessions = session_manager.lock().await;
        sessions.insert(session_id.clone(), new_scene_writer);
    }

    // 发送消息
    let (response_result, conversation_history) = {
        let mut sessions = session_manager.lock().await;
        let scene_writer = sessions.get_mut(&session_id).unwrap();

        let response = scene_writer.send_message(&message).await;
        let history = scene_writer.get_conversation_history().clone();
        (response, history)
    };

    match response_result {
        Ok(response) => Ok(Veo3ActorDefineResponse {
            success: true,
            content: response,
            error: None,
            conversation_history: Some(conversation_history),
        }),
        Err(e) => Ok(Veo3ActorDefineResponse {
            success: false,
            content: String::new(),
            error: Some(format!("发送消息失败: {}", e)),
            conversation_history: None,
        }),
    }
}

/// 发送带附件的消息到 VEO3 场景写作工具
#[tauri::command]
pub async fn veo3_scene_writer_send_message_with_attachments(
    session_id: String,
    message: String,
    attachment_paths: Vec<String>,
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<Veo3ActorDefineResponse, String> {
    // 检查会话是否存在，如果不存在则创建
    let session_exists = {
        let sessions = session_manager.lock().await;
        sessions.contains_key(&session_id)
    };

    if !session_exists {
        let new_scene_writer = Veo3SceneWriter::new()
            .await
            .map_err(|e| format!("创建 VEO3 场景写作实例失败: {}", e))?;

        let mut sessions = session_manager.lock().await;
        sessions.insert(session_id.clone(), new_scene_writer);
    }

    // 转换路径为字符串引用
    let attachment_refs: Vec<&str> = attachment_paths.iter().map(|s| s.as_str()).collect();

    // 发送带附件的消息
    let (response_result, conversation_history) = {
        let mut sessions = session_manager.lock().await;
        let scene_writer = sessions.get_mut(&session_id).unwrap();

        let response = scene_writer.send_message_with_attachments(&message, attachment_refs).await;
        let history = scene_writer.get_conversation_history().clone();
        (response, history)
    };

    match response_result {
        Ok(response) => Ok(Veo3ActorDefineResponse {
            success: true,
            content: response,
            error: None,
            conversation_history: Some(conversation_history),
        }),
        Err(e) => Ok(Veo3ActorDefineResponse {
            success: false,
            content: String::new(),
            error: Some(format!("发送带附件消息失败: {}", e)),
            conversation_history: None,
        }),
    }
}

/// 获取 VEO3 场景写作会话历史记录
#[tauri::command]
pub async fn veo3_scene_writer_get_conversation_history(
    session_id: String,
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<Vec<String>, String> {
    let sessions = session_manager.lock().await;

    if let Some(scene_writer) = sessions.get(&session_id) {
        Ok(scene_writer.get_conversation_history().clone())
    } else {
        Ok(Vec::new())
    }
}

/// 清除 VEO3 场景写作会话历史记录
#[tauri::command]
pub async fn veo3_scene_writer_clear_conversation(
    session_id: String,
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<(), String> {
    let mut sessions = session_manager.lock().await;

    if let Some(scene_writer) = sessions.get_mut(&session_id) {
        scene_writer.clear_conversation();
    }

    Ok(())
}

/// 删除 VEO3 场景写作会话
#[tauri::command]
pub async fn veo3_scene_writer_remove_session(
    session_id: String,
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<(), String> {
    let mut sessions = session_manager.lock().await;
    sessions.remove(&session_id);
    Ok(())
}

/// 获取所有活跃的 VEO3 场景写作会话ID
#[tauri::command]
pub async fn veo3_scene_writer_get_active_sessions(
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<Vec<String>, String> {
    let sessions = session_manager.lock().await;
    Ok(sessions.keys().cloned().collect())
}

/// 创建场景文件请求结构
#[derive(Debug, Deserialize)]
pub struct CreateSceneFileRequest {
    pub session_id: String,
    pub file_path: String,
    pub file_name: Option<String>,
}

/// 创建场景文件响应结构
#[derive(Debug, Serialize)]
pub struct CreateSceneFileResponse {
    pub success: bool,
    pub file_path: Option<String>,
    pub extracted_json: Option<Value>,
    pub error: Option<String>,
}

/// 创建场景文件 - 从最近一次对话中提取JSON并保存
#[tauri::command]
pub async fn veo3_scene_writer_create_scene_file(
    request: CreateSceneFileRequest,
    session_manager: State<'_, Veo3SceneWriterSessionManager>,
) -> Result<CreateSceneFileResponse, String> {
    // 获取最近一次助手回复
    let last_assistant_message = {
        let sessions = session_manager.lock().await;
        if let Some(scene_writer) = sessions.get(&request.session_id) {
            let history = scene_writer.get_conversation_history();

            // 查找最后一条助手消息
            history.iter()
                .rev()
                .find(|msg| msg.starts_with("助手: "))
                .map(|msg| msg.strip_prefix("助手: ").unwrap_or(msg).to_string())
        } else {
            None
        }
    };

    let assistant_message = match last_assistant_message {
        Some(msg) => msg,
        None => {
            return Ok(CreateSceneFileResponse {
                success: false,
                file_path: None,
                extracted_json: None,
                error: Some("未找到助手回复消息".to_string()),
            });
        }
    };

    // 使用容错JSON解析器提取JSON
    let mut parser = match TolerantJsonParser::new(None) {
        Ok(p) => p,
        Err(e) => {
            return Ok(CreateSceneFileResponse {
                success: false,
                file_path: None,
                extracted_json: None,
                error: Some(format!("创建JSON解析器失败: {}", e)),
            });
        }
    };

    let json_data = match parser.parse(&assistant_message) {
        Ok((data, _statistics)) => data,
        Err(e) => {
            return Ok(CreateSceneFileResponse {
                success: false,
                file_path: None,
                extracted_json: None,
                error: Some(format!("JSON解析失败: {}", e)),
            });
        }
    };

    // 生成文件名
    let file_name = request.file_name.unwrap_or_else(|| {
        let timestamp = chrono::Utc::now().format("%Y%m%d_%H%M%S");
        format!("veo3_scene_{}.json", timestamp)
    });

    // 确保文件路径存在
    let full_path = Path::new(&request.file_path).join(&file_name);

    if let Some(parent_dir) = full_path.parent() {
        if let Err(e) = std::fs::create_dir_all(parent_dir) {
            return Ok(CreateSceneFileResponse {
                success: false,
                file_path: None,
                extracted_json: Some(json_data),
                error: Some(format!("创建目录失败: {}", e)),
            });
        }
    }

    // 保存JSON文件
    let json_string = match serde_json::to_string_pretty(&json_data) {
        Ok(s) => s,
        Err(e) => {
            return Ok(CreateSceneFileResponse {
                success: false,
                file_path: None,
                extracted_json: Some(json_data),
                error: Some(format!("JSON序列化失败: {}", e)),
            });
        }
    };

    match std::fs::write(&full_path, json_string) {
        Ok(_) => Ok(CreateSceneFileResponse {
            success: true,
            file_path: Some(full_path.to_string_lossy().to_string()),
            extracted_json: Some(json_data),
            error: None,
        }),
        Err(e) => Ok(CreateSceneFileResponse {
            success: false,
            file_path: None,
            extracted_json: Some(json_data),
            error: Some(format!("文件保存失败: {}", e)),
        }),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::Arc;

    #[tokio::test]
    async fn test_veo3_actor_define_check_availability() {
        // 注意：这个测试需要有效的 API 配置才能通过
        if std::env::var("GEMINI_BEARER_TOKEN").is_ok() {
            let result = veo3_actor_define_check_availability().await;
            assert!(result.is_ok());
        }
    }

    #[tokio::test]
    async fn test_veo3_scene_writer_check_availability() {
        // 注意：这个测试需要有效的 API 配置才能通过
        if std::env::var("GEMINI_BEARER_TOKEN").is_ok() {
            let result = veo3_scene_writer_check_availability().await;
            assert!(result.is_ok());
        }
    }

    #[tokio::test]
    async fn test_session_management() {
        let session_manager = Arc::new(Veo3ActorDefineSessionManager::new(HashMap::new()));
        let session_id = "test-session".to_string();

        // 测试获取活跃会话（应该为空）
        let active_sessions = veo3_actor_define_get_active_sessions(
            tauri::State::from(session_manager.clone())
        ).await.unwrap();
        assert!(active_sessions.is_empty());

        // 测试获取不存在会话的历史记录
        let history = veo3_actor_define_get_conversation_history(
            session_id.clone(),
            tauri::State::from(session_manager.clone())
        ).await.unwrap();
        assert!(history.is_empty());

        // 测试清除不存在会话的历史记录
        let result = veo3_actor_define_clear_conversation(
            session_id.clone(),
            tauri::State::from(session_manager.clone())
        ).await;
        assert!(result.is_ok());

        // 测试删除不存在的会话
        let result = veo3_actor_define_remove_session(
            session_id,
            tauri::State::from(session_manager)
        ).await;
        assert!(result.is_ok());
    }
}
