package com.malk.guyuan.server.model;

import cn.hutool.core.util.ObjectUtil;
import com.malk.base.BaseDto;
import com.malk.server.common.McException;
import com.malk.server.common.McREnum;
import com.malk.utils.UtilMap;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Map;

/**
 * ppExt: 新版本官方返回数据已结构化, 以官方为准
 *
 * @apiNote https://cloud.tencent.com/document/api/866/33527#AirTransport 数据结构
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class McInvoiceDto extends BaseDto {


    /**************** 发票 ****************/

    /**
     * 发票名称 [类型全称]
     */
    private String name;

    // 兼容: 不为空
    public String getName() {
        if (StringUtils.isBlank(name)) {
            return kindName;
        }
        return name;
    }

    /**
     * 发票类型 [类型简称]
     * -
     * ppExt: 全电票, 新版本识别接口, 返回名称为: 电子发票(普通发票) 不包含全电标识, 发类型为: 全电发票. 注意取值
     */
    private String kindName;

    /**
     * 发票类型 [编码]
     */
    private int kind;

    /**
     * 发票代码
     */
    private String code;

    /**
     * 发票号码
     */
    private String serial;

    /**
     * 开票日期 [yyyy-MM-dd]
     */
    private String date;

    /**
     * 校验码
     */
    private String checkCode;

    /**
     * 价税合计
     */
    private BigDecimal amount;

    /**
     * 不含税金额
     */
    private BigDecimal excludingTax;

    /// 没有税额时, 税额可能没传递 [因此前提是不含税为空]，不含税金额等于价税合计
    public BigDecimal getExcludingTax() {
        if (ObjectUtil.isNull((excludingTax)) && (ObjectUtil.isNull(tax) || BigDecimal.ZERO.compareTo(tax) == 0)) {
            return amount;
        }
        return excludingTax;
    }

    /**
     * 不含税金额
     */
    private BigDecimal tax;

    /// 取值为null, 合计会异常
    public BigDecimal getTax() {
        if (ObjectUtil.isNull(tax)) {
            return BigDecimal.ZERO;
        }
        return tax;
    }

    /**
     * 购买方名称
     */
    private String buyerName;

    /**
     * 购买方税号
     */
    private String buyerTaxId;

    /**
     * 销售方名称
     */
    private String sellerName;

    /**
     * 销售方税号
     */
    private String sellerTaxId;

    /**
     * 备注
     */
    private String remark;

    /**************** 交通 ****************/

    /**
     * 乘客姓名
     */
    private String passengerName;

    /**
     * 座位类型
     */
    private String seatType;

    /**
     * 出发地
     */
    private String departurePort;

    /**
     * 到达地
     */
    private String arrivePort;

    /**
     * 出发时间 [yyyy-MM-dd HH:mm]
     */
    private String departureTime;

    /**
     * 车次编号/航班号
     */
    private String trainNo;

    /**
     * 保险费
     */
    private BigDecimal insuranceCosts;

    /**
     * 燃油附加费
     */
    private BigDecimal fuelCosts;

    /**
     * 民航发展基金
     */
    private BigDecimal constructionCosts;

    /**************** 格式化 ****************/

    /**
     * 实例Map, 服务宜搭组件映射 [明细组件获取表头, 通过名称转换字段]
     *
     * @implSpec const headers = this.$("tableField_liv5f4d2").props.children[0].props.children.map(({ props: { label, fieldId } }) => ({ label, compId: fieldId }))
     */
    public static Map formatDtoLabelAndProp() {

        Map data = UtilMap.map("发票名称, 发票类型, 发票代码, 发票号码, 开票日期, 校验码, 价税合计, 不含税金额, 税额", "name, kindName, code, serial, date, checkCode, amount, excludingTax, tax");
        data.putAll(UtilMap.map("购买方名称, 购买方税号, 销售方名称, 销售方税号", "buyerName, buyerTaxId, sellerName, sellerTaxId"));
        data.putAll(UtilMap.map("乘客姓名, 座位类型, 出发地, 到达地, 出发时间, 车次编号/航班号, 保险费, 燃油附加费, 民航发展基金", "passengerName, seatType, departurePort, arrivePort, departureTime, trainNo, insuranceCosts, fuelCosts, constructionCosts"));
        return data;
    }

    /**
     * 格式化返回
     */
    public static Map formatResponse(Object result) {
        return UtilMap.map("result, dto", result, formatDtoLabelAndProp());
    }

    /**************** 返回值 ****************/

    // 成功状态标记
    private final static String SUC_CODE = "OK";

    /**
     * 断言错误信息
     */
    public static void assertSuccess(Map result, String kind) {
        String code = UtilMap.getString(result, "Code");
        McException.assertException(!SUC_CODE.equals(code), McREnum.VENDOR_ERROR.getCode(), kind, "tencent");
    }
}

