use crate::data::models::project::Project;
use crate::infrastructure::database::Database;
use anyhow::anyhow;
use chrono::{DateTime, Utc};
use rusqlite::{Result, Row};
use std::sync::Arc;

/// 项目数据仓库
/// 遵循 Tauri 开发规范的数据访问层设计
pub struct ProjectRepository {
    database: Arc<Database>,
}

impl ProjectRepository {
    /// 创建新的项目仓库实例
    pub fn new(database: Arc<Database>) -> Result<Self> {
        Ok(ProjectRepository { database })
    }

    /// 创建项目
    pub fn create(&self, project: &Project) -> Result<()> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;
        // 检查路径是否已存在，如果存在则先尝试删除旧记录
        match conn.execute("DELETE FROM projects WHERE path = ?1", [&project.path]) {
            Ok(deleted_rows) => {
                if deleted_rows > 0 {
                    println!(
                        "Removed {} existing project record(s) for path: {}",
                        deleted_rows, project.path
                    );
                }
            }
            Err(e) => {
                println!(
                    "Warning: Failed to clean existing records for path {}: {}",
                    project.path, e
                );
            }
        }

        // 开始事务
        let tx = conn.unchecked_transaction()?;

        let _result = tx.execute(
            "INSERT INTO projects (id, name, path, description, created_at, updated_at, is_active)
             VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
            [
                project.id.as_str(),
                project.name.as_str(),
                project.path.as_str(),
                project.description.as_deref().unwrap_or(""),
                project.created_at.to_rfc3339().as_str(),
                project.updated_at.to_rfc3339().as_str(),
                if project.is_active { "1" } else { "0" },
            ],
        )?;

        // 提交事务
        tx.commit()?;

        Ok(())
    }

    /// 根据ID获取项目
    pub fn find_by_id(&self, id: &str) -> Result<Option<Project>> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;
        let mut stmt = conn.prepare(
            "SELECT id, name, path, description, created_at, updated_at, is_active
             FROM projects WHERE id = ?1",
        )?;

        let result = stmt.query_row([id], |row| Ok(self.row_to_project(row)?));

        match result {
            Ok(project) => Ok(Some(project)),
            Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
            Err(e) => Err(e),
        }
    }

    /// 根据路径获取项目
    pub fn find_by_path(&self, path: &str) -> Result<Option<Project>> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;
        let mut stmt = conn.prepare(
            "SELECT id, name, path, description, created_at, updated_at, is_active
             FROM projects WHERE path = ?1",
        )?;

        let result = stmt.query_row([path], |row| Ok(self.row_to_project(row)?));

        match result {
            Ok(project) => Ok(Some(project)),
            Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
            Err(e) => Err(e),
        }
    }

    /// 获取所有活跃项目
    pub fn find_all_active(&self) -> Result<Vec<Project>> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;

        // 首先检查表是否存在
        let _table_exists: i64 = conn.query_row(
            "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='projects'",
            [],
            |row| row.get(0),
        )?;

        let mut stmt = conn.prepare(
            "SELECT id, name, path, description, created_at, updated_at, is_active
             FROM projects WHERE is_active = 1 ORDER BY updated_at DESC",
        )?;

        let project_iter = stmt.query_map([], |row| Ok(self.row_to_project(row)?))?;

        let mut projects = Vec::new();
        for project in project_iter {
            projects.push(project?);
        }

        Ok(projects)
    }

    /// 更新项目
    pub fn update(&self, project: &Project) -> Result<()> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;
        conn.execute(
            "UPDATE projects SET name = ?1, description = ?2, updated_at = ?3
             WHERE id = ?4",
            [
                project.name.as_str(),
                project.description.as_deref().unwrap_or(""),
                project.updated_at.to_rfc3339().as_str(),
                project.id.as_str(),
            ],
        )?;
        Ok(())
    }

    /// 删除项目（软删除）
    pub fn delete(&self, id: &str) -> Result<()> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;
        conn.execute(
            "UPDATE projects SET is_active = 0, updated_at = ?1 WHERE id = ?2",
            [Utc::now().to_rfc3339().as_str(), id],
        )?;
        Ok(())
    }

    /// 检查路径是否已存在
    pub fn path_exists(&self, path: &str, exclude_id: Option<&str>) -> Result<bool> {
        if !self.database.has_pool() {
            return Err(rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some("连接池未启用，无法安全执行数据库操作".to_string()),
            ));
        }

        let conn = self.database.acquire_from_pool().map_err(|e| {
            rusqlite::Error::SqliteFailure(
                rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_MISUSE),
                Some(format!("获取连接池连接失败: {}", e)),
            )
        })?;
        let count: i64 = if let Some(id) = exclude_id {
            let mut stmt = conn.prepare(
                "SELECT COUNT(*) FROM projects WHERE path = ?1 AND id != ?2 AND is_active = 1",
            )?;
            stmt.query_row([path, id], |row| row.get(0))?
        } else {
            let mut stmt =
                conn.prepare("SELECT COUNT(*) FROM projects WHERE path = ?1 AND is_active = 1")?;
            stmt.query_row([path], |row| row.get(0))?
        };

        Ok(count > 0)
    }

    /// 将数据库行转换为项目对象
    fn row_to_project(&self, row: &Row) -> Result<Project> {
        let created_at_str: String = row.get(4)?;
        let updated_at_str: String = row.get(5)?;

        // 尝试读取 is_active 字段，支持多种数据类型
        let is_active = match row.get::<_, rusqlite::types::Value>(6)? {
            rusqlite::types::Value::Integer(i) => i != 0,
            rusqlite::types::Value::Text(s) => s == "1" || s.to_lowercase() == "true",
            rusqlite::types::Value::Real(f) => f != 0.0,
            _ => true, // 默认为 true
        };

        let created_at = DateTime::parse_from_rfc3339(&created_at_str)
            .map_err(|_| {
                rusqlite::Error::InvalidColumnType(
                    4,
                    "created_at".to_string(),
                    rusqlite::types::Type::Text,
                )
            })?
            .with_timezone(&Utc);

        let updated_at = DateTime::parse_from_rfc3339(&updated_at_str)
            .map_err(|_| {
                rusqlite::Error::InvalidColumnType(
                    5,
                    "updated_at".to_string(),
                    rusqlite::types::Type::Text,
                )
            })?
            .with_timezone(&Utc);

        // 正确处理可能为NULL的description字段
        let description: Option<String> = row.get(3)?;
        let description = description.filter(|s| !s.is_empty());

        Ok(Project {
            id: row.get(0)?,
            name: row.get(1)?,
            path: row.get(2)?,
            description,
            created_at,
            updated_at,
            is_active,
        })
    }
}
