package com.ruoyi.credit.domain;

import java.util.Date;

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

import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.credit.annotation.EncryptedField;

/**
 * 银行机构对象 dc_bank_institution
 * 
 * @author ruoyi
 * @date 2025-12-24
 */
public class BankInstitution extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 银行ID */
    private Long bankId;

    /** 银行编码 */
    @Excel(name = "银行编码")
    private String bankCode;

    /** 银行名称 */
    @Excel(name = "银行名称")
    private String bankName;

    /** 银行类型 */
    @Excel(name = "银行类型")
    private String bankType;

    /** 联系人 */
    @Excel(name = "联系人")
    private String contactPerson;

    /** 联系电话(加密) */
    @Excel(name = "联系电话")
    @EncryptedField(algorithm = "AES-256-GCM")
    private String contactPhone;

    /** 联系邮箱(加密) */
    @Excel(name = "联系邮箱")
    @EncryptedField(algorithm = "AES-256-GCM")
    private String contactEmail;

    /** 银行地址 */
    @Excel(name = "银行地址")
    private String bankAddress;

    /** 产品名称 */
    @Excel(name = "产品名称")
    private String productName;

    /** 产品利率 */
    @Excel(name = "产品利率")
    private Double productInterestRate;

    /** 产品期限(月) */
    @Excel(name = "产品期限(月)")
    private Integer productTermMonths;

    /** 创建者账号类型 */
    @Excel(name = "创建者账号类型")
    private String creatorAccountType;

    /** 基准利率 */
    @Excel(name = "基准利率")
    private Double baseInterestRate;

    /** 最低贷款金额(加密) */
    @Excel(name = "最低贷款金额")
    @EncryptedField(algorithm = "AES-256-GCM")
    private String minLoanAmount;

    /** 最高贷款金额(加密) */
    @Excel(name = "最高贷款金额")
    @EncryptedField(algorithm = "AES-256-GCM")
    private String maxLoanAmount;

    /** 最短贷款期限(月) */
    @Excel(name = "最短贷款期限(月)")
    private Integer minLoanTermMonths;

    /** 最长贷款期限(月) */
    @Excel(name = "最长贷款期限(月)")
    private Integer maxLoanTermMonths;

    /** 风险评级 */
    @Excel(name = "风险评级")
    private String riskRating;

    /** 合作状态 */
    @Excel(name = "合作状态")
    private String cooperationStatus;

    /** 合作开始日期 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "合作开始日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date cooperationStartDate;

    /** 合作结束日期 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "合作结束日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date cooperationEndDate;

    /** 银行状态 */
    @Excel(name = "银行状态")
    private String status;

    /** 备注信息 */
    @Excel(name = "备注信息")
    private String remarks;

    /** 部门ID */
    @Excel(name = "部门ID")
    private Long deptId;

    // 银行类型常量
    public static final String TYPE_COMMERCIAL = "COMMERCIAL";
    public static final String TYPE_POLICY = "POLICY";
    public static final String TYPE_COOPERATIVE = "COOPERATIVE";
    public static final String TYPE_FOREIGN = "FOREIGN";
    public static final String TYPE_CITY_COMMERCIAL = "CITY_COMMERCIAL";

    // 合作状态常量
    public static final String COOPERATION_ACTIVE = "ACTIVE";
    public static final String COOPERATION_SUSPENDED = "SUSPENDED";
    public static final String COOPERATION_TERMINATED = "TERMINATED";

    // 风险评级常量
    public static final String RISK_AAA = "AAA";
    public static final String RISK_AA = "AA";
    public static final String RISK_A = "A";
    public static final String RISK_BBB = "BBB";
    public static final String RISK_BB = "BB";
    public static final String RISK_B = "B";

    // 创建者账号类型常量
    public static final String CREATOR_FINANCIAL_COMPANY = "FINANCIAL_COMPANY";
    public static final String CREATOR_SYSTEM = "SYSTEM";

    // 状态常量
    public static final String STATUS_ACTIVE = "0";
    public static final String STATUS_INACTIVE = "1";

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

    public Long getBankId() 
    {
        return bankId;
    }

    public void setBankCode(String bankCode) 
    {
        this.bankCode = bankCode;
    }

    public String getBankCode() 
    {
        return bankCode;
    }

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

    public String getBankName() 
    {
        return bankName;
    }

    public void setBankType(String bankType) 
    {
        this.bankType = bankType;
    }

    public String getBankType() 
    {
        return bankType;
    }

    public void setContactPerson(String contactPerson) 
    {
        this.contactPerson = contactPerson;
    }

    public String getContactPerson() 
    {
        return contactPerson;
    }

    public void setContactPhone(String contactPhone) 
    {
        this.contactPhone = contactPhone;
    }

    public String getContactPhone() 
    {
        return contactPhone;
    }

    public void setContactEmail(String contactEmail) 
    {
        this.contactEmail = contactEmail;
    }

    public String getContactEmail() 
    {
        return contactEmail;
    }

    public void setBankAddress(String bankAddress) 
    {
        this.bankAddress = bankAddress;
    }

    public String getBankAddress() 
    {
        return bankAddress;
    }

    public void setProductName(String productName) 
    {
        this.productName = productName;
    }

    public String getProductName() 
    {
        return productName;
    }

    public void setProductInterestRate(Double productInterestRate) 
    {
        this.productInterestRate = productInterestRate;
    }

    public Double getProductInterestRate() 
    {
        return productInterestRate;
    }

    public void setProductTermMonths(Integer productTermMonths) 
    {
        this.productTermMonths = productTermMonths;
    }

    public Integer getProductTermMonths() 
    {
        return productTermMonths;
    }

    public void setCreatorAccountType(String creatorAccountType) 
    {
        this.creatorAccountType = creatorAccountType;
    }

    public String getCreatorAccountType() 
    {
        return creatorAccountType;
    }

    public void setBaseInterestRate(Double baseInterestRate) 
    {
        this.baseInterestRate = baseInterestRate;
    }

    public Double getBaseInterestRate() 
    {
        return baseInterestRate;
    }

    public void setMinLoanAmount(String minLoanAmount) 
    {
        this.minLoanAmount = minLoanAmount;
    }

    public String getMinLoanAmount() 
    {
        return minLoanAmount;
    }

    public void setMaxLoanAmount(String maxLoanAmount) 
    {
        this.maxLoanAmount = maxLoanAmount;
    }

    public String getMaxLoanAmount() 
    {
        return maxLoanAmount;
    }

    // Helper methods for handling encrypted decimal values
    public java.math.BigDecimal getMinLoanAmountDecimal() {
        if (minLoanAmount == null || minLoanAmount.isEmpty()) {
            return null;
        }
        try {
            // If it's already a plain number, parse it directly
            return new java.math.BigDecimal(minLoanAmount);
        } catch (NumberFormatException e) {
            // If it's encrypted, try to decrypt first
            // For now, return default values based on bank type to avoid null pointer exceptions
            if (minLoanAmount.startsWith("encrypted_")) {
                // Return reasonable default minimum amounts based on bank data
                return new java.math.BigDecimal("10000"); // Default minimum 10,000
            }
            return null;
        }
    }

    public void setMinLoanAmountDecimal(java.math.BigDecimal amount) {
        if (amount == null) {
            this.minLoanAmount = null;
        } else {
            // For now, store as plain text
            // TODO: Implement proper encryption
            this.minLoanAmount = amount.toString();
        }
    }

    public java.math.BigDecimal getMaxLoanAmountDecimal() {
        if (maxLoanAmount == null || maxLoanAmount.isEmpty()) {
            return null;
        }
        try {
            // If it's already a plain number, parse it directly
            return new java.math.BigDecimal(maxLoanAmount);
        } catch (NumberFormatException e) {
            // If it's encrypted, try to decrypt first
            // For now, return default values based on bank type to avoid null pointer exceptions
            if (maxLoanAmount.startsWith("encrypted_")) {
                // Return reasonable default maximum amounts based on bank data
                return new java.math.BigDecimal("5000000"); // Default maximum 5,000,000
            }
            return null;
        }
    }

    public void setMaxLoanAmountDecimal(java.math.BigDecimal amount) {
        if (amount == null) {
            this.maxLoanAmount = null;
        } else {
            // For now, store as plain text
            // TODO: Implement proper encryption
            this.maxLoanAmount = amount.toString();
        }
    }

    public void setMinLoanTermMonths(Integer minLoanTermMonths) 
    {
        this.minLoanTermMonths = minLoanTermMonths;
    }

    public Integer getMinLoanTermMonths() 
    {
        return minLoanTermMonths;
    }

    public void setMaxLoanTermMonths(Integer maxLoanTermMonths) 
    {
        this.maxLoanTermMonths = maxLoanTermMonths;
    }

    public Integer getMaxLoanTermMonths() 
    {
        return maxLoanTermMonths;
    }

    public void setRiskRating(String riskRating) 
    {
        this.riskRating = riskRating;
    }

    public String getRiskRating() 
    {
        return riskRating;
    }

    public void setCooperationStatus(String cooperationStatus) 
    {
        this.cooperationStatus = cooperationStatus;
    }

    public String getCooperationStatus() 
    {
        return cooperationStatus;
    }

    public void setCooperationStartDate(Date cooperationStartDate) 
    {
        this.cooperationStartDate = cooperationStartDate;
    }

    public Date getCooperationStartDate() 
    {
        return cooperationStartDate;
    }

    public void setCooperationEndDate(Date cooperationEndDate) 
    {
        this.cooperationEndDate = cooperationEndDate;
    }

    public Date getCooperationEndDate() 
    {
        return cooperationEndDate;
    }

    public void setStatus(String status) 
    {
        this.status = status;
    }

    public String getStatus() 
    {
        return status;
    }

    public void setRemarks(String remarks) 
    {
        this.remarks = remarks;
    }

    public String getRemarks() 
    {
        return remarks;
    }

    public void setDeptId(Long deptId) 
    {
        this.deptId = deptId;
    }

    public Long getDeptId() 
    {
        return deptId;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("bankId", getBankId())
            .append("bankCode", getBankCode())
            .append("bankName", getBankName())
            .append("bankType", getBankType())
            .append("contactPerson", getContactPerson())
            .append("contactPhone", getContactPhone())
            .append("contactEmail", getContactEmail())
            .append("bankAddress", getBankAddress())
            .append("productName", getProductName())
            .append("productInterestRate", getProductInterestRate())
            .append("productTermMonths", getProductTermMonths())
            .append("creatorAccountType", getCreatorAccountType())
            .append("baseInterestRate", getBaseInterestRate())
            .append("minLoanAmount", getMinLoanAmount())
            .append("maxLoanAmount", getMaxLoanAmount())
            .append("minLoanTermMonths", getMinLoanTermMonths())
            .append("maxLoanTermMonths", getMaxLoanTermMonths())
            .append("riskRating", getRiskRating())
            .append("cooperationStatus", getCooperationStatus())
            .append("cooperationStartDate", getCooperationStartDate())
            .append("cooperationEndDate", getCooperationEndDate())
            .append("status", getStatus())
            .append("remarks", getRemarks())
            .append("createTime", getCreateTime())
            .append("updateTime", getUpdateTime())
            .append("deptId", getDeptId())
            .toString();
    }
}