export const dynamic = "force-dynamic";
import getDb from '@/lib/db';
import { getUserFromRequest, unauthorizedResponse, forbiddenResponse, checkRole } from '@/lib/auth';
import ExcelJS from 'exceljs';
import path from 'path';

// Helper to parse numeric values from Excel
const parseNum = (val) => {
  if (val === null || val === undefined || val === '') return null;
  if (typeof val === 'number') return val;
  const cleaned = String(val).replace(/[¥$,\s]/g, '');
  const num = parseFloat(cleaned);
  return isNaN(num) ? null : num;
};

// Helper to fuzzy match Chinese names (handles sound-alike/homophone typos)
const findUserFuzzy = (name, userMap, allUsers) => {
  if (!name) return null;
  const cleanedName = name.trim();
  
  // 1. 尝试精确匹配
  if (userMap.has(cleanedName)) {
    return userMap.get(cleanedName);
  }
  
  // 2. 尝试模糊匹配（如 乔新晓 匹配 乔欣晓）
  // 三字姓名：如果姓和名匹配2个字，即可认为同一人
  if (cleanedName.length === 3) {
    for (const u of allUsers) {
      if (u.real_name.length === 3) {
        let matchCount = 0;
        if (u.real_name[0] === cleanedName[0]) matchCount++;
        if (u.real_name[1] === cleanedName[1]) matchCount++;
        if (u.real_name[2] === cleanedName[2]) matchCount++;
        if (matchCount >= 2) {
          return u;
        }
      }
    }
  } else if (cleanedName.length === 2) {
    // 二字姓名：如果姓（第一个字）相同，即可作为候选匹配
    for (const u of allUsers) {
      if (u.real_name.length === 2 && u.real_name[0] === cleanedName[0]) {
        return u;
      }
    }
  }
  
  return null;
};

// Helper to parse dates from Excel (fixes 1970-01-01 Excel serial date number issue)
const parseDate = (val) => {
  if (val instanceof Date) {
    return val.toISOString().substring(0, 10);
  }
  if (val === null || val === undefined || val === '') return null;
  
  const strVal = String(val).trim();

  // 1. 针对 YYYYMMDD (8位数字) 格式的处理
  if (/^\d{8}$/.test(strVal)) {
    const year = strVal.substring(0, 4);
    const month = strVal.substring(4, 6);
    const day = strVal.substring(6, 8);
    return `${year}-${month}-${day}`;
  }
  
  // 2. 如果是数字且在合理范围内，代表 Excel 序列日期数（40000 - 60000 之间为近十年日期）
  if (typeof val === 'number' && val > 0 && val < 100000) {
    const excelEpoch = new Date(Date.UTC(1899, 11, 30));
    const msPerDay = 24 * 60 * 60 * 1000;
    const date = new Date(excelEpoch.getTime() + val * msPerDay);
    if (!isNaN(date.getTime())) {
      return date.toISOString().substring(0, 10);
    }
  }

  // 3. 针对中文常见日期字符串格式（如“2023年10月24日”）进行正则提取，防止 JS 原生 Date 解析报错
  const match = strVal.match(/(\d{4})[-/年. ]\s*(\d{1,2})[-/月. ]\s*(\d{1,2})[日\s]*/);
  if (match) {
    const year = match[1];
    const month = match[2].padStart(2, '0');
    const day = match[3].padStart(2, '0');
    return `${year}-${month}-${day}`;
  }
  
  const date = new Date(val);
  if (!isNaN(date.getTime())) {
    return date.toISOString().substring(0, 10);
  }
  return strVal;
};

// POST /api/contracts/import - 导入历史已通过合同 Excel
export async function POST(request) {
  try {
    const user = getUserFromRequest(request);
    if (!user) return unauthorizedResponse();
    if (!checkRole(user, ['admin'])) return forbiddenResponse();

    const formData = await request.formData();
    const file = formData.get('file');
    if (!file) {
      return Response.json(
        { error: '请选择要上传的 Excel 文件' },
        { status: 400 }
      );
    }

    const arrayBuffer = await file.arrayBuffer();
    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.load(Buffer.from(arrayBuffer));
    const worksheet = workbook.worksheets[0];

    if (!worksheet) {
      return Response.json(
        { error: 'Excel 工作表为空' },
        { status: 400 }
      );
    }

    const db = await getDb();

    // 预先获取全量用户用于匹配经办人和项目负责人
    const allUsers = db.prepare('SELECT id, username, real_name, role, department_id FROM users').all();
    const userMap = new Map();
    for (const u of allUsers) {
      userMap.set(u.real_name, u);
    }

    // 预先获取全量部门名称和ID映射
    const allDepts = db.prepare('SELECT id, name FROM departments').all();
    const deptMap = new Map();
    const deptIdToNameMap = new Map();
    for (const d of allDepts) {
      deptMap.set(d.name, d.id);
      deptIdToNameMap.set(d.id, d.name);
    }

    // 预先获取合作伙伴列表
    const allPartners = db.prepare('SELECT id, name FROM partners WHERE is_deleted = 0').all();
    const partnerMap = new Map();
    for (const p of allPartners) {
      partnerMap.set(p.name, p.id);
    }

    // 解析表头列索引
    const headers = {};
    const headerRow = worksheet.getRow(1);
    headerRow.eachCell((cell, colNumber) => {
      const text = cell.text ? cell.text.trim() : '';
      if (!text) return;
      if (text.includes('创建时间') || text.includes('经办日期')) headers.created_at = colNumber;
      else if (text.includes('经办人') || text.includes('创建人')) headers.creator_name = colNumber;
      else if (text.includes('所属部门')) headers.department_name = colNumber;
      else if (text.includes('项目负责人') || text.includes('负责人')) headers.project_leader = colNumber;
      else if (text.includes('签订') || text.includes('签署') || text.includes('签字') || text.includes('签章')) headers.sign_date = colNumber;
      else if (text.includes('项目名称') || text.includes('合同名称')) headers.project_name = colNumber;
      else if (text.includes('合作单位') || text.includes('合作企业')) headers.partner_name = colNumber;
      else if (text.includes('项目内容') || text.includes('合同内容')) headers.contract_content = colNumber;
      else if (text.includes('合同总金额') || text.includes('合同金额') || text.includes('金额')) headers.contract_amount = colNumber;
      else if (text.includes('预估利润') || text.includes('利润')) headers.estimated_profit = colNumber;
      else if (text.includes('收款/付款') || text.includes('类型')) headers.payment_type = colNumber;
      else if (text.includes('初审意见') || text.includes('主管意见')) headers.supervisor_opinion = colNumber;
      else if (text.includes('财务部意见') || text.includes('财务意见')) headers.finance_opinion = colNumber;
      else if (text.includes('终审意见') || text.includes('秘书长意见')) headers.secretary_opinion = colNumber;
      else if (text.includes('合同期限') || text.includes('合作期限')) headers.contract_years = colNumber;
    });

    // 默认审核人员（财务和秘书长）
    const financeUser = allUsers.find(u => u.role === 'finance');
    const finance_id = financeUser ? financeUser.id : null;
    const finance_name = financeUser ? financeUser.real_name : null;

    const secretaryUser = allUsers.find(u => u.role === 'secretary');
    const secretary_id = secretaryUser ? secretaryUser.id : null;
    const secretary_name = secretaryUser ? secretaryUser.real_name : null;

    let importedCount = 0;

    // 使用事务包装批量写入操作，极大提升 SQLite 性能并保证数据一致性
    const runImport = db.transaction(() => {
      for (let rowNumber = 2; rowNumber <= worksheet.rowCount; rowNumber++) {
        const row = worksheet.getRow(rowNumber);
        console.log(`[Importer] Processing row: ${rowNumber}, Has Values: ${row.hasValues}`);
        if (!row.hasValues) continue;

        const getVal = (key) => {
          const colIndex = headers[key];
          if (!colIndex) return undefined;
          const cell = row.getCell(colIndex);
          if (!cell || !cell.value) return undefined;

          // Handle formula objects
          if (typeof cell.value === 'object' && cell.value !== null && cell.value.formula) {
            return cell.value.result;
          }
          return cell.value;
        };

        const getValText = (key) => {
          const colIndex = headers[key];
          if (!colIndex) return '';
          const cell = row.getCell(colIndex);
          if (!cell) return '';
          return cell.text ? cell.text.trim() : '';
        };

        const project_name = getValText('project_name');
        // if (!project_name) continue; // 项目名称不能为空，略过空行

        // 1. 匹配经办人与部门
        const excelCreator = getValText('creator_name');
        let creator_id = user.id; // 默认当前管理员
        let creator_name = excelCreator || user.real_name;
        let department_id = null;
        let department_name = null;

        if (excelCreator) {
          const matchedUser = findUserFuzzy(excelCreator, userMap, allUsers);
          if (matchedUser) {
            creator_id = matchedUser.id;
            creator_name = matchedUser.real_name;
            department_id = matchedUser.department_id;
            department_name = deptIdToNameMap.get(department_id) || null;
          }
        }

        // 如果经办人没有匹配到，看 Excel 中是否填了“所属部门”
        if (!department_id) {
          const excelDept = getValText('department_name');
          if (excelDept && deptMap.has(excelDept)) {
            department_id = deptMap.get(excelDept);
            department_name = excelDept;
          }
        }

        // 2. 匹配或自动创建合作单位
        let partner_name = getValText('partner_name');
        let partner_id = null;
        if (!partner_name) {
          partner_name = '历史导入合作单位';
        }
        if (partnerMap.has(partner_name)) {
          partner_id = partnerMap.get(partner_name);
        } else {
          // 数据库没有，动态插入合作单位作为种子数据
          const pResult = db.prepare(
            'INSERT INTO partners (name, is_deleted) VALUES (?, 0)'
          ).run(partner_name);
          partner_id = pResult.lastInsertRowid;
          partnerMap.set(partner_name, partner_id);
        }

        // 3. 匹配项目负责人（部门主管）
        const excelLeader = getValText('project_leader');
        let project_leader = excelLeader || null;
        let matchedLeaderUser = null;
        if (excelLeader) {
          const matchedLeader = findUserFuzzy(excelLeader, userMap, allUsers);
          if (matchedLeader) {
            project_leader = matchedLeader.real_name;
            matchedLeaderUser = matchedLeader;
          }
        }

        // 如果上面经办人没能定下部门（例如经办人在库里不存在且Excel无部门），
        // 但项目负责人（主管）匹配成功了，则以项目负责人的部门作为合同的归属部门，这样主管就可以看得到了！
        if (!department_id && matchedLeaderUser && matchedLeaderUser.department_id) {
          department_id = matchedLeaderUser.department_id;
          department_name = deptIdToNameMap.get(department_id) || null;
        }

        // 如果还是没有，回退到当前登录账号（管理员）的部门
        if (!department_id) {
          department_id = user.department_id || null;
          department_name = deptIdToNameMap.get(department_id) || null;
        }

        // 4. 收付款类型
        const excelPayment = getValText('payment_type');
        let payment_type = 'receive';
        if (excelPayment.includes('付') || excelPayment.toLowerCase().includes('pay')) {
          payment_type = 'pay';
        }

        // 5. 合同金额与预估利润
        const contract_amount = parseNum(getVal('contract_amount')) || 0;
        // 如果是付款，预估利润强置为 null，否则允许解析为空或数字
        let estimated_profit = null;
        if (payment_type !== 'pay') {
          estimated_profit = parseNum(getVal('estimated_profit'));
        }

        // 6. 日期格式解析
        const created_at_val = parseDate(getValText('created_at'));
        const sign_date = parseDate(getValText('sign_date'));
        const created_at = created_at_val || sign_date || new Date().toISOString().substring(0, 10);
        const approval_time = sign_date || created_at || new Date().toISOString().substring(0, 10);

        // 7. 匹配部门初审主管作为初审人
        let supervisor_id = null;
        let supervisor_name = null;

        if (matchedLeaderUser) {
            supervisor_id = matchedLeaderUser.id;
            supervisor_name = matchedLeaderUser.real_name;
        } else if (department_id) {
          const matchedSupervisor = allUsers.find(u => u.department_id === department_id && u.role === 'supervisor');
          if (matchedSupervisor) {
            supervisor_id = matchedSupervisor.id;
            supervisor_name = matchedSupervisor.real_name;
          }
        }
        // 如果上面没配出主管，但是项目负责人匹配出来的正是一个主管，则直接用他
        if (!supervisor_name && matchedLeaderUser && matchedLeaderUser.role === 'supervisor') {
          supervisor_id = matchedLeaderUser.id;
          supervisor_name = matchedLeaderUser.real_name;
        }
        if (!supervisor_name) {
          const anySupervisor = allUsers.find(u => u.role === 'supervisor');
          if (anySupervisor) {
            supervisor_id = anySupervisor.id;
            supervisor_name = anySupervisor.real_name;
          }
        }

        // 8. 审核意见（默认为 '无'）
        const supervisor_opinion = getValText('supervisor_opinion') || '无';
        const finance_opinion = getValText('finance_opinion') || '无';
        const secretary_opinion = getValText('secretary_opinion') || '无';

        const contract_content = getValText('contract_content') || null;
        const contract_years = getValText('contract_years') || null; // 留空即可

        // 9. 写入数据库并设为终审通过状态
        db.prepare(`
          INSERT INTO contracts (
            project_name, partner_id, partner_name, contract_content, contract_years,
            contract_amount, estimated_profit, payment_type, sign_date,
            creator_id, creator_name, department_id, department_name, project_leader,
            status,
            supervisor_opinion, supervisor_approved, supervisor_id, supervisor_name, supervisor_time,
            finance_opinion, finance_approved, finance_id, finance_name, finance_time,
            secretary_opinion, secretary_approved, secretary_id, secretary_name, secretary_time,
            created_at, updated_at
          ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'approved', ?, 1, ?, ?, ?, ?, 1, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?)
        `).run(
          project_name,
          partner_id,
          partner_name,
          contract_content,
          contract_years,
          contract_amount,
          estimated_profit,
          payment_type,
          sign_date,
          creator_id,
          creator_name,
          department_id,
          department_name,
          project_leader,
          
          supervisor_opinion,
          supervisor_id,
          supervisor_name,
          null, // supervisor_time
          
          finance_opinion,
          finance_id,
          finance_name,
          null, // finance_time
          
          secretary_opinion,
          secretary_id,
          secretary_name,
          null, // secretary_time,
          
          created_at,
          created_at
        );

        importedCount++;
      }
      return importedCount;
    });

    const totalImported = runImport();
    console.log(`[Contract Import] Successfully imported ${totalImported} rows.`);

    return Response.json({
      success: true,
      message: `成功导入了 ${totalImported} 条合同数据。`,
      count: totalImported
    });

  } catch (error) {
    console.error('导入合同数据失败:', error);
    return Response.json(
      { error: `导入失败: ${error.message || '服务器内部错误'}` },
      { status: 500 }
    );
  }
}
