package com.ruoyi.credit.controller;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.credit.domain.FinancingApplication;
import com.ruoyi.credit.service.IFinancingService;

/**
 * 融资管理API控制器
 *
 * 提供融资申请、审批、风险评估等RESTful API接口
 *
 * @author ruoyi
 * @date 2025-12-19
 */
@RestController
@RequestMapping("/api/credit/financing")
public class FinancingApplicationController extends BaseController {

    @Autowired
    private IFinancingService financingService;

    /**
     * 审批融资申请
     *
     * @param id 申请ID
     * @param approvalData 审批数据，包含status、approvedAmount、interestRate、approvalNote等字段
     * @return 审批结果
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:approve')")
    @Log(title = "融资申请", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/approve")
    public AjaxResult approveFinancingApplication(
            @PathVariable("id") Long id,
            @RequestBody Map<String, Object> approvalData) {
        try {
            // 从请求体中提取参数
            String status = (String) approvalData.get("status");
            boolean approved = "APPROVED".equals(status);
            
            BigDecimal approvedAmount = null;
            if (approvalData.get("approvedAmount") != null) {
                approvedAmount = new BigDecimal(approvalData.get("approvedAmount").toString());
            }
            
            Double interestRate = null;
            if (approvalData.get("interestRate") != null) {
                interestRate = Double.valueOf(approvalData.get("interestRate").toString());
            }
            
            String approvalComments = (String) approvalData.get("approvalNote");
            
            boolean result = financingService.processApproval(id, approved, approvedAmount,
                    interestRate, approvalComments);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("审批融资申请失败", e);
            return error("审批融资申请失败: " + e.getMessage());
        }
    }

    /**
     * 获取融资统计信息
     *
     * @return 融资统计数据
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:query')")
    @GetMapping("/stats")
    public AjaxResult getFinancingStats() {
        try {
            Map<String, Object> stats = financingService.getFinancingStats();
            return success(stats);
        } catch (Exception e) {
            logger.error("获取融资统计失败", e);
            return error("获取融资统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取融资详情
     *
     * @param id 申请ID
     * @return 融资详情
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:query')")
    @GetMapping("/{id}")
    public AjaxResult getFinancingApplication(@PathVariable("id") Long id) {
        try {
            FinancingApplication application = financingService.selectFinancingApplicationById(id);
            if (application != null) {
                return success(application);
            } else {
                return error("融资申请不存在");
            }
        } catch (Exception e) {
            logger.error("查询融资申请失败", e);
            return error("查询融资申请失败: " + e.getMessage());
        }
    }

    /**
     * 查询融资申请列表
     *
     * @param financingApplication 查询条件
     * @return 申请列表
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:list')")
    @GetMapping
    public TableDataInfo getFinancingApplicationList(FinancingApplication financingApplication) {
        try {
            startPage();
            List<FinancingApplication> list = financingService.selectFinancingApplicationList(financingApplication);
            return getDataTable(list);
        } catch (Exception e) {
            logger.error("查询融资申请列表失败", e);
            return getDataTable(null);
        }
    }

    /**
     * 风险评估
     *
     * @param id 申请ID
     * @return 风险评估报告
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:assess')")
    @PostMapping("/{id}/risk-assess")
    public AjaxResult riskAssessment(@PathVariable("id") Long id) {
        try {
            Map<String, Object> assessment = financingService.generateRiskAssessment(id);
            return success(assessment);
        } catch (Exception e) {
            logger.error("风险评估失败", e);
            return error("风险评估失败: " + e.getMessage());
        }
    }

    /**
     * 获取利率信息
     *
     * @param creditId 债权ID
     * @param financialInstitutionId 金融机构ID
     * @param requestAmount 申请金额
     * @return 利率信息
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:query')")
    @GetMapping("/interest-rate")
    public AjaxResult getInterestRate(
            @RequestParam("creditId") Long creditId,
            @RequestParam("financialInstitutionId") Long financialInstitutionId,
            @RequestParam("requestAmount") BigDecimal requestAmount) {
        try {
            Double interestRate = financingService.calculateInterestRate(creditId, financialInstitutionId, requestAmount);
            return success(interestRate);
        } catch (Exception e) {
            logger.error("计算利率失败", e);
            return error("计算利率失败: " + e.getMessage());
        }
    }

    /**
     * 根据债权ID查询融资申请
     *
     * @param creditId 债权ID
     * @return 申请列表
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:list')")
    @GetMapping("/credit/{creditId}")
    public AjaxResult getFinancingApplicationsByCreditId(@PathVariable("creditId") Long creditId) {
        try {
            List<FinancingApplication> list = financingService.selectFinancingApplicationByCreditId(creditId);
            return success(list);
        } catch (Exception e) {
            logger.error("根据债权ID查询融资申请失败", e);
            return error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 查询待审批的申请
     *
     * @return 待审批申请列表
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:list')")
    @GetMapping("/pending")
    public AjaxResult getPendingApplications() {
        try {
            List<FinancingApplication> list = financingService.selectPendingApplications();
            return success(list);
        } catch (Exception e) {
            logger.error("查询待审批申请失败", e);
            return error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 更新申请状态
     *
     * @param id 申请ID
     * @param status 状态
     * @return 更新结果
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:edit')")
    @Log(title = "融资申请", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/status")
    public AjaxResult updateApplicationStatus(@PathVariable("id") Long id,
            @RequestParam("status") String status) {
        try {
            boolean result = financingService.updateApplicationStatus(id, status);
            return toAjax(result);
        } catch (Exception e) {
            logger.error("更新申请状态失败", e);
            return error("更新申请状态失败: " + e.getMessage());
        }
    }

    /**
     * 信用检查
     *
     * @param creditId 债权ID
     * @param financialInstitutionId 金融机构ID
     * @return 信用检查结果
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:assess')")
    @PostMapping("/credit-check")
    public AjaxResult performCreditCheck(
            @RequestParam("creditId") Long creditId,
            @RequestParam("financialInstitutionId") Long financialInstitutionId) {
        try {
            Map<String, Object> result = financingService.performCreditCheck(creditId, financialInstitutionId);
            return success(result);
        } catch (Exception e) {
            logger.error("信用检查失败", e);
            return error("信用检查失败: " + e.getMessage());
        }
    }

    /**
     * 放款操作 (通过ID)
     *
     * @param id 融资申请ID
     * @param disburseData 放款数据
     * @return 放款结果
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:disburse')")
    @Log(title = "贷款放款", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/disburse")
    public AjaxResult disburseLoanById(@PathVariable("id") Long id, @RequestBody Map<String, Object> disburseData) {
        try {
            logger.info("收到放款请求: id={}, data={}", id, disburseData);

            // 从路径参数获取融资申请ID
            Long financingId = id;
            
            // 从请求体获取其他参数
            Long loanId = disburseData.get("loanId") != null ? Long.valueOf(disburseData.get("loanId").toString()) : null;
            Long creditId = disburseData.get("creditId") != null ? Long.valueOf(disburseData.get("creditId").toString()) : null;
            String disbursementAccount = (String) disburseData.get("disbursementAccount");
            String disbursementNote = (String) disburseData.get("disbursementNote");

            logger.info("解析放款参数: financingId={}, loanId={}, creditId={}, disbursementAccount={}, disbursementNote={}",
                    financingId, loanId, creditId, disbursementAccount, disbursementNote);

            // 验证必填参数
            if (financingId == null || creditId == null || disbursementAccount == null || disbursementAccount.trim().isEmpty()) {
                logger.error("放款参数不完整: financingId={}, creditId={}, disbursementAccount={}",
                        financingId, creditId, disbursementAccount);
                return error("放款参数不完整");
            }

            // 如果没有提供loanId，通过creditId获取对应的linkId
            if (loanId == null) {
                try {
                    loanId = financingService.getLoanIdByCreditId(creditId);
                    if (loanId != null) {
                        logger.info("通过creditId={}获取到linkId={}", creditId, loanId);
                    }
                } catch (Exception e) {
                    logger.error("通过creditId获取linkId失败: creditId={}", creditId, e);
                    loanId = financingId;
                }
            }

            // 执行放款操作
            boolean result = financingService.disburseLoan(loanId, creditId, disbursementAccount, disbursementNote);

            if (result) {
                logger.info("放款操作成功: financingId={}, loanId={}, creditId={}", financingId, loanId, creditId);
                return success("放款成功，融资申请状态已更新为DISBURSED");
            } else {
                logger.error("放款操作失败: financingId={}, loanId={}, creditId={}", financingId, loanId, creditId);
                return error("放款失败，请检查债权状态和融资申请状态");
            }
        } catch (NumberFormatException e) {
            logger.error("放款参数格式错误", e);
            return error("放款参数格式错误: " + e.getMessage());
        } catch (Exception e) {
            logger.error("放款操作异常", e);
            return error("放款操作失败: " + e.getMessage());
        }
    }

    /**
     * 放款操作 (原有方法，保持兼容性)
     *
     * @param disburseData 放款数据
     * @return 放款结果
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:disburse')")
    @Log(title = "贷款放款", businessType = BusinessType.UPDATE)
    @PostMapping("/disburse")
    public AjaxResult disburseLoan(@RequestBody Map<String, Object> disburseData) {
        try {
            logger.info("收到放款请求: {}", disburseData);

            Long loanId = Long.valueOf(disburseData.get("loanId").toString());
            Long creditId = Long.valueOf(disburseData.get("creditId").toString());
            String disbursementAccount = (String) disburseData.get("disbursementAccount");
            String disbursementNote = (String) disburseData.get("disbursementNote");

            logger.info("解析放款参数: loanId={}, creditId={}, disbursementAccount={}, disbursementNote={}",
                    loanId, creditId, disbursementAccount, disbursementNote);

            // 验证必填参数
            if (loanId == null || creditId == null || disbursementAccount == null || disbursementAccount.trim().isEmpty()) {
                logger.error("放款参数不完整: loanId={}, creditId={}, disbursementAccount={}",
                        loanId, creditId, disbursementAccount);
                return error("放款参数不完整");
            }

            // 执行放款操作
            boolean result = financingService.disburseLoan(loanId, creditId, disbursementAccount, disbursementNote);

            if (result) {
                logger.info("放款操作成功: loanId={}, creditId={}", loanId, creditId);
                return success("放款成功，融资申请状态已更新为DISBURSED");
            } else {
                logger.error("放款操作失败: loanId={}, creditId={}", loanId, creditId);
                return error("放款失败，请检查债权状态和融资申请状态");
            }
        } catch (NumberFormatException e) {
            logger.error("放款参数格式错误", e);
            return error("放款参数格式错误: " + e.getMessage());
        } catch (Exception e) {
            logger.error("放款操作异常", e);
            return error("放款操作失败: " + e.getMessage());
        }
    }

    /**
     * 导出融资申请数据
     *
     * @param response HTTP响应
     * @param financingApplication 查询条件
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:export')")
    @Log(title = "融资申请", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, FinancingApplication financingApplication) {
        try {
            List<FinancingApplication> list = financingService.selectFinancingApplicationList(financingApplication);
            ExcelUtil<FinancingApplication> util = new ExcelUtil<FinancingApplication>(FinancingApplication.class);
            util.exportExcel(response, list, "融资申请数据");
        } catch (Exception e) {
            logger.error("导出融资申请数据失败", e);
        }
    }

    /**
     * 检查债权是否可以创建新的融资申请
     *
     * @param creditId 债权ID
     * @return 检查结果
     */
    @PreAuthorize("@ss.hasPermi('credit:financing:query')")
    @GetMapping("/check-eligibility/{creditId}")
    public AjaxResult checkCreditEligibilityForNewApplication(@PathVariable("creditId") Long creditId) {
        try {
            Map<String, Object> result = financingService.checkCreditEligibilityForNewApplication(creditId);
            return success(result);
        } catch (Exception e) {
            logger.error("检查债权融资申请资格失败", e);
            return error("检查失败: " + e.getMessage());
        }
    }
}
