package com.ruoyi.credit.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

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 com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.credit.domain.DigitalCredit;
import com.ruoyi.credit.domain.FinancingApplication;
import com.ruoyi.credit.domain.ServicePeriod;
import com.ruoyi.credit.domain.ServicePeriodLoan;
import com.ruoyi.credit.mapper.DigitalCreditMapper;
import com.ruoyi.credit.mapper.FinancingMapper;
import com.ruoyi.credit.mapper.ServicePeriodLoanMapper;
import com.ruoyi.credit.mapper.ServicePeriodMapper;
import com.ruoyi.credit.service.IFinancingService;
import com.ruoyi.framework.security.context.DepartmentContextHolder;
import com.ruoyi.framework.security.validator.DepartmentPermissionValidator;

/**
 * 融资管理服务实现
 *
 * @author ruoyi
 * @date 2025-01-07
 */
@Service
public class FinancingServiceImpl implements IFinancingService {

    private static final Logger log = LoggerFactory.getLogger(FinancingServiceImpl.class);

    @Autowired
    private FinancingMapper financingMapper;

    @Autowired
    private ServicePeriodLoanMapper servicePeriodLoanMapper;

    @Autowired
    private ServicePeriodMapper servicePeriodMapper;

    @Autowired
    private DigitalCreditMapper digitalCreditMapper;

    @Autowired
    private DepartmentPermissionValidator departmentPermissionValidator;

    /**
     * 根据债权ID获取对应的服务周期贷款
     *
     * @param creditId 债权ID
     * @return 服务周期贷款列表
     */
    private List<ServicePeriodLoan> getServicePeriodLoansByCreditId(Long creditId) {
        try {
            log.debug("开始获取债权{}的服务周期贷款", creditId);
            
            // 1. 根据债权ID获取债权信息
            DigitalCredit digitalCredit = digitalCreditMapper.selectDigitalCreditByCreditId(creditId);
            log.debug("债权查询结果: digitalCredit={}", digitalCredit);
            
            if (digitalCredit == null) {
                log.warn("债权{}不存在", creditId);
                return new ArrayList<>();
            }
            
            if (digitalCredit.getContractId() == null) {
                log.warn("债权{}未关联合同, contractId=null", creditId);
                return new ArrayList<>();
            }
            
            log.info("债权{}关联的合同ID: {}", creditId, digitalCredit.getContractId());

            // 2. 根据合同ID获取服务周期列表
            ServicePeriod queryPeriod = new ServicePeriod();
            queryPeriod.setContractId(digitalCredit.getContractId());
            List<ServicePeriod> servicePeriods = servicePeriodMapper.selectServicePeriodList(queryPeriod);
            log.info("合同{}的服务周期数量: {}", digitalCredit.getContractId(), servicePeriods.size());
            
            if (servicePeriods.isEmpty()) {
                log.warn("合同{}没有服务周期", digitalCredit.getContractId());
                return new ArrayList<>();
            }

            // 3. 获取所有服务周期的贷款
            List<ServicePeriodLoan> allLoans = new ArrayList<>();
            for (ServicePeriod period : servicePeriods) {
                log.debug("查询服务周期{}的贷款", period.getServicePeriodId());
                List<ServicePeriodLoan> periodLoans = servicePeriodLoanMapper.selectServicePeriodLoansByPeriodId(period.getServicePeriodId());
                if (periodLoans != null) {
                    allLoans.addAll(periodLoans);
                }
            }
            
            log.info("债权{}总共找到{}个服务周期贷款", creditId, allLoans.size());
            return allLoans;
        } catch (Exception e) {
            log.error("根据债权ID获取服务周期贷款失败: creditId={}", creditId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 从服务周期贷款创建融资申请
     *
     * @param servicePeriodLoan 服务周期贷款信息
     * @return 创建结果
     */
    @Override
    @Transactional
    public Map<String, Object> createFinancingApplicationFromLoan(ServicePeriodLoan servicePeriodLoan) {
        log.info("从服务周期贷款创建融资申请: loanId={}", servicePeriodLoan.getLinkId());

        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 获取服务周期信息
            ServicePeriod servicePeriod = servicePeriodMapper.selectServicePeriodByServicePeriodId(servicePeriodLoan.getServicePeriodId());
            if (servicePeriod == null) {
                result.put("success", false);
                result.put("message", "服务周期不存在");
                return result;
            }

            // 2. 获取债权信息 - 通过服务周期关联的合同获取
            DigitalCredit digitalCredit = null;
            if (servicePeriod.getContractId() != null) {
                digitalCredit = digitalCreditMapper.selectDigitalCreditByContractId(servicePeriod.getContractId());
                if (digitalCredit == null) {
                    result.put("success", false);
                    result.put("message", "未找到关联的债权信息，合同ID: " + servicePeriod.getContractId());
                    return result;
                }
                log.info("找到关联债权: creditId={}, creditNumber={}", digitalCredit.getCreditId(), digitalCredit.getCreditNumber());
            } else {
                result.put("success", false);
                result.put("message", "服务周期未关联合同");
                return result;
            }

            // 3. 检查是否已存在融资申请（只有SUBMITTED状态才允许创建新申请）
            List<FinancingApplication> existingApplications = financingMapper.selectFinancingApplicationByCreditId(digitalCredit.getCreditId());
            if (!existingApplications.isEmpty()) {
                // 检查现有申请的状态，只有SUBMITTED状态才允许创建新申请
                for (FinancingApplication existingApp : existingApplications) {
                    String status = existingApp.getFinancingStatus();
                    if (!"SUBMITTED".equals(status)) {
                        log.warn("债权{}已存在融资申请，状态: {}，不允许创建新申请", digitalCredit.getCreditId(), status);
                        result.put("success", true);
                        result.put("message", "债权已存在融资申请，返回现有申请");
                        result.put("financingId", existingApp.getFinancingId());
                        result.put("applicationNumber", existingApp.getApplicationNumber());
                        result.put("loanId", servicePeriodLoan.getLinkId());
                        result.put("existing", true);
                        return result;
                    }
                }
                // 如果所有现有申请都是SUBMITTED状态，允许创建新申请
                log.info("债权{}的现有融资申请均为SUBMITTED状态，允许创建新申请", digitalCredit.getCreditId());
            }

            // 4. 创建融资申请记录
            FinancingApplication financing = new FinancingApplication();

            // 设置部门ID - 从债权获取部门ID
            if (digitalCredit.getDeptId() != null) {
                financing.setDeptId(digitalCredit.getDeptId());
            } else {
                // 如果债权没有部门ID，从服务周期获取
                financing.setDeptId(servicePeriod.getDeptId());
            }

            // 验证部门数据一致性
            departmentPermissionValidator.validateFinancingCreditConsistency(digitalCredit.getCreditId(), null);

            // 验证创建权限并自动设置部门ID（如果需要）
            departmentPermissionValidator.validateDataCreation(financing);

            // 生成申请编号
            financing.setApplicationNumber(generateApplicationNumber());

            // 设置债权信息（使用真实数据）
            financing.setCreditId(digitalCredit.getCreditId());
            financing.setCreditNumber(digitalCredit.getCreditNumber());

            // 设置申请人信息（从债权信息获取）
            financing.setApplicantId(digitalCredit.getCreditorId());
            financing.setApplicantName(digitalCredit.getCreditorName());

            // 设置金融机构信息
            if (servicePeriodLoan.getBankInstitutionId() != null) {
                financing.setFinancialInstitutionId(servicePeriodLoan.getBankInstitutionId());
                financing.setFinancialInstitutionName(servicePeriodLoan.getBankInstitutionName());
            }

            // 设置融资金额和条件
            financing.setRequestedAmount(servicePeriodLoan.getLoanAmount());
            financing.setInterestRate(servicePeriodLoan.getInterestRate() != null
                    ? new BigDecimal(servicePeriodLoan.getInterestRate().toString()) : null);
            financing.setFinancingTerm(servicePeriodLoan.getLoanTermMonths() != null
                    ? servicePeriodLoan.getLoanTermMonths() * 30 : null); // 转换为天数

            // 设置状态
            financing.setFinancingStatus(convertLoanStatusToFinancingStatus(servicePeriodLoan.getLoanStatus()));

            // 设置申请材料（包含债权和贷款信息）
            Map<String, Object> applicationMaterials = new HashMap<>();
            applicationMaterials.put("loanPurpose", servicePeriodLoan.getLoanPurpose());
            applicationMaterials.put("submitComments", servicePeriodLoan.getSubmitComments());
            applicationMaterials.put("servicePeriodId", servicePeriodLoan.getServicePeriodId());
            applicationMaterials.put("originalLoanId", servicePeriodLoan.getLinkId());
            // 添加债权相关信息
            applicationMaterials.put("creditAmount", digitalCredit.getCreditAmount());
            applicationMaterials.put("creditDescription", digitalCredit.getDescription());
            applicationMaterials.put("debtorName", digitalCredit.getDebtorName());
            applicationMaterials.put("issueDate", digitalCredit.getIssueDate());
            applicationMaterials.put("maturityDate", digitalCredit.getMaturityDate());
            applicationMaterials.put("creditStatus", digitalCredit.getCreditStatus());
            financing.setApplicationMaterials(applicationMaterials.toString());

            // 设置创建信息
            financing.setCreateBy(SecurityUtils.getUsername());
            financing.setCreateTime(DateUtils.getNowDate());
            financing.setUpdateBy(SecurityUtils.getUsername());
            financing.setUpdateTime(DateUtils.getNowDate());

            // 设置备注
            financing.setRemark("从服务周期贷款自动创建，债权编号: " + digitalCredit.getCreditNumber() + ", 贷款编号: " + servicePeriodLoan.getLoanNumber());

            // 5. 保存融资申请
            int insertResult = financingMapper.insertFinancingApplication(financing);

            if (insertResult > 0) {
                // 融资申请创建成功，更新备注以包含关联关系
                String finalRemark = "关联贷款ID: " + servicePeriodLoan.getLinkId() + " | " + financing.getRemark();
                financing.setRemark(finalRemark);
                financingMapper.updateFinancingApplication(financing);

                result.put("success", true);
                result.put("message", "融资申请创建成功");
                result.put("financingId", financing.getFinancingId());
                result.put("applicationNumber", financing.getApplicationNumber());
                result.put("loanId", servicePeriodLoan.getLinkId());

                log.info("融资申请创建成功: financingId={}, applicationNumber={}, loanId={}",
                        financing.getFinancingId(), financing.getApplicationNumber(), servicePeriodLoan.getLinkId());
            } else {
                result.put("success", false);
                result.put("message", "融资申请创建失败");
            }

        } catch (Exception e) {
            log.error("创建融资申请失败: loanId={}", servicePeriodLoan.getLinkId(), e);
            result.put("success", false);
            result.put("message", "创建失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 同步服务周期贷款数据到融资申请
     *
     * @param servicePeriodLoan 服务周期贷款
     * @return 同步结果
     */
    @Transactional
    public Map<String, Object> syncLoanDataToFinancing(ServicePeriodLoan servicePeriodLoan) {
        log.info("同步贷款数据到融资申请: loanId={}", servicePeriodLoan.getLinkId());

        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 查找是否已有关联的融资申请（通过备注字段查找）
            String remarkPattern = "关联贷款ID: " + servicePeriodLoan.getLinkId();
            FinancingApplication queryParam = new FinancingApplication();
            queryParam.setRemark(remarkPattern);
            List<FinancingApplication> existingApplications = financingMapper.selectFinancingApplicationList(queryParam);

            FinancingApplication financing = null;
            if (!existingApplications.isEmpty()) {
                financing = existingApplications.get(0);
            }

            // 2. 如果没有融资申请，创建新的
            if (financing == null) {
                return createFinancingApplicationFromLoan(servicePeriodLoan);
            }

            // 3. 更新现有融资申请
            boolean needUpdate = false;

            // 更新金融机构信息
            if (!Objects.equals(financing.getFinancialInstitutionId(), servicePeriodLoan.getBankInstitutionId())) {
                financing.setFinancialInstitutionId(servicePeriodLoan.getBankInstitutionId());
                financing.setFinancialInstitutionName(servicePeriodLoan.getBankInstitutionName());
                needUpdate = true;
            }

            // 更新融资金额
            if (!Objects.equals(financing.getRequestedAmount(), servicePeriodLoan.getLoanAmount())) {
                financing.setRequestedAmount(servicePeriodLoan.getLoanAmount());
                needUpdate = true;
            }

            // 更新利率
            BigDecimal newInterestRate = servicePeriodLoan.getInterestRate() != null
                    ? new BigDecimal(servicePeriodLoan.getInterestRate().toString()) : null;
            if (!Objects.equals(financing.getInterestRate(), newInterestRate)) {
                financing.setInterestRate(newInterestRate);
                needUpdate = true;
            }

            // 更新融资期限
            Integer newFinancingTerm = servicePeriodLoan.getLoanTermMonths() != null
                    ? servicePeriodLoan.getLoanTermMonths() * 30 : null;
            if (!Objects.equals(financing.getFinancingTerm(), newFinancingTerm)) {
                financing.setFinancingTerm(newFinancingTerm);
                needUpdate = true;
            }

            // 更新状态
            String newFinancingStatus = convertLoanStatusToFinancingStatus(servicePeriodLoan.getLoanStatus());
            if (!Objects.equals(financing.getFinancingStatus(), newFinancingStatus)) {
                financing.setFinancingStatus(newFinancingStatus);
                needUpdate = true;
            }

            // 4. 如果有变更，执行更新
            if (needUpdate) {
                financing.setUpdateBy(SecurityUtils.getUsername());
                financing.setUpdateTime(DateUtils.getNowDate());

                int updateResult = financingMapper.updateFinancingApplication(financing);

                if (updateResult > 0) {
                    result.put("success", true);
                    result.put("message", "融资申请同步成功");
                    result.put("updated", true);

                    log.info("融资申请同步成功: financingId={}, loanId={}",
                            financing.getFinancingId(), servicePeriodLoan.getLinkId());
                } else {
                    result.put("success", false);
                    result.put("message", "融资申请同步失败");
                }
            } else {
                result.put("success", true);
                result.put("message", "融资申请无需更新");
                result.put("updated", false);
            }

        } catch (Exception e) {
            log.error("同步贷款数据到融资申请失败: loanId={}", servicePeriodLoan.getLinkId(), e);
            result.put("success", false);
            result.put("message", "同步失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 批量同步所有贷款数据到融资申请
     *
     * @return 同步结果
     */
    @Transactional
    public Map<String, Object> batchSyncAllLoansToFinancing() {
        log.info("批量同步所有贷款数据到融资申请");

        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 获取所有服务周期贷款
            List<ServicePeriodLoan> allLoans = servicePeriodLoanMapper.selectServicePeriodLoanList(new ServicePeriodLoan());

            int totalCount = allLoans.size();
            int successCount = 0;
            int failureCount = 0;
            List<String> errors = new ArrayList<>();

            // 2. 逐个同步
            for (ServicePeriodLoan loan : allLoans) {
                try {
                    Map<String, Object> syncResult = syncLoanDataToFinancing(loan);
                    if ((Boolean) syncResult.get("success")) {
                        successCount++;
                    } else {
                        failureCount++;
                        errors.add("贷款ID " + loan.getLinkId() + ": " + syncResult.get("message"));
                    }
                } catch (Exception e) {
                    failureCount++;
                    errors.add("贷款ID " + loan.getLinkId() + ": " + e.getMessage());
                    log.error("同步贷款失败: loanId={}", loan.getLinkId(), e);
                }
            }

            result.put("success", true);
            result.put("message", String.format("批量同步完成，总数: %d, 成功: %d, 失败: %d",
                    totalCount, successCount, failureCount));
            result.put("totalCount", totalCount);
            result.put("successCount", successCount);
            result.put("failureCount", failureCount);
            result.put("errors", errors);

            log.info("批量同步完成: 总数={}, 成功={}, 失败={}", totalCount, successCount, failureCount);

        } catch (Exception e) {
            log.error("批量同步失败", e);
            result.put("success", false);
            result.put("message", "批量同步失败: " + e.getMessage());
        }

        return result;
    }



    // ==================== 实现IFinancingService接口方法 ====================

    @Override
    @Transactional
    public boolean processApproval(Long applicationId, boolean approved, BigDecimal approvedAmount,
            Double interestRate, String approvalComments) {
        log.info("处理融资申请审批: applicationId={}, approved={}, approvedAmount={}, interestRate={}", 
                applicationId, approved, approvedAmount, interestRate);
        
        try {
            // 1. 查询融资申请
            FinancingApplication application = financingMapper.selectFinancingApplicationById(applicationId);
            if (application == null) {
                log.error("融资申请不存在: applicationId={}", applicationId);
                return false;
            }
            
            // 2. 检查申请状态是否可以审批
            String currentStatus = application.getFinancingStatus();
            if (!"PENDING".equals(currentStatus) && !"SUBMITTED".equals(currentStatus)) {
                log.error("融资申请状态不允许审批: applicationId={}, currentStatus={}", applicationId, currentStatus);
                return false;
            }
            
            // 3. 更新审批信息
            FinancingApplication updateApplication = new FinancingApplication();
            updateApplication.setFinancingId(applicationId);
            
            if (approved) {
                updateApplication.setFinancingStatus("APPROVED");
                updateApplication.setApprovedAmount(approvedAmount != null ? approvedAmount : application.getRequestedAmount());
                updateApplication.setInterestRate(interestRate != null ? new BigDecimal(interestRate.toString()) : application.getInterestRate());
            } else {
                updateApplication.setFinancingStatus("REJECTED");
                updateApplication.setApprovedAmount(BigDecimal.ZERO);
            }
            
            updateApplication.setApprovalOpinion(approvalComments);
            updateApplication.setApprovedTime(DateUtils.getNowDate());
            updateApplication.setApprovedBy(SecurityUtils.getUserId());
            updateApplication.setUpdateBy(SecurityUtils.getUsername());
            updateApplication.setUpdateTime(DateUtils.getNowDate());
            
            // 4. 执行更新
            int result = financingMapper.updateFinancingApplication(updateApplication);
            
            if (result > 0) {
                log.info("融资申请审批成功: applicationId={}, approved={}", applicationId, approved);
                return true;
            } else {
                log.error("融资申请审批失败: applicationId={}", applicationId);
                return false;
            }
            
        } catch (Exception e) {
            log.error("处理融资申请审批异常: applicationId={}", applicationId, e);
            return false;
        }
    }

    @Override
    public boolean recordApprovalResult(Long applicationId, Map<String, Object> approvalResult) {
        // 实现审批结果记录逻辑
        return false;
    }

    @Override
    public Double calculateInterestRate(Long creditId, Long financialInstitutionId, BigDecimal requestAmount) {
        // 实现利率计算逻辑
        return 0.05; // 默认5%
    }

    @Override
    public Map<String, Object> generateRiskAssessment(Long applicationId) {
        // 实现风险评估逻辑
        return new HashMap<>();
    }

    @Override
    public Map<String, Object> performCreditCheck(Long creditId, Long financialInstitutionId) {
        // 实现信用检查逻辑
        return new HashMap<>();
    }

    @Override
    public FinancingApplication selectFinancingApplicationById(Long applicationId) {
        // 验证访问权限
        if (!DepartmentContextHolder.isSuperAdmin()) {
            departmentPermissionValidator.validateDataAccess(applicationId, "dc_financing");
        }
        return financingMapper.selectFinancingApplicationById(applicationId);
    }

    @Override
    public List<FinancingApplication> selectFinancingApplicationList(FinancingApplication financingApplication) {
        // 应用部门过滤
        if (!DepartmentContextHolder.isSuperAdmin()) {
            Long currentDeptId = DepartmentContextHolder.getCurrentDeptId();
            if (currentDeptId != null) {
                financingApplication.setDeptId(currentDeptId);
            }
        }
        return financingMapper.selectFinancingApplicationList(financingApplication);
    }

    @Override
    public List<FinancingApplication> selectFinancingApplicationByCreditId(Long creditId) {
        // 验证债权访问权限
        if (!DepartmentContextHolder.isSuperAdmin()) {
            departmentPermissionValidator.validateDataAccess(creditId, "dc_credit");
        }
        return financingMapper.selectFinancingApplicationByCreditId(creditId);
    }

    @Override
    public List<FinancingApplication> selectPendingApplications() {
        // 应用部门过滤
        FinancingApplication queryParam = new FinancingApplication();
        if (!DepartmentContextHolder.isSuperAdmin()) {
            Long currentDeptId = DepartmentContextHolder.getCurrentDeptId();
            if (currentDeptId != null) {
                queryParam.setDeptId(currentDeptId);
            }
        }
        queryParam.setFinancingStatus("PENDING");
        return financingMapper.selectFinancingApplicationList(queryParam);
    }

    @Override
    public boolean updateApplicationStatus(Long applicationId, String status) {
        FinancingApplication financing = new FinancingApplication();
        financing.setFinancingId(applicationId);
        financing.setFinancingStatus(status);
        financing.setUpdateTime(DateUtils.getNowDate());
        return financingMapper.updateFinancingApplication(financing) > 0;
    }

    @Override
    public boolean validateCreditValidity(Long creditId) {
        try {
            DigitalCredit digitalCredit = digitalCreditMapper.selectDigitalCreditByCreditId(creditId);
            if (digitalCredit == null) {
                return false;
            }

            // 检查债权状态是否有效
            String status = digitalCredit.getCreditStatus();
            if (!"VALID".equals(status) && !"verified".equals(status)) {
                log.warn("债权状态无效: creditId={}, status={}", creditId, status);
                return false;
            }

            // 检查是否已过期
            Date maturityDate = digitalCredit.getMaturityDate();
            if (maturityDate != null && maturityDate.before(new Date())) {
                log.warn("债权已过期: creditId={}, maturityDate={}", creditId, maturityDate);
                return false;
            }

            return true;
        } catch (Exception e) {
            log.error("验证债权有效性失败: creditId={}", creditId, e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean disburseLoan(Long loanId, Long creditId, String disbursementAccount, String disbursementNote) {
        log.info("执行放款操作: loanId={}, creditId={}, disbursementAccount={}", loanId, creditId, disbursementAccount);
        
        try {
            // 1. 查找对应的融资申请
            List<FinancingApplication> applications = financingMapper.selectFinancingApplicationByCreditId(creditId);
            if (applications.isEmpty()) {
                log.error("未找到债权{}对应的融资申请", creditId);
                return false;
            }
            
            // 2. 找到状态为APPROVED的融资申请
            FinancingApplication targetApplication = null;
            for (FinancingApplication app : applications) {
                if ("APPROVED".equals(app.getFinancingStatus())) {
                    targetApplication = app;
                    break;
                }
            }
            
            if (targetApplication == null) {
                log.error("未找到状态为APPROVED的融资申请: creditId={}", creditId);
                return false;
            }
            
            // 3. 更新融资申请状态为DISBURSED
            FinancingApplication updateApplication = new FinancingApplication();
            updateApplication.setFinancingId(targetApplication.getFinancingId());
            updateApplication.setFinancingStatus("DISBURSED");
            updateApplication.setDisbursementAccount(disbursementAccount);
            updateApplication.setDisbursementNote(disbursementNote);
            updateApplication.setDisbursementTime(DateUtils.getNowDate());
            updateApplication.setUpdateBy(SecurityUtils.getUsername());
            updateApplication.setUpdateTime(DateUtils.getNowDate());
            
            int result = financingMapper.updateFinancingApplication(updateApplication);
            
            if (result > 0) {
                log.info("融资申请状态更新为DISBURSED成功: financingId={}, creditId={}", 
                        targetApplication.getFinancingId(), creditId);
                return true;
            } else {
                log.error("融资申请状态更新失败: financingId={}", targetApplication.getFinancingId());
                return false;
            }
            
        } catch (Exception e) {
            log.error("放款操作失败: loanId={}, creditId={}", loanId, creditId, e);
            return false;
        }
    }

    @Override
    public String generateApplicationNumber() {
        // 生成申请编号: FA + 年月日 + 6位序号
        String dateStr = DateUtils.dateTimeNow("yyyyMMdd");
        String sequence = String.format("%06d", System.currentTimeMillis() % 1000000);
        return "FA" + dateStr + sequence;
    }

    @Override
    public Map<String, Object> getFinancingStats() {
        log.info("获取融资统计信息");

        Map<String, Object> stats = new HashMap<>();

        try {
            // 1. 获取总申请数量
            FinancingApplication queryParam = new FinancingApplication();
            List<FinancingApplication> allApplications = financingMapper.selectFinancingApplicationList(queryParam);
            int totalApplications = allApplications.size();

            // 2. 按状态统计
            Map<String, Integer> statusStats = new HashMap<>();
            statusStats.put("PENDING", 0);
            statusStats.put("APPROVED", 0);
            statusStats.put("REJECTED", 0);
            statusStats.put("DISBURSED", 0);
            statusStats.put("SETTLED", 0);

            BigDecimal totalRequestedAmount = BigDecimal.ZERO;
            BigDecimal totalApprovedAmount = BigDecimal.ZERO;

            for (FinancingApplication app : allApplications) {
                String status = app.getFinancingStatus();
                if (status != null) {
                    statusStats.put(status, statusStats.getOrDefault(status, 0) + 1);
                }

                // 累计申请金额
                if (app.getRequestedAmount() != null) {
                    totalRequestedAmount = totalRequestedAmount.add(app.getRequestedAmount());
                }

                // 累计批准金额
                if ("APPROVED".equals(status) || "DISBURSED".equals(status) || "SETTLED".equals(status)) {
                    if (app.getApprovedAmount() != null) {
                        totalApprovedAmount = totalApprovedAmount.add(app.getApprovedAmount());
                    } else if (app.getRequestedAmount() != null) {
                        // 如果没有批准金额，使用申请金额
                        totalApprovedAmount = totalApprovedAmount.add(app.getRequestedAmount());
                    }
                }
            }

            // 3. 计算批准率
            double approvalRate = 0.0;
            int processedApplications = statusStats.get("APPROVED") + statusStats.get("REJECTED");
            if (processedApplications > 0) {
                approvalRate = (double) statusStats.get("APPROVED") / processedApplications * 100;
            }

            // 4. 按风险等级统计
            Map<String, Integer> riskStats = new HashMap<>();
            riskStats.put("LOW", 0);
            riskStats.put("MEDIUM", 0);
            riskStats.put("HIGH", 0);

            for (FinancingApplication app : allApplications) {
                String riskLevel = app.getRiskLevel();
                if (riskLevel != null) {
                    riskStats.put(riskLevel, riskStats.getOrDefault(riskLevel, 0) + 1);
                }
            }

            // 5. 组装统计结果
            stats.put("totalApplications", totalApplications);
            stats.put("statusStats", statusStats);
            stats.put("totalRequestedAmount", totalRequestedAmount);
            stats.put("totalApprovedAmount", totalApprovedAmount);
            stats.put("approvalRate", Math.round(approvalRate * 100.0) / 100.0); // 保留两位小数
            stats.put("riskStats", riskStats);

            // 6. 添加一些额外的统计信息
            stats.put("pendingApplications", statusStats.get("PENDING"));
            stats.put("approvedApplications", statusStats.get("APPROVED"));
            stats.put("rejectedApplications", statusStats.get("REJECTED"));
            stats.put("disbursedApplications", statusStats.get("DISBURSED"));
            stats.put("settledApplications", statusStats.get("SETTLED"));

            log.info("融资统计信息获取成功: 总申请数={}, 待审批={}, 已批准={}",
                    totalApplications, statusStats.get("PENDING"), statusStats.get("APPROVED"));

        } catch (Exception e) {
            log.error("获取融资统计信息失败", e);
            stats.put("error", "获取统计信息失败: " + e.getMessage());
        }

        return stats;
    }

    /**
     * 根据债权ID获取对应的关联ID
     *
     * @param creditId 债权ID
     * @return 关联ID，如果没有找到则返回null
     */
    @Override
    public Long getLoanIdByCreditId(Long creditId) {
        log.info("根据债权ID获取关联ID: creditId={}", creditId);
        
        try {
            // 获取债权对应的服务周期贷款列表
            List<ServicePeriodLoan> servicePeriodLoans = getServicePeriodLoansByCreditId(creditId);
            
            if (!servicePeriodLoans.isEmpty()) {
                // 返回第一个有效的关联ID
                for (ServicePeriodLoan loan : servicePeriodLoans) {
                    if (loan.getLinkId() != null) {
                        log.info("找到债权{}对应的关联ID: {}", creditId, loan.getLinkId());
                        return loan.getLinkId();
                    }
                }
            }
            
            log.warn("债权{}没有找到对应的关联ID", creditId);
            return null;
        } catch (Exception e) {
            log.error("根据债权ID获取关联ID失败: creditId={}", creditId, e);
            return null;
        }
    }

    /**
     * 检查债权是否可以创建新的融资申请
     *
     * @param creditId 债权ID
     * @return 检查结果
     */
    @Override
    public Map<String, Object> checkCreditEligibilityForNewApplication(Long creditId) {
        log.info("检查债权是否可以创建新融资申请: creditId={}", creditId);

        Map<String, Object> result = new HashMap<>();

        try {
            // 1. 检查债权是否存在
            log.debug("开始查询债权信息: creditId={}", creditId);
            DigitalCredit digitalCredit = digitalCreditMapper.selectDigitalCreditByCreditId(creditId);
            log.debug("债权查询结果: digitalCredit={}", digitalCredit != null ? digitalCredit.getCreditNumber() : "null");
            
            if (digitalCredit == null) {
                log.warn("债权不存在: creditId={}", creditId);
                result.put("eligible", false);
                result.put("reason", "债权不存在");
                return result;
            }
            
            log.info("找到债权: creditId={}, creditNumber={}, creditStatus={}", 
                creditId, digitalCredit.getCreditNumber(), digitalCredit.getCreditStatus());

            // 2. 检查对应的服务周期贷款状态
            log.debug("开始查询债权{}的服务周期贷款", creditId);
            List<ServicePeriodLoan> servicePeriodLoans = getServicePeriodLoansByCreditId(creditId);
            log.info("债权{}的服务周期贷款查询结果: 数量={}", creditId, servicePeriodLoans.size());
            
            if (servicePeriodLoans.isEmpty()) {
                log.warn("债权{}没有对应的服务周期贷款", creditId);
                result.put("eligible", false);
                result.put("reason", "债权没有对应的服务周期贷款");
                result.put("existingCount", 0);
                result.put("submittedLoanCount", 0);
                result.put("otherStatusLoanCount", 0);
                return result;
            }

            // 3. 分析服务周期贷款的状态
            int submittedLoanCount = 0;
            int otherStatusLoanCount = 0;
            List<Map<String, Object>> loanDetails = new ArrayList<>();

            for (ServicePeriodLoan loan : servicePeriodLoans) {
                String loanStatus = loan.getLoanStatus();
                Map<String, Object> loanDetail = new HashMap<>();
                loanDetail.put("loanId", loan.getLinkId());
                loanDetail.put("loanNumber", loan.getLoanNumber());
                loanDetail.put("loanStatus", loanStatus);
                loanDetail.put("loanAmount", loan.getLoanAmount());
                loanDetail.put("servicePeriodId", loan.getServicePeriodId());

                if ("SUBMITTED".equals(loanStatus)) {
                    submittedLoanCount++;
                    loanDetail.put("allowsNewApplication", true);
                } else {
                    otherStatusLoanCount++;
                    loanDetail.put("allowsNewApplication", false);
                }

                loanDetails.add(loanDetail);
            }

            // 4. 检查现有融资申请
            List<FinancingApplication> existingApplications = financingMapper.selectFinancingApplicationByCreditId(creditId);

            // 5. 决定是否可以创建新申请（需要有SUBMITTED状态的贷款且没有现有融资申请）
            boolean eligible = submittedLoanCount > 0 && existingApplications.isEmpty();

            result.put("eligible", eligible);
            result.put("existingApplicationCount", existingApplications.size());
            result.put("servicePeriodLoanCount", servicePeriodLoans.size());
            result.put("submittedLoanCount", submittedLoanCount);
            result.put("otherStatusLoanCount", otherStatusLoanCount);
            result.put("loanDetails", loanDetails);

            if (eligible) {
                result.put("reason", "存在SUBMITTED状态的服务周期贷款且无现有融资申请，可以创建新申请");
            } else if (submittedLoanCount == 0) {
                result.put("reason", "没有SUBMITTED状态的服务周期贷款，不能创建新申请");
            } else if (!existingApplications.isEmpty()) {
                result.put("reason", "已存在融资申请，不能创建新申请");
            }

            log.info("债权{}融资申请检查完成: 贷款总数={}, SUBMITTED贷款={}, 其他状态贷款={}, 现有申请={}, 可创建={}",
                    creditId, servicePeriodLoans.size(), submittedLoanCount, otherStatusLoanCount, existingApplications.size(), eligible);

        } catch (Exception e) {
            log.error("检查债权融资申请资格失败: creditId={}", creditId, e);
            result.put("eligible", false);
            result.put("reason", "检查失败: " + e.getMessage());
        }

        return result;
    }

    // ==================== 私有辅助方法 ====================
    /**
     * 将贷款状态转换为融资状态
     */
    private String convertLoanStatusToFinancingStatus(String loanStatus) {
        if (loanStatus == null) {
            return "PENDING";
        }

        switch (loanStatus) {
            case "PENDING":
                return "PENDING";
            case "SUBMITTED":
                return "PENDING";
            case "APPROVED":
                return "APPROVED";
            case "REJECTED":
                return "REJECTED";
            case "DISBURSED":
                return "DISBURSED";
            case "REPAID":
                return "SETTLED";
            default:
                return "PENDING";
        }
    }
}
