// 产品组装拆分模块
use serde::{Deserialize, Serialize};
use crate::models::*;
use crate::database::DB_CONN;
use crate::operation_logs::log_operation;
use crate::error_util;
use crate::permissions::check_permission;
use uuid::Uuid;
use chrono::Local;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssemblyRecordFull {
    pub id: String,
    pub record_no: String,
    pub assembly_type: String,
    pub product_id: String,
    pub product_name: String,
    pub quantity: f64,
    pub components: String,
    pub component_details: Vec<AssemblyComponentDetail>,
    pub remark: String,
    pub created_at: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssemblyComponentDetail {
    pub product_id: String,
    pub product_name: String,
    pub quantity: f64,
}

#[tauri::command]
pub fn create_assembly_record(request: CreateAssemblyRequest, username: String, real_name: String) -> Result<AssemblyRecordFull, String> {
    if !check_permission(&username, "inventory_ops") {
        return Err("权限不足：没有创建组装分拆记录的权限".to_string());
    }
    let mut conn_guard = DB_CONN.lock().map_err(|e| error_util::to_chinese_error(e))?;
    let conn = conn_guard.as_mut().ok_or("系统错误：数据库未初始化")?;

    let tx = conn.transaction().map_err(|e| error_util::to_chinese_error(e))?;

    let id = Uuid::new_v4().to_string();
    let record_no = format!("AS{}", Local::now().format("%Y%m%d%H%M%S"));
    let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

    // 序列化组件
    let components_json = serde_json::to_string(&request.components).map_err(|e| error_util::to_chinese_error(e))?;

    if request.assembly_type == "assemble" {
        // 组装：扣减组件库存，增加成品库存
        for comp in &request.components {
            let cur: f64 = tx.query_row("SELECT COALESCE(stock,0.0) FROM products WHERE id=?1",
                [&comp.product_id], |row| row.get(0)).map_err(|e| format!("组件商品不存在: {}", e))?;
            let used = comp.quantity * request.quantity;
            if cur < used {
                return Err(format!("组件 '{}' 库存不足，需要: {:.2}, 当前: {:.2}", comp.product_name, used, cur));
            }
            let new_stock = cur - used;
            tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
                [&new_stock.to_string(), &comp.product_id]).map_err(|e| error_util::to_chinese_error(e))?;
            tx.execute(
                "INSERT INTO inventory_records (id, product_id, product_name, change_type, quantity, before_stock, after_stock, remark, created_at) 
                 VALUES (?1,?2,?3,'assembly_out',?4,?5,?6,?7,?8)",
                [&Uuid::new_v4().to_string(), &comp.product_id, &comp.product_name,
                 &(-used).to_string(), &cur.to_string(), &new_stock.to_string(),
                 &format!("组装出库: {}", record_no), &now]
            ).map_err(|e| error_util::to_chinese_error(e))?;
        }
        // 增加成品库存
        let cur_prod: f64 = tx.query_row("SELECT COALESCE(stock,0.0) FROM products WHERE id=?1",
            [&request.product_id], |row| row.get(0)).map_err(|e| error_util::to_chinese_error(e))?;
        let new_prod = cur_prod + request.quantity;
        tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
            [&new_prod.to_string(), &request.product_id]).map_err(|e| error_util::to_chinese_error(e))?;
        tx.execute(
            "INSERT INTO inventory_records (id, product_id, product_name, change_type, quantity, before_stock, after_stock, remark, created_at) 
             VALUES (?1,?2,?3,'assembly_in',?4,?5,?6,?7,?8)",
            [&Uuid::new_v4().to_string(), &request.product_id, &request.product_name,
             &request.quantity.to_string(), &cur_prod.to_string(), &new_prod.to_string(),
             &format!("组装入库: {}", record_no), &now]
        ).map_err(|e| error_util::to_chinese_error(e))?;
    } else {
        // 拆分：扣减成品库存，增加组件库存
        let cur_prod: f64 = tx.query_row("SELECT COALESCE(stock,0.0) FROM products WHERE id=?1",
            [&request.product_id], |row| row.get(0)).map_err(|e| error_util::to_chinese_error(e))?;
        if cur_prod < request.quantity {
            return Err(format!("成品 '{}' 库存不足，需要: {:.2}, 当前: {:.2}", request.product_name, request.quantity, cur_prod));
        }
        let new_prod = cur_prod - request.quantity;
        tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
            [&new_prod.to_string(), &request.product_id]).map_err(|e| error_util::to_chinese_error(e))?;
        tx.execute(
            "INSERT INTO inventory_records (id, product_id, product_name, change_type, quantity, before_stock, after_stock, remark, created_at) 
             VALUES (?1,?2,?3,'disassembly_out',?4,?5,?6,?7,?8)",
            [&Uuid::new_v4().to_string(), &request.product_id, &request.product_name,
             &(-request.quantity).to_string(), &cur_prod.to_string(), &new_prod.to_string(),
             &format!("拆分出库: {}", record_no), &now]
        ).map_err(|e| error_util::to_chinese_error(e))?;
        
        for comp in &request.components {
            let cur: f64 = tx.query_row("SELECT COALESCE(stock,0.0) FROM products WHERE id=?1",
                [&comp.product_id], |row| row.get(0)).map_err(|e| error_util::to_chinese_error(e))?;
            let added = comp.quantity * request.quantity;
            let new_comp = cur + added;
            tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
                [&new_comp.to_string(), &comp.product_id]).map_err(|e| error_util::to_chinese_error(e))?;
            tx.execute(
                "INSERT INTO inventory_records (id, product_id, product_name, change_type, quantity, before_stock, after_stock, remark, created_at) 
                 VALUES (?1,?2,?3,'disassembly_in',?4,?5,?6,?7,?8)",
                [&Uuid::new_v4().to_string(), &comp.product_id, &comp.product_name,
                 &added.to_string(), &cur.to_string(), &new_comp.to_string(),
                 &format!("拆分入库: {}", record_no), &now]
            ).map_err(|e| error_util::to_chinese_error(e))?;
        }
    }

    tx.execute(
        "INSERT INTO assembly_records (id, record_no, assembly_type, product_id, product_name, quantity, components, remark, created_at) 
         VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9)",
        [&id, &record_no, &request.assembly_type, &request.product_id, &request.product_name,
         &request.quantity.to_string(), &components_json, &request.remark, &now]
    ).map_err(|e| error_util::to_chinese_error(e))?;

    tx.commit().map_err(|e| error_util::to_chinese_error(e))?;

    log_operation(&username, &real_name, "创建", "产品组装拆分", &format!("{}: {} 单号: {}", 
        if request.assembly_type == "assemble" { "组装" } else { "拆分" }, request.product_name, record_no));

    Ok(AssemblyRecordFull {
        id, record_no, assembly_type: request.assembly_type,
        product_id: request.product_id, product_name: request.product_name,
        quantity: request.quantity, components: components_json,
        component_details: request.components.into_iter().map(|c| AssemblyComponentDetail {
            product_id: c.product_id,
            product_name: c.product_name,
            quantity: c.quantity,
        }).collect(),
        remark: request.remark,
        created_at: now,
    })
}

#[tauri::command]
pub fn get_assembly_records() -> Result<Vec<AssemblyRecordFull>, String> {
    let conn_guard = DB_CONN.lock().map_err(|e| error_util::to_chinese_error(e))?;
    let conn = conn_guard.as_ref().ok_or("系统错误：数据库未初始化")?;
    
    let mut stmt = conn.prepare("SELECT * FROM assembly_records ORDER BY created_at DESC")
        .map_err(|e| error_util::to_chinese_error(e))?;
    let records = stmt.query_map([], |row| {
        let components_str: String = row.get::<_, Option<String>>(6)?.unwrap_or_default();
        let details: Vec<AssemblyComponentDetail> = serde_json::from_str(&components_str).unwrap_or_default();
        Ok(AssemblyRecordFull {
            id: row.get(0)?, record_no: row.get(1)?,
            assembly_type: row.get(2)?, product_id: row.get(3)?,
            product_name: row.get(4)?, quantity: row.get(5)?,
            components: components_str.clone(), component_details: details,
            remark: row.get::<_, Option<String>>(7)?.unwrap_or_default(),
            created_at: row.get::<_, String>(8).unwrap_or_default(),
        })
    }).map_err(|e| error_util::to_chinese_error(e))?;
    records.collect::<Result<Vec<_>, _>>().map_err(|e| error_util::to_chinese_error(e))
}

#[tauri::command]
pub fn delete_assembly_record(record_id: String, username: String, real_name: String) -> Result<String, String> {
    if !check_permission(&username, "inventory_ops") {
        return Err("权限不足：没有删除组装分拆记录的权限".to_string());
    }
    let mut conn_guard = DB_CONN.lock().map_err(|e| error_util::to_chinese_error(e))?;
    let conn = conn_guard.as_mut().ok_or("系统错误：数据库未初始化")?;
    let info: (String, String) = conn.query_row(
        "SELECT assembly_type, product_name FROM assembly_records WHERE id=?1", [&record_id],
        |row| Ok((row.get(0)?, row.get(1)?))
    ).unwrap_or_default();
    conn.execute("DELETE FROM assembly_records WHERE id=?1", [&record_id])
        .map_err(|e| error_util::to_chinese_error(e))?;
    log_operation(&username, &real_name, "删除", "产品组装拆分", &format!("删除{}记录: {}", info.0, info.1));
    Ok("删除成功".to_string())
}