package com.ruoyi.credit.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.credit.domain.ContractEmployeeLink;
import com.ruoyi.credit.domain.EmployeeInfo;
import com.ruoyi.credit.domain.EmployeeLibrary;
import com.ruoyi.credit.mapper.ContractEmployeeLinkMapper;
import com.ruoyi.credit.mapper.EmployeeInfoMapper;
import com.ruoyi.credit.mapper.EmployeeLibraryMapper;
import com.ruoyi.credit.service.IEmployeeManagerService;
import com.ruoyi.framework.security.validator.DepartmentPermissionValidator;

/**
 * 员工管理服务实现
 * 
 * @author ruoyi
 * @date 2025-12-22
 */
@Service
public class EmployeeManagerServiceImpl implements IEmployeeManagerService
{
    private static final Logger log = LoggerFactory.getLogger(EmployeeManagerServiceImpl.class);

    @Autowired
    private EmployeeLibraryMapper employeeLibraryMapper;

    @Autowired
    private EmployeeInfoMapper employeeInfoMapper;

    @Autowired
    private ContractEmployeeLinkMapper contractEmployeeLinkMapper;

    @Autowired
    private DepartmentPermissionValidator departmentPermissionValidator;

    // ==================== 员工库管理 ====================

    /**
     * 为安保公司创建员工库
     */
    @Override
    @Transactional
    public EmployeeLibrary createEmployeeLibrary(Long companyId, String libraryName, String description)
    {
        log.info("为公司创建员工库: companyId={}, libraryName={}", companyId, libraryName);
        
        // 检查公司是否已有员工库
        EmployeeLibrary existingLibrary = employeeLibraryMapper.selectEmployeeLibraryByCompanyId(companyId);
        if (existingLibrary != null) {
            log.warn("公司已存在员工库: companyId={}, libraryId={}", companyId, existingLibrary.getLibraryId());
            return existingLibrary;
        }
        
        EmployeeLibrary library = new EmployeeLibrary();
        library.setCompanyId(companyId);
        library.setLibraryName(libraryName);
        library.setDescription(description);
        library.setTotalEmployees(0);
        library.setLibraryStatus(EmployeeLibrary.STATUS_ACTIVE);
        library.setCreateBy(SecurityUtils.getUsername());
        library.setCreateTime(DateUtils.getNowDate());
        
        // 验证数据创建权限并自动设置部门ID
        departmentPermissionValidator.validateDataCreation(library);
        
        employeeLibraryMapper.insertEmployeeLibrary(library);
        
        log.info("员工库创建成功: libraryId={}", library.getLibraryId());
        return library;
    }

    /**
     * 查询员工库
     */
    @Override
    public EmployeeLibrary selectEmployeeLibraryByLibraryId(Long libraryId)
    {
        return employeeLibraryMapper.selectEmployeeLibraryByLibraryId(libraryId);
    }

    /**
     * 根据公司ID查询员工库
     */
    @Override
    public EmployeeLibrary selectEmployeeLibraryByCompanyId(Long companyId)
    {
        return employeeLibraryMapper.selectEmployeeLibraryByCompanyId(companyId);
    }

    /**
     * 查询员工库列表
     */
    @Override
    public List<EmployeeLibrary> selectEmployeeLibraryList(EmployeeLibrary employeeLibrary)
    {
        return employeeLibraryMapper.selectEmployeeLibraryList(employeeLibrary);
    }

    /**
     * 修改员工库
     */
    @Override
    @Transactional
    public int updateEmployeeLibrary(EmployeeLibrary employeeLibrary)
    {
        employeeLibrary.setUpdateTime(DateUtils.getNowDate());
        return employeeLibraryMapper.updateEmployeeLibrary(employeeLibrary);
    }

    /**
     * 删除员工库
     */
    @Override
    @Transactional
    public int deleteEmployeeLibraryByLibraryId(Long libraryId)
    {
        log.info("删除员工库: libraryId={}", libraryId);
        
        // 检查是否有关联的员工
        List<EmployeeInfo> employees = employeeInfoMapper.selectEmployeeInfosByLibraryId(libraryId);
        if (!employees.isEmpty()) {
            log.warn("员工库中还有员工，无法删除: libraryId={}, employeeCount={}", libraryId, employees.size());
            throw new RuntimeException("员工库中还有 " + employees.size() + " 个员工，请先删除或转移员工后再删除员工库");
        }
        
        // 检查是否有关联的合同员工链接
        List<ContractEmployeeLink> contractLinks = contractEmployeeLinkMapper.selectContractEmployeeLinksByLibraryId(libraryId);
        if (!contractLinks.isEmpty()) {
            log.warn("员工库中还有合同员工关联，无法删除: libraryId={}, linkCount={}", libraryId, contractLinks.size());
            throw new RuntimeException("员工库中还有 " + contractLinks.size() + " 个合同员工关联，请先解除关联后再删除员工库");
        }
        
        int result = employeeLibraryMapper.deleteEmployeeLibraryByLibraryId(libraryId);
        if (result > 0) {
            log.info("员工库删除成功: libraryId={}", libraryId);
        } else {
            log.warn("员工库删除失败，可能不存在: libraryId={}", libraryId);
            throw new RuntimeException("员工库删除失败，员工库可能不存在");
        }
        
        return result;
    }

    // ==================== 员工信息管理 ====================

    /**
     * 批量导入ERP格式的员工数据
     */
    @Override
    @Transactional
    public Map<String, Object> importEmployeesFromERP(MultipartFile file, Long libraryId, String format)
    {
        log.info("开始导入ERP员工数据: libraryId={}, format={}", libraryId, format);
        
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        int successCount = 0;
        int totalCount = 0;
        
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = WorkbookFactory.create(inputStream)) {
            
            Sheet sheet = workbook.getSheetAt(0);
            
            // 跳过标题行
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;
                
                totalCount++;
                
                try {
                    EmployeeInfo employee = parseEmployeeFromRow(row, libraryId);
                    if (employee != null) {
                        int insertResult = employeeInfoMapper.insertEmployeeInfo(employee);
                        if (insertResult > 0) {
                            successCount++;
                        } else {
                            errors.add("第" + (i + 1) + "行：插入失败");
                        }
                    } else {
                        errors.add("第" + (i + 1) + "行：数据解析失败");
                    }
                } catch (Exception e) {
                    log.error("导入第{}行数据异常", i + 1, e);
                    errors.add("第" + (i + 1) + "行：" + e.getMessage());
                }
            }
            
            // 更新员工库的员工数量
            updateEmployeeLibraryCount(libraryId);
            
        } catch (IOException e) {
            log.error("读取Excel文件异常", e);
            errors.add("文件读取失败：" + e.getMessage());
        }
        
        result.put("totalCount", totalCount);
        result.put("successCount", successCount);
        result.put("errorCount", totalCount - successCount);
        result.put("errors", errors);
        
        log.info("ERP员工数据导入完成: 总数={}, 成功={}, 失败={}", totalCount, successCount, totalCount - successCount);
        return result;
    }

    /**
     * 从Excel行解析员工信息
     */
    private EmployeeInfo parseEmployeeFromRow(Row row, Long libraryId) {
        try {
            EmployeeInfo employee = new EmployeeInfo();
            employee.setLibraryId(libraryId);
            
            // 根据ERP格式解析各列数据
            employee.setEmployeeNumber(getCellStringValue(row, 0));
            employee.setEmployeeName(getCellStringValue(row, 1));
            employee.setIdCardNumber(getCellStringValue(row, 2));
            employee.setPosition(getCellStringValue(row, 3));
            employee.setDepartment(getCellStringValue(row, 4));
            employee.setContactPhone(getCellStringValue(row, 5));
            
            // 设置默认值
            employee.setEmployeeStatus(EmployeeInfo.STATUS_ACTIVE);
            employee.setIsTemporary(false);
            employee.setCreateTime(DateUtils.getNowDate());
            employee.setCreateBy(SecurityUtils.getUsername());
            
            return employee;
        } catch (Exception e) {
            log.error("解析员工信息异常", e);
            return null;
        }
    }

    /**
     * 获取单元格字符串值
     */
    private String getCellStringValue(Row row, int cellIndex) {
        if (row.getCell(cellIndex) == null) {
            return null;
        }
        return row.getCell(cellIndex).getStringCellValue();
    }

    /**
     * 创建员工信息
     */
    @Override
    @Transactional
    public int createEmployee(EmployeeInfo employeeInfo)
    {
        log.info("创建员工信息: employeeName={}, employeeNumber={}", 
                employeeInfo.getEmployeeName(), employeeInfo.getEmployeeNumber());
        
        // 设置默认值
        if (employeeInfo.getEmployeeStatus() == null) {
            employeeInfo.setEmployeeStatus(EmployeeInfo.STATUS_ACTIVE);
        }
        
        if (employeeInfo.getIsTemporary() == null) {
            employeeInfo.setIsTemporary(false);
        }
        
        employeeInfo.setCreateBy(SecurityUtils.getUsername());
        employeeInfo.setCreateTime(DateUtils.getNowDate());
        
        // 验证数据创建权限并自动设置部门ID
        departmentPermissionValidator.validateDataCreation(employeeInfo);
        
        int result = employeeInfoMapper.insertEmployeeInfo(employeeInfo);
        
        // 更新员工库的员工数量
        if (result > 0 && employeeInfo.getLibraryId() != null) {
            updateEmployeeLibraryCount(employeeInfo.getLibraryId());
        }
        
        return result;
    }

    /**
     * 查询员工信息
     */
    @Override
    public EmployeeInfo selectEmployeeInfoByEmployeeId(Long employeeId)
    {
        return employeeInfoMapper.selectEmployeeInfoByEmployeeId(employeeId);
    }

    /**
     * 根据员工库ID查询员工信息列表
     */
    @Override
    public List<EmployeeInfo> selectEmployeeInfosByLibraryId(Long libraryId)
    {
        return employeeInfoMapper.selectEmployeeInfosByLibraryId(libraryId);
    }

    /**
     * 根据岗位查询员工信息列表
     */
    @Override
    public List<EmployeeInfo> selectEmployeeInfosByPosition(String position)
    {
        return employeeInfoMapper.selectEmployeeInfosByPosition(position);
    }

    /**
     * 查询员工信息列表
     */
    @Override
    public List<EmployeeInfo> selectEmployeeInfoList(EmployeeInfo employeeInfo)
    {
        return employeeInfoMapper.selectEmployeeInfoList(employeeInfo);
    }

    /**
     * 修改员工信息
     */
    @Override
    @Transactional
    public int updateEmployeeInfo(EmployeeInfo employeeInfo)
    {
        log.info("更新员工信息: employeeId={}, employeeName={}, monthlySalary={}, dailySalary={}, hourlySalary={}", 
                employeeInfo.getEmployeeId(), employeeInfo.getEmployeeName(), 
                employeeInfo.getMonthlySalary(), employeeInfo.getDailySalary(), employeeInfo.getHourlySalary());
        
        employeeInfo.setUpdateTime(DateUtils.getNowDate());
        employeeInfo.setUpdateBy(SecurityUtils.getUsername());
        
        int result = employeeInfoMapper.updateEmployeeInfo(employeeInfo);
        
        log.info("员工信息更新结果: employeeId={}, result={}", employeeInfo.getEmployeeId(), result);
        
        return result;
    }

    /**
     * 删除员工信息
     */
    @Override
    @Transactional
    public int deleteEmployeeInfoByEmployeeId(Long employeeId)
    {
        log.info("删除员工信息: employeeId={}", employeeId);
        
        // 获取员工信息以便更新员工库统计
        EmployeeInfo employee = employeeInfoMapper.selectEmployeeInfoByEmployeeId(employeeId);
        
        int result = employeeInfoMapper.deleteEmployeeInfoByEmployeeId(employeeId);
        
        // 更新员工库的员工数量
        if (result > 0 && employee != null && employee.getLibraryId() != null) {
            updateEmployeeLibraryCount(employee.getLibraryId());
        }
        
        return result;
    }

    /**
     * 添加临时员工
     */
    @Override
    @Transactional
    public int addTemporaryEmployee(EmployeeInfo employeeInfo, boolean syncToLibrary)
    {
        log.info("添加临时员工: employeeName={}, syncToLibrary={}", 
                employeeInfo.getEmployeeName(), syncToLibrary);
        
        employeeInfo.setIsTemporary(true);
        employeeInfo.setEmployeeStatus(EmployeeInfo.STATUS_ACTIVE);
        employeeInfo.setCreateBy(SecurityUtils.getUsername());
        employeeInfo.setCreateTime(DateUtils.getNowDate());
        
        // 验证数据创建权限并自动设置部门ID
        departmentPermissionValidator.validateDataCreation(employeeInfo);
        
        int result = employeeInfoMapper.insertEmployeeInfo(employeeInfo);
        
        // 如果需要同步到员工库，更新统计
        if (result > 0 && syncToLibrary && employeeInfo.getLibraryId() != null) {
            updateEmployeeLibraryCount(employeeInfo.getLibraryId());
        }
        
        return result;
    }

    // ==================== 员工批量操作 ====================

    /**
     * 批量修改员工信息
     */
    @Override
    @Transactional
    public int batchUpdateEmployees(List<Long> employeeIds, Map<String, Object> updateFields)
    {
        log.info("批量修改员工信息: employeeIds={}, updateFields={}", employeeIds, updateFields);
        
        int successCount = 0;
        
        for (Long employeeId : employeeIds) {
            try {
                // 获取现有员工信息
                EmployeeInfo employee = employeeInfoMapper.selectEmployeeInfoByEmployeeId(employeeId);
                if (employee == null) {
                    log.warn("员工不存在，跳过: employeeId={}", employeeId);
                    continue;
                }
                
                // 应用更新字段
                applyUpdateFields(employee, updateFields);
                employee.setUpdateTime(DateUtils.getNowDate());
                employee.setUpdateBy(SecurityUtils.getUsername());
                
                int result = employeeInfoMapper.updateEmployeeInfo(employee);
                if (result > 0) {
                    successCount++;
                }
            } catch (Exception e) {
                log.error("批量修改员工异常: employeeId={}", employeeId, e);
            }
        }
        
        log.info("批量修改员工完成: 成功数量={}", successCount);
        return successCount;
    }

    /**
     * 批量删除员工信息
     */
    @Override
    @Transactional
    public int batchDeleteEmployees(List<Long> employeeIds)
    {
        log.info("批量删除员工信息: employeeIds={}", employeeIds);
        
        int successCount = 0;
        Map<Long, Integer> libraryCountMap = new HashMap<>();
        
        for (Long employeeId : employeeIds) {
            try {
                // 获取员工信息以便更新员工库统计
                EmployeeInfo employee = employeeInfoMapper.selectEmployeeInfoByEmployeeId(employeeId);
                if (employee == null) {
                    log.warn("员工不存在，跳过: employeeId={}", employeeId);
                    continue;
                }
                
                int result = employeeInfoMapper.deleteEmployeeInfoByEmployeeId(employeeId);
                if (result > 0) {
                    successCount++;
                    // 记录需要更新的员工库
                    if (employee.getLibraryId() != null) {
                        libraryCountMap.put(employee.getLibraryId(), 
                                libraryCountMap.getOrDefault(employee.getLibraryId(), 0) + 1);
                    }
                }
            } catch (Exception e) {
                log.error("批量删除员工异常: employeeId={}", employeeId, e);
            }
        }
        
        // 更新员工库统计
        for (Long libraryId : libraryCountMap.keySet()) {
            updateEmployeeLibraryCount(libraryId);
        }
        
        log.info("批量删除员工完成: 成功数量={}", successCount);
        return successCount;
    }

    /**
     * 批量转移员工到其他员工库
     */
    @Override
    @Transactional
    public int batchTransferEmployees(List<Long> employeeIds, Long targetLibraryId)
    {
        log.info("批量转移员工: employeeIds={}, targetLibraryId={}", employeeIds, targetLibraryId);
        
        // 验证目标员工库是否存在
        EmployeeLibrary targetLibrary = employeeLibraryMapper.selectEmployeeLibraryByLibraryId(targetLibraryId);
        if (targetLibrary == null) {
            log.error("目标员工库不存在: targetLibraryId={}", targetLibraryId);
            return 0;
        }
        
        int successCount = 0;
        Map<Long, Integer> sourceLibraryCountMap = new HashMap<>();
        
        for (Long employeeId : employeeIds) {
            try {
                EmployeeInfo employee = employeeInfoMapper.selectEmployeeInfoByEmployeeId(employeeId);
                if (employee == null) {
                    log.warn("员工不存在，跳过: employeeId={}", employeeId);
                    continue;
                }
                
                Long sourceLibraryId = employee.getLibraryId();
                employee.setLibraryId(targetLibraryId);
                employee.setUpdateTime(DateUtils.getNowDate());
                employee.setUpdateBy(SecurityUtils.getUsername());
                
                int result = employeeInfoMapper.updateEmployeeInfo(employee);
                if (result > 0) {
                    successCount++;
                    // 记录源员工库
                    if (sourceLibraryId != null) {
                        sourceLibraryCountMap.put(sourceLibraryId, 
                                sourceLibraryCountMap.getOrDefault(sourceLibraryId, 0) + 1);
                    }
                }
            } catch (Exception e) {
                log.error("批量转移员工异常: employeeId={}", employeeId, e);
            }
        }
        
        // 更新源员工库和目标员工库的统计
        for (Long sourceLibraryId : sourceLibraryCountMap.keySet()) {
            updateEmployeeLibraryCount(sourceLibraryId);
        }
        updateEmployeeLibraryCount(targetLibraryId);
        
        log.info("批量转移员工完成: 成功数量={}", successCount);
        return successCount;
    }

    // ==================== OCR和数据提取 ====================

    /**
     * 通过OCR提取员工相关信息
     */
    @Override
    public Map<String, Object> extractEmployeeInfoFromOCR(MultipartFile contractFile)
    {
        log.info("开始OCR提取员工信息: fileName={}", contractFile.getOriginalFilename());
        
        Map<String, Object> result = new HashMap<>();
        
        // TODO: 实现OCR功能
        result.put("success", false);
        result.put("message", "OCR功能暂未实现");
        
        return result;
    }

    // ==================== 数据验证 ====================

    /**
     * 验证员工数据完整性
     */
    @Override
    public Map<String, Object> validateEmployeeData(Map<String, Object> employeeData)
    {
        log.info("验证员工数据完整性");
        
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        
        // 验证必填字段
        if (!employeeData.containsKey("employeeName") || 
            StringUtils.isEmpty((String) employeeData.get("employeeName"))) {
            errors.add("员工姓名不能为空");
        }
        
        if (!employeeData.containsKey("employeeNumber") || 
            StringUtils.isEmpty((String) employeeData.get("employeeNumber"))) {
            errors.add("员工工号不能为空");
        }
        
        if (!employeeData.containsKey("idCardNumber") || 
            StringUtils.isEmpty((String) employeeData.get("idCardNumber"))) {
            errors.add("身份证号不能为空");
        }
        
        result.put("valid", errors.isEmpty());
        result.put("errors", errors);
        
        return result;
    }

    /**
     * 生成员工工号
     */
    @Override
    public String generateEmployeeNumber(Long libraryId)
    {
        log.info("生成员工工号: libraryId={}", libraryId);
        
        // 获取员工库信息
        EmployeeLibrary library = employeeLibraryMapper.selectEmployeeLibraryByLibraryId(libraryId);
        if (library == null) {
            log.error("员工库不存在: libraryId={}", libraryId);
            return null;
        }
        
        // 获取当前员工库中的最大工号序号
        int maxNumber = employeeInfoMapper.getMaxEmployeeNumberByLibraryId(libraryId);
        
        // 生成新工号：库ID + 4位序号，确保唯一性
        String newEmployeeNumber;
        int attempts = 0;
        int maxAttempts = 100; // 最多尝试100次
        
        do {
            maxNumber++;
            newEmployeeNumber = String.format("%d%04d", libraryId, maxNumber);
            attempts++;
            
            // 检查工号是否已存在
            EmployeeInfo existingEmployee = employeeInfoMapper.selectEmployeeInfoByEmployeeNumber(newEmployeeNumber);
            if (existingEmployee == null) {
                log.info("生成员工工号成功: {}", newEmployeeNumber);
                return newEmployeeNumber;
            }
            
            log.warn("工号已存在，尝试下一个: {}", newEmployeeNumber);
            
        } while (attempts < maxAttempts);
        
        log.error("生成员工工号失败，已尝试{}次", maxAttempts);
        return null;
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 更新员工库的员工数量统计
     */
    private void updateEmployeeLibraryCount(Long libraryId) {
        if (libraryId == null) return;
        
        try {
            int count = employeeInfoMapper.countEmployeesByLibraryId(libraryId);
            EmployeeLibrary library = new EmployeeLibrary();
            library.setLibraryId(libraryId);
            library.setTotalEmployees(count);
            library.setUpdateTime(DateUtils.getNowDate());
            employeeLibraryMapper.updateEmployeeLibrary(library);
            
            log.debug("更新员工库统计: libraryId={}, totalEmployees={}", libraryId, count);
        } catch (Exception e) {
            log.error("更新员工库统计异常: libraryId={}", libraryId, e);
        }
    }

    /**
     * 应用更新字段到员工对象
     */
    private void applyUpdateFields(EmployeeInfo employee, Map<String, Object> updateFields) {
        for (Map.Entry<String, Object> entry : updateFields.entrySet()) {
            String fieldName = entry.getKey();
            Object value = entry.getValue();
            
            switch (fieldName) {
                case "employeeName":
                    employee.setEmployeeName((String) value);
                    break;
                case "position":
                    employee.setPosition((String) value);
                    break;
                case "department":
                    employee.setDepartment((String) value);
                    break;
                case "contactPhone":
                    employee.setContactPhone((String) value);
                    break;
                case "employeeStatus":
                    employee.setEmployeeStatus((String) value);
                    break;
                case "dailySalary":
                    if (value instanceof String) {
                        employee.setDailySalary(new BigDecimal((String) value));
                    } else if (value instanceof BigDecimal) {
                        employee.setDailySalary((BigDecimal) value);
                    } else if (value instanceof Number) {
                        employee.setDailySalary(new BigDecimal(value.toString()));
                    }
                    // 设置日薪时清空其他薪资字段
                    employee.setMonthlySalary(null);
                    employee.setHourlySalary(null);
                    break;
                case "monthlySalary":
                    if (value instanceof String) {
                        employee.setMonthlySalary(new BigDecimal((String) value));
                    } else if (value instanceof BigDecimal) {
                        employee.setMonthlySalary((BigDecimal) value);
                    } else if (value instanceof Number) {
                        employee.setMonthlySalary(new BigDecimal(value.toString()));
                    }
                    // 设置月薪时清空其他薪资字段
                    employee.setDailySalary(null);
                    employee.setHourlySalary(null);
                    break;
                case "hourlySalary":
                    if (value instanceof String) {
                        employee.setHourlySalary(new BigDecimal((String) value));
                    } else if (value instanceof BigDecimal) {
                        employee.setHourlySalary((BigDecimal) value);
                    } else if (value instanceof Number) {
                        employee.setHourlySalary(new BigDecimal(value.toString()));
                    }
                    // 设置时薪时清空其他薪资字段
                    employee.setMonthlySalary(null);
                    employee.setDailySalary(null);
                    break;
                // 可以根据需要添加更多字段
                default:
                    log.warn("未知的更新字段: {}", fieldName);
                    break;
            }
        }
    }
}