package com.ruoyi.security.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
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.security.domain.DataConsistencyCheck;
import com.ruoyi.security.domain.RiskEvent;
import com.ruoyi.security.domain.RiskEventTracking;
import com.ruoyi.security.service.IRiskMonitorService;

/**
 * 风险监控Controller
 * 
 * @author ruoyi
 * @date 2025-12-22
 */
@RestController
@RequestMapping("/security/risk")
public class RiskMonitorController extends BaseController
{
    @Autowired
    private IRiskMonitorService riskMonitorService;

    /**
     * 检查合同金额一致性
     */
    @PreAuthorize("@ss.hasPermi('security:risk:check')")
    @Log(title = "合同金额一致性检查", businessType = BusinessType.OTHER)
    @PostMapping("/check-contract-amount")
    public AjaxResult checkContractAmount(@RequestBody ContractAmountCheckRequest request)
    {
        DataConsistencyCheck result = riskMonitorService.checkContractAmountConsistency(
            request.getContractId(), request.getServiceConfirmationId());
        return success(result);
    }

    /**
     * 检查发票金额一致性
     */
    @PreAuthorize("@ss.hasPermi('security:risk:check')")
    @Log(title = "发票金额一致性检查", businessType = BusinessType.OTHER)
    @PostMapping("/check-invoice-amount")
    public AjaxResult checkInvoiceAmount(@RequestBody InvoiceAmountCheckRequest request)
    {
        DataConsistencyCheck result = riskMonitorService.checkInvoiceAmountConsistency(
            request.getServiceConfirmationId(), request.getInvoiceId());
        return success(result);
    }

    /**
     * 验证主体信息
     */
    @PreAuthorize("@ss.hasPermi('security:risk:check')")
    @Log(title = "主体信息验证", businessType = BusinessType.OTHER)
    @PostMapping("/validate-party-info")
    public AjaxResult validatePartyInfo(@RequestBody PartyInfoValidationRequest request)
    {
        DataConsistencyCheck result = riskMonitorService.validatePartyInformation(
            request.getInvoiceParty(), request.getContractParty());
        return success(result);
    }

    /**
     * 检查服务期限一致性
     */
    @PreAuthorize("@ss.hasPermi('security:risk:check')")
    @Log(title = "服务期限一致性检查", businessType = BusinessType.OTHER)
    @PostMapping("/check-service-period")
    public AjaxResult checkServicePeriod(@RequestBody ServicePeriodCheckRequest request)
    {
        DataConsistencyCheck result = riskMonitorService.checkServicePeriodConsistency(
            request.getContractId(), request.getActualServicePeriods());
        return success(result);
    }

    /**
     * 验证融资数据一致性
     */
    @PreAuthorize("@ss.hasPermi('security:risk:check')")
    @Log(title = "融资数据一致性验证", businessType = BusinessType.OTHER)
    @PostMapping("/validate-financing-data")
    public AjaxResult validateFinancingData(@RequestBody FinancingDataValidationRequest request)
    {
        DataConsistencyCheck result = riskMonitorService.validateFinancingDataConsistency(request.getApplicationId());
        return success(result);
    }

    /**
     * 获取风险评估报告
     */
    @PreAuthorize("@ss.hasPermi('security:risk:view')")
    @GetMapping("/assessment/{applicationId}")
    public AjaxResult getRiskAssessment(@PathVariable("applicationId") Long applicationId)
    {
        String report = riskMonitorService.generateRiskAssessmentReport(applicationId);
        return success(report);
    }

    /**
     * 记录数据异常
     */
    @PreAuthorize("@ss.hasPermi('security:risk:add')")
    @Log(title = "记录数据异常", businessType = BusinessType.INSERT)
    @PostMapping("/record-anomaly")
    public AjaxResult recordAnomaly(@RequestBody DataAnomalyRequest request)
    {
        RiskEvent result = riskMonitorService.recordDataAnomaly(request.getAnomalyInfo());
        return success(result);
    }

    /**
     * 创建风险事件跟踪
     */
    @PreAuthorize("@ss.hasPermi('security:risk:add')")
    @Log(title = "创建风险事件跟踪", businessType = BusinessType.INSERT)
    @PostMapping("/create-tracking")
    public AjaxResult createTracking(@RequestBody RiskTrackingRequest request)
    {
        RiskEventTracking result = riskMonitorService.createRiskEventTracking(request.getRiskEventId());
        return success(result);
    }

    /**
     * 发送风险提示
     */
    @PreAuthorize("@ss.hasPermi('security:risk:alert')")
    @Log(title = "发送风险提示", businessType = BusinessType.OTHER)
    @PostMapping("/send-alert")
    public AjaxResult sendAlert(@RequestBody RiskAlertRequest request)
    {
        // 首先获取风险事件
        List<RiskEvent> events = riskMonitorService.selectRiskEventList(new RiskEvent());
        RiskEvent riskEvent = events.stream()
            .filter(e -> e.getEventId().equals(request.getRiskEventId()))
            .findFirst()
            .orElse(null);
            
        if (riskEvent == null) {
            return error("风险事件不存在");
        }
        
        boolean result = riskMonitorService.sendRiskAlert(riskEvent, request.getUserRole());
        return success(result);
    }

    /**
     * 数据修正后重新验证
     */
    @PreAuthorize("@ss.hasPermi('security:risk:check')")
    @Log(title = "重新验证", businessType = BusinessType.OTHER)
    @PostMapping("/revalidate")
    public AjaxResult revalidate(@RequestBody RevalidationRequest request)
    {
        DataConsistencyCheck result = riskMonitorService.revalidateAfterCorrection(
            request.getDataId(), request.getCorrectionInfo());
        return success(result);
    }

    /**
     * 更新风险状态
     */
    @PreAuthorize("@ss.hasPermi('security:risk:edit')")
    @Log(title = "更新风险状态", businessType = BusinessType.UPDATE)
    @PutMapping("/events/{eventId}/status")
    public AjaxResult updateRiskStatus(@PathVariable("eventId") Long eventId, @RequestBody RiskStatusUpdateRequest request)
    {
        boolean result = riskMonitorService.updateRiskStatus(eventId, request.getNewStatus());
        return success(result);
    }

    /**
     * 查询风险事件列表
     */
    @PreAuthorize("@ss.hasPermi('security:risk:list')")
    @GetMapping("/events")
    public TableDataInfo getRiskEventList(RiskEvent riskEvent)
    {
        startPage();
        List<RiskEvent> list = riskMonitorService.selectRiskEventList(riskEvent);
        return getDataTable(list);
    }

    /**
     * 查询风险事件跟踪列表
     */
    @PreAuthorize("@ss.hasPermi('security:risk:list')")
    @GetMapping("/events/{eventId}/tracking")
    public TableDataInfo getRiskEventTrackingList(@PathVariable("eventId") Long eventId)
    {
        startPage();
        List<RiskEventTracking> list = riskMonitorService.selectRiskEventTrackingList(eventId);
        return getDataTable(list);
    }

    /**
     * 查询数据一致性检查记录列表
     */
    @PreAuthorize("@ss.hasPermi('security:risk:list')")
    @GetMapping("/consistency-checks")
    public TableDataInfo getDataConsistencyCheckList(DataConsistencyCheck dataConsistencyCheck)
    {
        startPage();
        List<DataConsistencyCheck> list = riskMonitorService.selectDataConsistencyCheckList(dataConsistencyCheck);
        return getDataTable(list);
    }

    /**
     * 导出风险事件列表
     */
    @PreAuthorize("@ss.hasPermi('security:risk:export')")
    @Log(title = "风险事件", businessType = BusinessType.EXPORT)
    @PostMapping("/events/export")
    public void exportRiskEvents(HttpServletResponse response, RiskEvent riskEvent)
    {
        List<RiskEvent> list = riskMonitorService.selectRiskEventList(riskEvent);
        ExcelUtil<RiskEvent> util = new ExcelUtil<RiskEvent>(RiskEvent.class);
        util.exportExcel(response, list, "风险事件数据");
    }

    // 内部请求类

    public static class ContractAmountCheckRequest {
        private Long contractId;
        private Long serviceConfirmationId;

        public Long getContractId() { return contractId; }
        public void setContractId(Long contractId) { this.contractId = contractId; }
        public Long getServiceConfirmationId() { return serviceConfirmationId; }
        public void setServiceConfirmationId(Long serviceConfirmationId) { this.serviceConfirmationId = serviceConfirmationId; }
    }

    public static class InvoiceAmountCheckRequest {
        private Long serviceConfirmationId;
        private Long invoiceId;

        public Long getServiceConfirmationId() { return serviceConfirmationId; }
        public void setServiceConfirmationId(Long serviceConfirmationId) { this.serviceConfirmationId = serviceConfirmationId; }
        public Long getInvoiceId() { return invoiceId; }
        public void setInvoiceId(Long invoiceId) { this.invoiceId = invoiceId; }
    }

    public static class PartyInfoValidationRequest {
        private String invoiceParty;
        private String contractParty;

        public String getInvoiceParty() { return invoiceParty; }
        public void setInvoiceParty(String invoiceParty) { this.invoiceParty = invoiceParty; }
        public String getContractParty() { return contractParty; }
        public void setContractParty(String contractParty) { this.contractParty = contractParty; }
    }

    public static class ServicePeriodCheckRequest {
        private Long contractId;
        private String actualServicePeriods;

        public Long getContractId() { return contractId; }
        public void setContractId(Long contractId) { this.contractId = contractId; }
        public String getActualServicePeriods() { return actualServicePeriods; }
        public void setActualServicePeriods(String actualServicePeriods) { this.actualServicePeriods = actualServicePeriods; }
    }

    public static class FinancingDataValidationRequest {
        private Long applicationId;

        public Long getApplicationId() { return applicationId; }
        public void setApplicationId(Long applicationId) { this.applicationId = applicationId; }
    }

    public static class DataAnomalyRequest {
        private String anomalyInfo;

        public String getAnomalyInfo() { return anomalyInfo; }
        public void setAnomalyInfo(String anomalyInfo) { this.anomalyInfo = anomalyInfo; }
    }

    public static class RiskTrackingRequest {
        private Long riskEventId;

        public Long getRiskEventId() { return riskEventId; }
        public void setRiskEventId(Long riskEventId) { this.riskEventId = riskEventId; }
    }

    public static class RiskAlertRequest {
        private Long riskEventId;
        private String userRole;

        public Long getRiskEventId() { return riskEventId; }
        public void setRiskEventId(Long riskEventId) { this.riskEventId = riskEventId; }
        public String getUserRole() { return userRole; }
        public void setUserRole(String userRole) { this.userRole = userRole; }
    }

    public static class RevalidationRequest {
        private Long dataId;
        private String correctionInfo;

        public Long getDataId() { return dataId; }
        public void setDataId(Long dataId) { this.dataId = dataId; }
        public String getCorrectionInfo() { return correctionInfo; }
        public void setCorrectionInfo(String correctionInfo) { this.correctionInfo = correctionInfo; }
    }

    public static class RiskStatusUpdateRequest {
        private String newStatus;

        public String getNewStatus() { return newStatus; }
        public void setNewStatus(String newStatus) { this.newStatus = newStatus; }
    }
}