package com.yd.csf.feign.dto.appointment;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.yd.csf.feign.dto.AddressDto;
import com.yd.csf.feign.dto.taxation.ApiTaxationDto;
import com.yd.csf.feign.enums.RelTypeEnum;
import com.yd.csf.feign.valid.GroupValid;
import lombok.Data;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.List;

/**
 * 受保人信息入参
 */
@Data
public class ApiInsurantInfoDto {

    /**
     * 受保人信息表唯一业务ID
     */
    private String insurantBizId;

    /**
     * 关联客户信息表唯一业务ID（冗余字段）
     */
    @NotBlank(message = "受保人-关联客户信息表唯一业务ID不能为空", groups = GroupValid.NotSelf.class)
    private String customerBizId;

    /**
     * 关联客户编号（和客户信息表唯一业务ID是一对，唯一，冗余字段）
     */
//    @NotBlank(message = "受保人-关联客户编号不能为空", groups = GroupValid.NotSelf.class)
    private String customerNo;

    /**
     * 与投保人关系（字典）
     */
    @NotBlank(message = "受保人-与投保人关系不能为空", groups = GroupValid.Always.class)
    private String policyholderRel;

    //-- 以下基础信息
    /**
     * 姓名-中文
     */
    @NotBlank(message = "受保人-姓名（中文）不能为空", groups = GroupValid.NotSelf.class)
    @Pattern(regexp = "^[\u4e00-\u9fa5]{2,6}$", message = "受保人-姓名（中文）必须为2-6位汉字", groups = GroupValid.NotSelf.class)
    private String nameCn;

    /**
     * 姓名-（拼音/英文，通过中文自动加载全部大写的拼音）
     */
    @NotBlank(message = "受保人-姓名（拼音/英文）不能为空", groups = GroupValid.NotSelf.class)
    private String namePyEn;

    /**
     * 证件类型（字典，下拉选择）
     */
    @NotBlank(message = "受保人-证件类型不能为空", groups = GroupValid.NotSelf.class)
    private String documentType;

    /**
     * 证件号码
     */
    @NotBlank(message = "受保人-证件号码不能为空", groups = GroupValid.NotSelf.class)
    private String idNumber;

    /**
     * 性别（字典，如果是身份证，自动获取性别和生日）
     */
    @NotBlank(message = "受保人-性别不能为空", groups = GroupValid.NotSelf.class)
    private String gender;

    /**
     * 出生日期（生日，如果是身份证，自动获取性别和生日）
     */
    @NotNull(message = "受保人-生日不能为空", groups = GroupValid.NotSelf.class)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime birthday;
    @AssertTrue(message = "受保人-必须大于18周岁", groups = GroupValid.NotSelf.class)
    public boolean isBirthdayValid() {
        if (birthday == null) {
            // @NotNull 会处理空值
            return true;
        }
        LocalDateTime now = LocalDateTime.now();
        // 计算年龄
        int age = Period.between(birthday.toLocalDate(), now.toLocalDate()).getYears();
        return age > 18;
    }

    /**
     * 年龄（通过生日自动获取年龄）
     */
    @NotBlank(message = "受保人-年龄不能为空", groups = GroupValid.NotSelf.class)
    private String age;

    /**
     * 国籍（下拉选择）
     */
    @NotBlank(message = "受保人-国籍不能为空", groups = GroupValid.NotSelf.class)
    private String nationality;

    /**
     * 出生地
     */
    private String birthplace;

    /**
     * 是否拥有其他国家公民身份（如美国、日本等）: 0-否, 1-是（字典）
     */
    private Integer isOtherCountry;

    /**
     * 吸烟情况（字典）
     */
    @NotBlank(message = "受保人-吸烟情况不能为空", groups = GroupValid.NotSelf.class)
    private String smokingStatus;

    /**
     * 婚姻情况（字典）
     */
    @NotBlank(message = "受保人-婚姻情况不能为空", groups = GroupValid.NotSelf.class)
    private String maritalStatus;

    /**
     * 教育程度（字典）
     */
    @NotBlank(message = "受保人-教育程度不能为空", groups = GroupValid.NotSelf.class)
    private String educationLevel;

    /**
     * 是否退休（字典）
     */
    @NotNull(message = "受保人-是否退休不能为空", groups = GroupValid.NotSelf.class)
    private Integer isRetirement;

    /**
     * 退休年龄（如已退休，再显示）
     */
    private String retirementAge;

    /**
     * 身高（CM)
     */
    private String height;

    /**
     * 体重（KG)
     */
    private String weight;

    /**
     * BMI指数（根据身高和体重自动计算）
     */
    private String bmi;

    /**
     * 风险偏好（字典，下拉选择）
     */
    private String riskAppetite;

    /**
     * 受供养人数目（通过FNA带入）
     */
    private Integer dependentsNum;

    //-- 以下是联系信息
    /**
     * 移动电话区号
     */
    @NotBlank(message = "受保人-移动电话区号不能为空", groups = GroupValid.NotSelf.class)
    private String mobileCode;

    /**
     * 移动电话
     */
    @NotBlank(message = "受保人-移动电话不能为空", groups = GroupValid.NotSelf.class)
    private String mobile;

    /**
     * 住宅电话区号
     */
    private String residenceMobileCode;

    /**
     * 住宅电话
     */
    private String residenceMobile;

    /**
     * 固定电话区号
     */
    private String landlineCode;

    /**
     * 固定电话
     */
    private String landline;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 证件地址
     */
    @NotBlank(message = "受保人-证件地址不能为空", groups = GroupValid.NotSelf.class)
    private String certificateAddress;

    /**
     * 通讯地址
     */
    private String mailingAddress;

    /**
     * 居住地址（住宅地址）
     */
    private String residentialAddress;

    /**
     * 通讯地址邮政编号
     */
    private String mailingAddressCode;

    //-- 以下是工作信息
    /**
     * 就业情况（字典，下拉选择）
     */
    private String employmentStatus;

    /**
     * 公司/学校名称
     */
    private String csName;

    /**
     * 行业
     */
    private String industry;

    /**
     * 现时每月收入（HKD)
     */
    private BigDecimal currentMonthlyIncome;

    /**
     * 总工作年期
     */
    private BigDecimal totalWorkingYears;

    /**
     * 受雇于现职年期
     */
    private BigDecimal currentTenure;

    /**
     * 职位
     */
    private String position;

    /**
     * 公司地址
     */
    private String companyAddress;

    /**
     * 公司电话区号
     */
    private String companyMobileCode;

    /**
     * 公司电话
     */
    private String companyMobile;

    /**
     * 公司地址邮政编号
     */
    private String companyAddressCode;

    //-- 以下是财务信息
    /**
     * 平均每月收入（HKD）
     */
    private BigDecimal monthIncome;

    /**
     * 平均每月支出（HKD）
     */
    private BigDecimal monthExpenditure;

    /**
     * 总流动资产（HKD）
     */
    private BigDecimal totalCurrentAssets;

    /**
     * 总负债额（HKD）
     */
    private BigDecimal totalDebt;

    //-- 其他信息（非必填）
    /**
     * 旅行（字典）
     */
    private String travel;

    /**
     * 运动（字典，下拉选择）
     */
    private String exercise;

    /**
     * 游戏（字典，下拉选择）
     */
    private String game;

    /**
     * 电影/戏剧（字典，下拉选择）
     */
    private String movieDrama;

    /**
     * 美食（输入）
     */
    private String delicacy;

    /**
     * 地址列表
     */
    private List<AddressDto> addressList;

    /**
     * 税务信息列表
     */
    private List<ApiTaxationDto> apiTaxationDtoList;

    // 判断与投保人关系是否为本人关系
    public boolean isSelf() {
        return RelTypeEnum.MYSELF.getItemValue().equals(policyholderRel);
    }
}
