package com.ruoyi.credit.event;

import java.util.Date;

import org.springframework.context.ApplicationEvent;

import com.ruoyi.common.utils.DateUtils;

/**
 * 贷款记录变更事件
 * 用于通知贷款记录的新增、修改、删除等变更操作
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
public class LoanChangeEvent extends ApplicationEvent {

    private static final long serialVersionUID = 1L;

    /**
     * 事件类型枚举
     */
    public enum EventType {
        CREATED("CREATED", "贷款记录新增"),
        UPDATED("UPDATED", "贷款记录修改"),
        DELETED("DELETED", "贷款记录删除"),
        CREDIT_CHANGED("CREDIT_CHANGED", "债权凭证变更"),
        SERVICE_PERIOD_CHANGED("SERVICE_PERIOD_CHANGED", "服务周期变更"),
        BATCH_VALIDATION_REQUEST("BATCH_VALIDATION_REQUEST", "批量验证请求");

        private final String code;
        private final String description;

        EventType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public String getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }

    /** 贷款ID */
    private Long loanId;

    /** 债权凭证ID */
    private Long creditId;

    /** 服务周期ID */
    private Long servicePeriodId;

    /** 事件类型 */
    private EventType eventType;

    /** 事件时间 */
    private Date eventTime;

    /** 事件描述 */
    private String eventDescription;

    /** 触发用户 */
    private String triggeredBy;

    /** 变更前数据 */
    private Object oldData;

    /** 变更后数据 */
    private Object newData;

    /**
     * 构造函数
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param eventType 事件类型
     */
    public LoanChangeEvent(Object source, Long loanId, EventType eventType) {
        super(source);
        this.loanId = loanId;
        this.eventType = eventType;
        this.eventTime = DateUtils.getNowDate();
        this.eventDescription = eventType.getDescription();
    }

    /**
     * 构造函数（包含债权凭证ID）
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param creditId 债权凭证ID
     * @param eventType 事件类型
     */
    public LoanChangeEvent(Object source, Long loanId, Long creditId, EventType eventType) {
        super(source);
        this.loanId = loanId;
        this.creditId = creditId;
        this.eventType = eventType;
        this.eventTime = DateUtils.getNowDate();
        this.eventDescription = eventType.getDescription();
    }

    /**
     * 构造函数（包含服务周期ID）
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param servicePeriodId 服务周期ID
     * @param eventType 事件类型
     */
    public LoanChangeEvent(Object source, Long loanId, Long servicePeriodId, EventType eventType, boolean isServicePeriod) {
        super(source);
        this.loanId = loanId;
        this.servicePeriodId = servicePeriodId;
        this.eventType = eventType;
        this.eventTime = DateUtils.getNowDate();
        this.eventDescription = eventType.getDescription();
    }

    /**
     * 完整构造函数
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param creditId 债权凭证ID
     * @param servicePeriodId 服务周期ID
     * @param eventType 事件类型
     * @param triggeredBy 触发用户
     */
    public LoanChangeEvent(Object source, Long loanId, Long creditId, Long servicePeriodId, 
                          EventType eventType, String triggeredBy) {
        super(source);
        this.loanId = loanId;
        this.creditId = creditId;
        this.servicePeriodId = servicePeriodId;
        this.eventType = eventType;
        this.eventTime = DateUtils.getNowDate();
        this.eventDescription = eventType.getDescription();
        this.triggeredBy = triggeredBy;
    }

    /**
     * 创建贷款新增事件
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param triggeredBy 触发用户
     * @return 贷款变更事件
     */
    public static LoanChangeEvent createLoanCreatedEvent(Object source, Long loanId, String triggeredBy) {
        LoanChangeEvent event = new LoanChangeEvent(source, loanId, EventType.CREATED);
        event.setTriggeredBy(triggeredBy);
        return event;
    }

    /**
     * 创建贷款修改事件
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param triggeredBy 触发用户
     * @param oldData 变更前数据
     * @param newData 变更后数据
     * @return 贷款变更事件
     */
    public static LoanChangeEvent createLoanUpdatedEvent(Object source, Long loanId, String triggeredBy, 
                                                        Object oldData, Object newData) {
        LoanChangeEvent event = new LoanChangeEvent(source, loanId, EventType.UPDATED);
        event.setTriggeredBy(triggeredBy);
        event.setOldData(oldData);
        event.setNewData(newData);
        return event;
    }

    /**
     * 创建债权凭证变更事件
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param creditId 债权凭证ID
     * @param triggeredBy 触发用户
     * @return 贷款变更事件
     */
    public static LoanChangeEvent createCreditChangedEvent(Object source, Long loanId, Long creditId, String triggeredBy) {
        LoanChangeEvent event = new LoanChangeEvent(source, loanId, creditId, EventType.CREDIT_CHANGED);
        event.setTriggeredBy(triggeredBy);
        return event;
    }

    /**
     * 创建服务周期变更事件
     * 
     * @param source 事件源
     * @param loanId 贷款ID
     * @param servicePeriodId 服务周期ID
     * @param triggeredBy 触发用户
     * @return 贷款变更事件
     */
    public static LoanChangeEvent createServicePeriodChangedEvent(Object source, Long loanId, Long servicePeriodId, String triggeredBy) {
        LoanChangeEvent event = new LoanChangeEvent(source, loanId, servicePeriodId, EventType.SERVICE_PERIOD_CHANGED, true);
        event.setTriggeredBy(triggeredBy);
        return event;
    }

    /**
     * 创建批量验证请求事件
     * 
     * @param source 事件源
     * @param triggeredBy 触发用户
     * @return 贷款变更事件
     */
    public static LoanChangeEvent createBatchValidationRequestEvent(Object source, String triggeredBy) {
        LoanChangeEvent event = new LoanChangeEvent(source, null, EventType.BATCH_VALIDATION_REQUEST);
        event.setTriggeredBy(triggeredBy);
        return event;
    }

    // Getters and Setters

    public Long getLoanId() {
        return loanId;
    }

    public void setLoanId(Long loanId) {
        this.loanId = loanId;
    }

    public Long getCreditId() {
        return creditId;
    }

    public void setCreditId(Long creditId) {
        this.creditId = creditId;
    }

    public Long getServicePeriodId() {
        return servicePeriodId;
    }

    public void setServicePeriodId(Long servicePeriodId) {
        this.servicePeriodId = servicePeriodId;
    }

    public EventType getEventType() {
        return eventType;
    }

    public void setEventType(EventType eventType) {
        this.eventType = eventType;
        this.eventDescription = eventType.getDescription();
    }

    public Date getEventTime() {
        return eventTime;
    }

    public void setEventTime(Date eventTime) {
        this.eventTime = eventTime;
    }

    public String getEventDescription() {
        return eventDescription;
    }

    public void setEventDescription(String eventDescription) {
        this.eventDescription = eventDescription;
    }

    public String getTriggeredBy() {
        return triggeredBy;
    }

    public void setTriggeredBy(String triggeredBy) {
        this.triggeredBy = triggeredBy;
    }

    public Object getOldData() {
        return oldData;
    }

    public void setOldData(Object oldData) {
        this.oldData = oldData;
    }

    public Object getNewData() {
        return newData;
    }

    public void setNewData(Object newData) {
        this.newData = newData;
    }

    @Override
    public String toString() {
        return "LoanChangeEvent{" +
                "loanId=" + loanId +
                ", creditId=" + creditId +
                ", servicePeriodId=" + servicePeriodId +
                ", eventType=" + eventType +
                ", eventTime=" + eventTime +
                ", eventDescription='" + eventDescription + '\'' +
                ", triggeredBy='" + triggeredBy + '\'' +
                '}';
    }
}