package com.yd.csf.service.vo;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yd.csf.service.enums.CurrencyEnum;
import com.yd.csf.service.model.Fortune;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.beans.BeanUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;

@Data
public class FortuneVO implements Serializable {

    /**
     * fortune id
     */
    @Schema(description = "fortune id")
    private Long id;

    /**
     * 保单出账业务id
     */
    @Schema(description = "保单出账业务id")
    private String fortuneBizId;

    /**
     * 检核年月
     */
    @Schema(description = "检核年月")
    private String reconciliationYearMonth;

    /**
     * 应付款类型 R-关联保单应付款 U-非关联保单应付款
     */
    @Schema(description = "应付款类型 R-关联保单应付款 U-非关联保单应付款")
    private String fortuneBizType;

    /**
     * 是否拆分出来的出账 1-是 0-否 2-拆分的原纪录
     */
    @Schema(description = "是否拆分出来的出账 1-是 0-否 2-拆分的原纪录")
    private Integer isPart;

    /**
     * 预计出账业务ID
     */
    @Schema(description = "预计出账业务ID")
    private String expectedFortuneBizId;

    /**
     * 应付账款编号
     */
    @Schema(description = "应付账款编号")
    private String payableNo;

    /**
     * 保单号
     */
    @Schema(description = "保单号")
    private String policyNo;

    /**
     * 保单币种
     */
    @Schema(description = "保单币种")
    private String policyCurrency;

    /**
     * 期交保费
     */
    @Schema(description = "期交保费")
    private BigDecimal premium;

    /**
     * 产品名称
     */
    @Schema(description = "产品名称")
    private String productName;

    /**
     * 保险公司
     */
    @Schema(description = "保险公司")
    private String insuranceCompany;

    /**
     * 来佣业务id
     */
    @Schema(description = "来佣业务id")
    private String commissionBizId;

    /**
     * 来佣预期业务id
     */
    @Schema(description = "来佣预期业务id")
    private String commissionExpectedBizId;

    /**
     * 已入账来佣金额（HKD）
     */
    @Schema(description = "已入账来佣金额（HKD）")
    private BigDecimal commissionPaidAmount;

    /**
     * 已入账来佣比例 (%)
     */
    @Schema(description = "已入账来佣比例 (%)")
    private BigDecimal commissionPaidRatio;

    /**
     * 入账达成率缺口 (%)
     */
    @Schema(description = "入账达成率缺口 (%)")
    private BigDecimal commissionPendingRatio;

    /**
     * 本次已来佣金额
     */
//    @Schema(description = "本次已来佣金额")
//    private Object commissionAmount;

    /**
     * 出账期数(1=第一年; 2=第二年; 3=第三年; 4=第四年; 5=第五年)
     */
    @Schema(description = "出账期数(1=第一年; 2=第二年; 3=第三年; 4=第四年; 5=第五年)")
    private Integer fortunePeriod;

    /**
     * 出账总期数
     */
    @Schema(description = "出账总期数")
    private Integer fortuneTotalPeriod;

    /**
     * 转介人
     */
    @Schema(description = "转介人")
    private String broker;

    /**
     * 转介人职级
     */
    @Schema(description = "转介人职级")
    private String brokerGradeName;

    /**
     * 转介人业务ID
     */
    @Schema(description = "转介人业务ID")
    private String brokerBizId;

    /**
     * 所属团队
     */
    @Schema(description = "所属团队")
    private String team;

    /**
     * 所属团队业务ID
     */
    @Schema(description = "所属团队业务ID")
    private String teamBizId;

    /**
     * 出账名称
     */
    @Schema(description = "出账名称")
    private String fortuneName;

    /**
     * 出账类型
     */
    @Schema(description = "出账类型")
    private String fortuneType;

    /**
     * 保单币种金额
     */
    @Schema(description = "保单币种金额")
    private BigDecimal ruleAmount;

    /**
     * 保单币种
     */
    @Schema(description = "保单币种")
    private String ruleCurrency;

    /**
     * 保单币种→港币汇率（入账检核汇率）
     */
    @Schema(description = "保单币种→港币汇率（入账检核汇率）")
    private BigDecimal exchangeRate;

    /**
     * 原币种
     */
    @Schema(description = "原币种")
    private String originalCurrency;

    /**
     * 原币种金额
     */
    @Schema(description = "原币种金额")
    private BigDecimal originalAmount;

    /**
     * 原币种→港币汇率
     */
    @Schema(description = "原币种→港币汇率")
    private BigDecimal originalToHkdRate;

    /**
     * 发放币种
     */
    @Schema(description = "发放币种")
    private String payoutCurrency;

    /**
     * 发放币种金额
     */
    @Schema(description = "发放币种金额")
    private BigDecimal payoutAmount;

    /**
     * 港币→发放币种汇率
     */
    @Schema(description = "港币→发放币种汇率")
    private BigDecimal hkdToPayoutRate;

    /**
     * 港币出账金额
     */
    @Schema(description = "港币出账金额")
    private BigDecimal hkdAmount;

    /**
     * 已出账金额
     */
    @Schema(description = "已出账金额")
    private BigDecimal fortunePaidAmount;

    /**
     * 待出账金额
     */
    @Schema(description = "剩余出账金额")
    private BigDecimal fortuneUnpaidAmount;

    /**
     * 本期出账金额
     */
    @Schema(description = "本期出账金额")
    private BigDecimal currentPaymentAmount;

    /**
     * 本次出账港币金额
     */
    @Schema(description = "本次出账港币金额")
    private BigDecimal currentPaymentHkdAmount;

    /**
     * 本期出账比例
     */
    @Schema(description = "本期出账比例")
    private BigDecimal currentPaymentRatio;

    /**
     * 剩余出账比例 剩余出账金额/应出账金额
     */
    @Schema(description = "剩余出账比例 剩余出账金额/应出账金额")
    private BigDecimal fortuneUnpaidRatio;

    /**
     * 出账状态 0=待出账 1=可出账，待检核 2=已出账 3=部分出账 4=保留 5=已失效 6=可出账，检核完成
     */
    @Schema(description = "出账状态 字典值：csf_fortune_status")
    private String status;

    /**
     * 出账日(估) / 预计发佣月
     */
    @Schema(description = "出账日(估) / 预计发佣月")
    @JsonFormat(pattern = "yyyy-MM", timezone = "GMT+8")
    private LocalDate payoutDate;

    /**
     * 出账日(实)
     */
    @Schema(description = "出账日(实)")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate actualPayoutDate;

    /**
     * 是否含税 0=No, 1=Yes
     */
    @Schema(description = "是否含税 0=No, 1=Yes")
    private Integer isTax;

    /**
     * 应缴税额
     */
    @Schema(description = "应缴税额")
    private BigDecimal taxAmount;

    /**
     * 税后出账
     */
    @Schema(description = "税后出账")
    private BigDecimal netAmount;

    /**
     * 薪资单业务id
     */
    @Schema(description = "薪资单业务id")
    private String salaryBizId;

    /**
     * 基本法id
     */
    @Schema(description = "基本法id")
    private String baseRuleBizId;

    /**
     * 计算规则id
     */
    @Schema(description = "计算规则id")
    private String settlementBizId;

    /**
     * 计算公式
     */
    @Schema(description = "计算公式")
    private String calculationFormula;

    /**
     * 备注
     */
    @Schema(description = "备注")
    private String remark;

    /**
     * 创建人ID
     */
    @Schema(description = "创建人ID")
    private String creatorId;

    /**
     * 操作人
     */
    @Schema(description = "操作人")
    private String reconciliationOperator;

    /**
     * 更新人ID
     */
    @Schema(description = "更新人ID")
    private String updaterId;

    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    /**
     * 更新时间
     */
    @Schema(description = "更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;

    private static final long serialVersionUID = 1L;


    /**
     * 对象转封装类
     *
     * @param fortune
     * @return
     */
    public static FortuneVO objToVo(Fortune fortune) {
        if (fortune == null) {
            return null;
        }
        FortuneVO fortuneVO = new FortuneVO();
        BeanUtils.copyProperties(fortune, fortuneVO);

        // 安全获取港币金额，避免 null
        BigDecimal hkdAmount = ObjectUtil.defaultIfNull(fortune.getHkdAmount(), BigDecimal.ZERO);

        // 已出账金额（status=2 时取 currentPaymentHkdAmount，否则为 0）
        BigDecimal currentPaymentHkdAmount = "2".equals(fortune.getStatus())
                ? ObjectUtil.defaultIfNull(fortune.getCurrentPaymentHkdAmount(), BigDecimal.ZERO)
                : BigDecimal.ZERO;

        fortuneVO.setFortunePaidAmount(currentPaymentHkdAmount);
        fortuneVO.setFortuneUnpaidAmount(NumberUtil.sub(hkdAmount, currentPaymentHkdAmount));

        // 计算已出账比例，分母为 0 时直接设为 0%
        BigDecimal currentPaymentRatio;
        if (hkdAmount.compareTo(BigDecimal.ZERO) == 0) {
            currentPaymentRatio = BigDecimal.ZERO;
        } else {
            currentPaymentRatio = NumberUtil.div(currentPaymentHkdAmount, hkdAmount, 4)
                    .multiply(BigDecimal.valueOf(100));
        }
        fortuneVO.setCurrentPaymentRatio(currentPaymentRatio);
        fortuneVO.setFortuneUnpaidRatio(BigDecimal.valueOf(100).subtract(currentPaymentRatio));

//        fortuneVO.setCurrency(CurrencyEnum.toLabel(fortune.getCurrency()));
        fortuneVO.setPolicyCurrency((CurrencyEnum.toLabel(fortune.getPolicyCurrency())));

        return fortuneVO;
    }

}
