package com.malk.harrison.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McException;
import com.malk.server.common.McR;
import com.malk.server.dingtalk.DDConf;
import com.malk.service.aliwork.YDClient;
import com.malk.harrison.server.XYR;
import com.malk.utils.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 错误抛出与拦截详见 CatchException
 */
@Slf4j
@RestController
@RequestMapping("/harrison")
public class HLController {

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDConf ddConf;

    // prd: 物流类型打印模板 业务类型 中文->英文 对照
    private static final Map<String, String> PART_EN = new HashMap<>();

    static {
        PART_EN.put("内陆运输", "TRANSPORTATION");
        PART_EN.put("THC", "TERMINAL HANDLING CHARGES");
        PART_EN.put("港口货代", "TNPA CARGO DUES");
        PART_EN.put("海运", "OCEAN FREIGHT");
        PART_EN.put("检测", "SAMPLING AND ANALYSIS");
        PART_EN.put("单证", "DOCUMENTATION FEE");
        PART_EN.put("保险", "OCEAN INSURANCE");
    }

    @PostMapping("/invoice")
    McR HL_invoice(@RequestBody Map data, HttpServletResponse response, HttpServletRequest request) {

//        data.putAll(UtilMap.map("type, abbr, formId", "销售发票, FLOURISH, 4070f44f-72da-4beb-b4b4-64d65d70c271"));
        log.info("invoice, {}", data);

        McException.assertParamException_Null(data, "formId, abbr, type");

        String formId = UtilMap.getString(data, "formId");
        Map formData = ydClient.queryData(YDParam.builder()
                .formInstId(formId)
                .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();

        /// 字段: 销售方, 购买方, 发票号, 合同号, 付款条款, 船名, 提单号, 原厂地（国家）, 装货港, 卸货港, 包装方式, 贸易方式, 提单日期, 品名
        Map printData = UtilMap.map("seller, buyer, invoice, contract, payment, vessel, lading, origin, ladP, disP, packing, trade, bDate, commodity",
                "selectField_mgvg350c, selectField_mgvh3io0, textField_l6q5sysr, selectField_mkdpx3e7, selectField_l5rljms7, selectField_migsdo11, textField_migsdo16, textField_migsdo17, selectField_mkdpx3e8, selectField_mkdpx3e9, textareaField_migsdo1a, textField_migsdo1b, dateField_migsdo1e, selectField_l6mztuvx",
                formData);
        printData.put("date", UtilDateTime.formatDate(new Date(UtilMap.getLong(formData, "dateField_mgvqvr4l")))); // 开票日期
        String title = UtilMap.getString(formData, "selectField_mgvqvr4j").equals("最终发票") ? "FINAL COMMERCIAL INVOICE" : "PROVISIONAL COMMERCIAL INVOICE";
        printData.put("title", title); // 发票类型
        String[] sAddrs = UtilMap.getString(formData, "textareaField_migsdo0w").split("\\|");
        for (int i = 0; i < sAddrs.length; i++) {
            printData.put("sAddr" + i, sAddrs[i]); // 销售方-地址
        }
        String[] bAddrs = UtilMap.getString(formData, "textareaField_migsdo0x").split("\\|");
        for (int i = 0; i < bAddrs.length; i++) {
            printData.put("bAddr" + i, bAddrs[i]); // 购买方-地址
        }
        // prd 0605 贸易打印模板修改，页面可从明细带出如船、装港、卸港，从第一条带出
        printData.put("wet", UtilMap.getFloat(formData, "numberField_mpzjdkj0")); // 湿吨
        printData.put("hsl", UtilMap.getFloat(formData, "numberField_mq6r7ntr")); // 含水量
        printData.put("dry", UtilMap.getFloat(formData, "numberField_mpzjdkj1")); // 干吨
        printData.put("gap", UtilMap.getFloat(formData, "numberField_mpzjdkj0") - UtilMap.getFloat(formData, "numberField_mpzjdkj1")); // 差值
        printData.put("unit", UtilMap.getFloat(formData, "numberField_mpzo2g8o")); // 单价-美金
        printData.put("qmt", UtilMap.getFloat(formData, "numberField_mq6sdnqp")); // 计算吨数

        List<Map> details =  UtilMap.getList(formData, "tableField_mgvqvr53");
        List<Map> dataList = details.stream().map(item-> {
            // 字段: 业务-业务类型, 吨数-结算吨数, 单价-发票金额(美金), 总价-发票合计(美金), 汇率
            Map row = UtilMap.map("part, num, price, amount, rate",
                    "selectField_mgugk66v, numberField_mgvqvr58, numberField_mpzo2g8p, numberField_l49o1fgx, numberField_mgugk673",
                    item);
            String part = UtilMap.getString(item, "selectField_mgugk66v");
            row.put("part", PART_EN.getOrDefault(part, part)); // prd: 物流类型模板展示英文业务类型, 命中映射才替换
            row.put("quantity", UtilMap.getFloat(item, "numberField_mgvqvr58") + "MT");
            row.put("exchange", UtilNumber.formatPrecisionString(UtilMap.getFloat(item, "numberField_l5ryl6qe") / UtilMap.getFloat(item, "numberField_mgugk673")));
            row.put("empty", ""); // ppExt: 添加了子表, 若模板未用到会异常, 添加标注
            return row;
        }).collect(Collectors.toList());
        printData.put("oTotal", UtilMap.getDouble(formData, "numberField_mgvvsif6")); // 发票金额合计-美金 // fixme: 百万级金额, float32 精度不足会显示为 2816951.20, 用 Double
        log.info("printData, {}", printData);

        String type = UtilMap.getString(data, "type"); // 模板类型
        String abbr = UtilMap.getString(data, "abbr"); // 公司简称
        String fileName = abbr + " " + title;
        UtilExcel.exportMapAndListByTemplate(response, printData, dataList, Map.class, fileName, abbr + " " + type + ".xlsx");
        return  McR.success();
    }

}
