// 库存调拨模块
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 TransferOrderFull {
    pub id: String,
    pub order_no: String,
    pub from_warehouse_id: String,
    pub from_warehouse_name: String,
    pub to_warehouse_id: String,
    pub to_warehouse_name: String,
    pub status: String,
    pub remark: String,
    pub created_at: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransferOrderItemFull {
    pub id: String,
    pub transfer_id: String,
    pub product_id: String,
    pub product_name: String,
    pub quantity: f64,
    pub unit: String,
    pub batch_no: String,
}

#[tauri::command]
pub fn create_transfer_order(request: CreateTransferOrderRequest, username: String, real_name: String) -> Result<TransferOrderFull, 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 order_no = format!("TO{}", Local::now().format("%Y%m%d%H%M%S"));
    let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

    // 查询仓库名称
    let from_wh_name: String = tx.query_row("SELECT name FROM warehouses WHERE id=?1",
        [&request.from_warehouse_id], |row| row.get(0)).unwrap_or_default();
    let to_wh_name: String = tx.query_row("SELECT name FROM warehouses WHERE id=?1",
        [&request.to_warehouse_id], |row| row.get(0)).unwrap_or_default();

    for item in &request.items {
        // 检查源仓库库存
        let current_stock: f64 = tx.query_row(
            "SELECT COALESCE(stock, 0.0) FROM products WHERE id = ?1",
            [&item.product_id], |row| row.get(0)
        ).map_err(|e| error_util::to_chinese_error(e))?;

        if current_stock < item.quantity {
            return Err(format!("商品 '{}' 库存不足，当前库存: {:.2}", item.product_name, current_stock));
        }
    }

    tx.execute(
        "INSERT INTO transfer_orders (id, order_no, from_warehouse_id, from_warehouse_name, to_warehouse_id, to_warehouse_name, status, remark, created_at) 
         VALUES (?1, ?2, ?3, ?4, ?5, ?6, 'completed', ?7, ?8)",
        [&id, &order_no, &request.from_warehouse_id, &from_wh_name,
         &request.to_warehouse_id, &to_wh_name, &request.remark, &now]
    ).map_err(|e| error_util::to_chinese_error(e))?;

    for item in &request.items {
        let item_id = Uuid::new_v4().to_string();
        tx.execute(
            "INSERT INTO transfer_order_items (id, transfer_id, product_id, product_name, quantity, unit, batch_no) 
             VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
            [&item_id, &id, &item.product_id, &item.product_name,
             &item.quantity.to_string(), &item.unit, &item.batch_no]
        ).map_err(|e| error_util::to_chinese_error(e))?;

        // 获取当前库存并扣减（源仓库出库）
        let current_stock: f64 = tx.query_row(
            "SELECT COALESCE(stock, 0.0) FROM products WHERE id = ?1",
            [&item.product_id], |row| row.get(0)
        ).map_err(|e| error_util::to_chinese_error(e))?;
        let new_stock = current_stock - item.quantity;
        tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
            [&new_stock.to_string(), &item.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, ?4, ?5, ?6, ?7, ?8, ?9)",
            [&Uuid::new_v4().to_string(), &item.product_id, &item.product_name,
             "transfer_out", &(-item.quantity).to_string(), &current_stock.to_string(),
             &new_stock.to_string(), &format!("调拨出库->{}: {}", to_wh_name, order_no), &now]
        ).map_err(|e| error_util::to_chinese_error(e))?;

        // 目标仓库入库（恢复总库存，但记录入库流水）
        let after_in = new_stock + item.quantity;
        tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
            [&after_in.to_string(), &item.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, ?4, ?5, ?6, ?7, ?8, ?9)",
            [&Uuid::new_v4().to_string(), &item.product_id, &item.product_name,
             "transfer_in", &item.quantity.to_string(), &new_stock.to_string(),
             &after_in.to_string(), &format!("调拨入库<-{}: {}", from_wh_name, order_no), &now]
        ).map_err(|e| error_util::to_chinese_error(e))?;

        // 记入 stock_transactions
        tx.execute(
            "INSERT INTO stock_transactions (id, product_id, product_name, transaction_type, quantity, ref_order_no, remark, created_at) VALUES (?1,?2,?3,'transfer_in',?4,?5,?6,?7)",
            [&Uuid::new_v4().to_string(), &item.product_id, &item.product_name, &item.quantity.to_string(), &order_no, &format!("调拨入库: {}", to_wh_name), &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!("创建调拨单: {} 从 {} 到 {}", order_no, from_wh_name, to_wh_name));

    Ok(TransferOrderFull {
        id, order_no,
        from_warehouse_id: request.from_warehouse_id,
        from_warehouse_name: from_wh_name,
        to_warehouse_id: request.to_warehouse_id,
        to_warehouse_name: to_wh_name,
        status: "completed".to_string(),
        remark: request.remark,
        created_at: now,
    })
}

#[tauri::command]
pub fn get_transfer_orders() -> Result<Vec<TransferOrderFull>, 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 transfer_orders ORDER BY created_at DESC")
        .map_err(|e| error_util::to_chinese_error(e))?;
    let orders = stmt.query_map([], |row| {
        Ok(TransferOrderFull {
            id: row.get(0)?, order_no: row.get(1)?,
            from_warehouse_id: row.get(2)?, from_warehouse_name: row.get(3)?,
            to_warehouse_id: row.get(4)?, to_warehouse_name: row.get(5)?,
            status: row.get(6)?, remark: row.get(7)?, created_at: row.get(8)?,
        })
    }).map_err(|e| error_util::to_chinese_error(e))?;
    orders.collect::<Result<Vec<_>, _>>().map_err(|e| error_util::to_chinese_error(e))
}

#[tauri::command]
pub fn get_transfer_order_items(transfer_id: String) -> Result<Vec<TransferOrderItemFull>, 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 transfer_order_items WHERE transfer_id=?1")
        .map_err(|e| error_util::to_chinese_error(e))?;
    let items = stmt.query_map([&transfer_id], |row| {
        Ok(TransferOrderItemFull {
            id: row.get(0)?, transfer_id: row.get(1)?,
            product_id: row.get(2)?, product_name: row.get(3)?,
            quantity: row.get(4)?, unit: row.get(5)?, batch_no: row.get(6)?,
        })
    }).map_err(|e| error_util::to_chinese_error(e))?;
    items.collect::<Result<Vec<_>, _>>().map_err(|e| error_util::to_chinese_error(e))
}

#[tauri::command]
pub fn delete_transfer_order(transfer_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 tx = conn.transaction().map_err(|e| error_util::to_chinese_error(e))?;
    
    // 恢复库存 - 先收集数据再释放stmt
    let items: Vec<(String, String, f64)> = {
        let mut stmt = tx.prepare("SELECT product_id, product_name, quantity FROM transfer_order_items WHERE transfer_id=?1")
            .map_err(|e| error_util::to_chinese_error(e))?;
        let rows = stmt.query_map([&transfer_id], |row| {
            Ok((row.get(0)?, row.get(1)?, row.get(2)?))
        }).map_err(|e| error_util::to_chinese_error(e))?;
        rows.filter_map(|r| r.ok()).collect()
    };
    
    for (pid, pname, qty) in &items {
        let cur: f64 = tx.query_row("SELECT COALESCE(stock,0.0) FROM products WHERE id=?1",
            [pid], |row| row.get(0)).unwrap_or(0.0);
        tx.execute("UPDATE products SET stock=?1 WHERE id=?2",
            [&(cur + qty).to_string(), pid]).map_err(|e| error_util::to_chinese_error(e))?;
        
        let now = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
        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,'transfer_cancel',?4,?5,?6,?7,?8)",
            [&Uuid::new_v4().to_string(), pid, pname, &qty.to_string(),
             &cur.to_string(), &(cur + qty).to_string(),
             &format!("取消调拨单, 恢复库存"), &now]
        ).map_err(|e| error_util::to_chinese_error(e))?;
    }
    
    let transfer_no: String = tx.query_row("SELECT transfer_no FROM transfer_orders WHERE id=?1", [&transfer_id], |row| row.get(0)).unwrap_or_default();
    tx.execute("DELETE FROM transfer_order_items WHERE transfer_id=?1", [&transfer_id])
        .map_err(|e| error_util::to_chinese_error(e))?;
    tx.execute("DELETE FROM transfer_orders WHERE id=?1", [&transfer_id])
        .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!("删除调拨单: {}", transfer_no));
    
    Ok("调拨单已删除".to_string())
}