package com.ruoyi.credit.domain;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

/**
 * 数据差异模型
 * 
 * @author ruoyi
 * @date 2025-12-25
 */
public class DataDifference
{
    /** 银行ID */
    private Long bankId;
    
    /** 银行名称 */
    private String bankName;
    
    /** 字段名称 */
    private String fieldName;
    
    /** 字段显示名称 */
    private String fieldDisplayName;
    
    /** 银行管理界面值 */
    private Object managementValue;
    
    /** 服务周期贷款系统值 */
    private Object loanSystemValue;
    
    /** 差异类型 */
    private String differenceType;
    
    /** 差异描述 */
    private String description;
    
    /** 严重程度 */
    private String severity;

    /** 差异类型常量 */
    public static final String TYPE_VALUE_DIFFERENT = "VALUE_DIFFERENT";
    public static final String TYPE_MISSING_IN_MANAGEMENT = "MISSING_IN_MANAGEMENT";
    public static final String TYPE_MISSING_IN_LOAN_SYSTEM = "MISSING_IN_LOAN_SYSTEM";
    public static final String TYPE_FORMAT_DIFFERENT = "FORMAT_DIFFERENT";
    
    /** 严重程度常量 */
    public static final String SEVERITY_HIGH = "HIGH";
    public static final String SEVERITY_MEDIUM = "MEDIUM";
    public static final String SEVERITY_LOW = "LOW";

    public DataDifference() {
    }

    public DataDifference(Long bankId, String bankName, String fieldName, 
                         Object managementValue, Object loanSystemValue, String differenceType) {
        this.bankId = bankId;
        this.bankName = bankName;
        this.fieldName = fieldName;
        this.managementValue = managementValue;
        this.loanSystemValue = loanSystemValue;
        this.differenceType = differenceType;
        this.severity = determineSeverity(fieldName, differenceType);
        this.description = generateDescription();
    }

    /**
     * 创建值不同的差异
     */
    public static DataDifference createValueDifference(Long bankId, String bankName, String fieldName,
                                                      Object managementValue, Object loanSystemValue) {
        return new DataDifference(bankId, bankName, fieldName, managementValue, loanSystemValue, TYPE_VALUE_DIFFERENT);
    }

    /**
     * 创建银行管理界面缺失的差异
     */
    public static DataDifference createMissingInManagement(Long bankId, String bankName, String fieldName,
                                                          Object loanSystemValue) {
        return new DataDifference(bankId, bankName, fieldName, null, loanSystemValue, TYPE_MISSING_IN_MANAGEMENT);
    }

    /**
     * 创建服务周期贷款系统缺失的差异
     */
    public static DataDifference createMissingInLoanSystem(Long bankId, String bankName, String fieldName,
                                                          Object managementValue) {
        return new DataDifference(bankId, bankName, fieldName, managementValue, null, TYPE_MISSING_IN_LOAN_SYSTEM);
    }

    /**
     * 根据字段名和差异类型确定严重程度
     */
    private String determineSeverity(String fieldName, String differenceType) {
        if (fieldName == null) {
            return SEVERITY_LOW;
        }
        
        // 关键字段差异为高严重程度
        if (fieldName.equals("bankName") || fieldName.equals("status") || 
            fieldName.equals("cooperationStatus") || fieldName.equals("interestRate")) {
            return SEVERITY_HIGH;
        }
        
        // 金额和期限字段为中等严重程度
        if (fieldName.contains("Amount") || fieldName.contains("Term") || 
            fieldName.equals("baseInterestRate")) {
            return SEVERITY_MEDIUM;
        }
        
        // 其他字段为低严重程度
        return SEVERITY_LOW;
    }

    /**
     * 生成差异描述
     */
    private String generateDescription() {
        if (bankName == null || fieldName == null || differenceType == null) {
            return "数据差异";
        }
        
        String fieldDisplay = getFieldDisplayName() != null ? getFieldDisplayName() : fieldName;
        
        switch (differenceType) {
            case TYPE_VALUE_DIFFERENT:
                return String.format("银行[%s]的%s不一致：管理界面为[%s]，贷款系统为[%s]", 
                                   bankName, fieldDisplay, managementValue, loanSystemValue);
            case TYPE_MISSING_IN_MANAGEMENT:
                return String.format("银行[%s]的%s在管理界面中缺失，贷款系统值为[%s]", 
                                   bankName, fieldDisplay, loanSystemValue);
            case TYPE_MISSING_IN_LOAN_SYSTEM:
                return String.format("银行[%s]的%s在贷款系统中缺失，管理界面值为[%s]", 
                                   bankName, fieldDisplay, managementValue);
            case TYPE_FORMAT_DIFFERENT:
                return String.format("银行[%s]的%s格式不一致：管理界面为[%s]，贷款系统为[%s]", 
                                   bankName, fieldDisplay, managementValue, loanSystemValue);
            default:
                return String.format("银行[%s]的%s存在未知差异", bankName, fieldDisplay);
        }
    }

    /**
     * 获取字段显示名称
     */
    public String getFieldDisplayName() {
        if (fieldDisplayName != null) {
            return fieldDisplayName;
        }
        
        // 根据字段名返回中文显示名称
        switch (fieldName != null ? fieldName : "") {
            case "bankName": return "银行名称";
            case "bankCode": return "银行编码";
            case "bankType": return "银行类型";
            case "status": return "银行状态";
            case "cooperationStatus": return "合作状态";
            case "baseInterestRate": return "基准利率";
            case "interestRate": return "利率";
            case "minLoanAmount": return "最低贷款金额";
            case "maxLoanAmount": return "最高贷款金额";
            case "minLoanTermMonths": return "最短期限";
            case "maxLoanTermMonths": return "最长期限";
            case "productName": return "产品名称";
            case "termMatch": return "期限匹配度";
            default: return fieldName;
        }
    }

    /**
     * 是否为高严重程度差异
     */
    public boolean isHighSeverity() {
        return SEVERITY_HIGH.equals(severity);
    }

    /**
     * 是否为关键字段差异
     */
    public boolean isCriticalField() {
        return isHighSeverity();
    }

    // Getters and Setters
    public Long getBankId() {
        return bankId;
    }

    public void setBankId(Long bankId) {
        this.bankId = bankId;
    }

    public String getBankName() {
        return bankName;
    }

    public void setBankName(String bankName) {
        this.bankName = bankName;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public void setFieldDisplayName(String fieldDisplayName) {
        this.fieldDisplayName = fieldDisplayName;
    }

    public Object getManagementValue() {
        return managementValue;
    }

    public void setManagementValue(Object managementValue) {
        this.managementValue = managementValue;
    }

    public Object getLoanSystemValue() {
        return loanSystemValue;
    }

    public void setLoanSystemValue(Object loanSystemValue) {
        this.loanSystemValue = loanSystemValue;
    }

    public String getDifferenceType() {
        return differenceType;
    }

    public void setDifferenceType(String differenceType) {
        this.differenceType = differenceType;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getSeverity() {
        return severity;
    }

    public void setSeverity(String severity) {
        this.severity = severity;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
            .append("bankId", getBankId())
            .append("bankName", getBankName())
            .append("fieldName", getFieldName())
            .append("fieldDisplayName", getFieldDisplayName())
            .append("managementValue", getManagementValue())
            .append("loanSystemValue", getLoanSystemValue())
            .append("differenceType", getDifferenceType())
            .append("description", getDescription())
            .append("severity", getSeverity())
            .toString();
    }
}