package com.yd.api.commission.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yd.api.commission.service.LifeCommissionService;
import com.yd.api.commission.vo.lifecommission.*;
import com.yd.api.result.CommonResult;
import com.yd.dal.entity.agms.fortune.FortunePayToOrderInfo;
import com.yd.dal.entity.commission.OrderCommissonCheck;
import com.yd.dal.entity.customer.AclCustomerFortune;
import com.yd.dal.entity.order.PoOrder;
import com.yd.dal.mapper.lifecommission.LifeCommissionMapper;
import com.yd.dal.service.customer.AclCustomerFortuneDALService;
import com.yd.dal.service.order.PoOrderDALService;
import com.yd.rmi.ali.send.service.SendService;
import com.yd.rmi.cache.SystemConfigService;
import com.yd.util.config.ZHBErrorConfig;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;


@Service
public class LifeCommissionServiceImpl implements LifeCommissionService {

    @Autowired
    private LifeCommissionMapper lifeCommissionMapper;
    @Autowired
    private AclCustomerFortuneDALService customerFortuneDalService;
    @Autowired
    private PoOrderDALService poOrderDALService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private SendService sendService;


    @Override
    public ComeCommissionListResponseVO queryComeCommissionList(QueryComeCommissionListRequestVO requestVO) {
        ComeCommissionListResponseVO resp = new ComeCommissionListResponseVO();
        try {
            // 分页结果集
            PageInfo<ComeCommissionVO> pageInfo = this.queryComeCommissionListPage(requestVO);
            resp.setDataList(pageInfo.getList());
            pageInfo.setList(null);
            // 不分页结果集统计总单数，总保费，总来佣，待来佣总数，已比对总数，已退保总数
            Map<String, Object> summaries = lifeCommissionMapper.getSummaries(requestVO);
            resp.setTotalOrderPrice(summaries.get("totalOrderPrice").toString());
            resp.setTotalCommission(summaries.get("totalCommission").toString());
            resp.setTotalSingular(summaries.get("totalSingular").toString());
            resp.setTotalDaiLaiYong(summaries.get("totalDaiLaiYong").toString());
            resp.setTotalYiBiDui(summaries.get("totalYiBiDui").toString());
            resp.setTotalYiTuiBao(summaries.get("totalYiTuiBao").toString());

            resp.setPage(pageInfo);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CheckComeCommissionResponseVO updateCommissionCheckStatus(CheckComeCommissionRequestVO requestVO) {
        CheckComeCommissionResponseVO resp = new CheckComeCommissionResponseVO();
        List<Long> orderIds = requestVO.getOrderIds();
        String status = requestVO.getCheckStatus();
        String loginId = requestVO.getLoginId();
        String checkBatch = requestVO.getCheckBatch();
        if (StringUtils.isBlank(checkBatch)) {
            resp.setCommonResult(new CommonResult(false, "检核日期不能为空"));
            return resp;
        }
        try {
            // 操作前先检查是否已关账
            // 查询对应订单记录
            List<PoOrder> orders = poOrderDALService.findByIds(orderIds);
            // 查询保单下的所有寿险经纪人的fortune记录
            List<AclCustomerFortune> fortuneList = customerFortuneDalService.queryLifeFortuneListByOrderIds(orderIds);

            // 已关帐的订单，则该笔订单来佣比对状态不能改为待来佣和已比对，但能改为已退保
            // 处理历史记录，暂时关闭
//            this.validateClosed(orders, fortuneList, status);

            String fortuneCommissionPayoutStatus;
            if ("2".equals(status)) {//已比对
                fortuneCommissionPayoutStatus = "2";

            } else if ("3".equals(status)) {//已退保
                fortuneCommissionPayoutStatus = "1";

            } else {//待来佣
                fortuneCommissionPayoutStatus = "1";
            }
            this.updateOrderAndFortune(orderIds, fortuneList, status, fortuneCommissionPayoutStatus, loginId, checkBatch);

            // 订单已退保后发送邮件通知运营
            if ("3".equals(status)) {//已比对
                this.orderCommissionCheckCancelSendMail(orders);
            }

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public QuerycheckBatchListResponseVO querycheckBatchList() {
        QuerycheckBatchListResponseVO resp = new QuerycheckBatchListResponseVO();
        try {
            List<String> checkBatchList = lifeCommissionMapper.querycheckBatchList();

            // 将["2020-12","2020-11"]转为[{“key”:"2020-12","value":null}]
            List<Map<String, String>> dataList = new ArrayList<>();
            for (int i = 0; i < checkBatchList.size(); i++) {
                Map<String, String> map = new HashMap<>();
                map.put("key", checkBatchList.get(i));
                map.put("value", null);
                dataList.add(map);
            }

            resp.setCheckBatchList(dataList);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public ExportComeCommissionResponseVO exportComeCommission(QueryComeCommissionListRequestVO requestVO, HttpServletResponse response) {

        ExportComeCommissionResponseVO responseVO = new ExportComeCommissionResponseVO();

        List<ComeCommissionVO> dataList = lifeCommissionMapper.queryComeCommissionList(requestVO);

        dataList.sort(Comparator.comparing(ComeCommissionVO::getOrderDate).reversed());

        createCSV(dataList, response);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    private void orderCommissionCheckCancelSendMail(List<PoOrder> orders) {
        //发送邮件
        List<String> ccList = systemConfigService.getListConfigValue("CancelPolicyNotifyCommissionChecking");
        List<String> arrList = new ArrayList(ccList);
        String email = arrList.remove(0);
        String[] ccAddresses = arrList.toArray(new String[arrList.size()]);

        StringBuilder messageText = new StringBuilder();
        for (PoOrder order:orders) {
            messageText.append("保单号:").append(order.getPolicyNo()).append("<br>");
        }
        messageText.append("<br>");
        messageText.append("来佣比对已退保，请知悉");

        String subject = "来佣比对已退保";
        sendService.sendEmailOrSMS("email", email, "3", messageText.toString(), null, subject, ccAddresses, "来佣比对已退保", 99, null);
    }

    private void updateOrderAndFortune(List<Long> orderIds, List<AclCustomerFortune> fortuneList, String status, String fortuneCommissionPayoutStatus,
                                       String loginId, String checkBatch) {
        // 获取批次号（如2020-11的字符串）
        Long checkBatchId = this.getOrderCommissionCheckBatch(checkBatch, loginId);
        // 设置order记录的CommissionCheckId
        this.setOrderCommissionCheckId(orderIds, status, checkBatchId, loginId);

        if (fortuneList.size() == 0) {
            return;
        }
        // 批量设置fortune为可发佣
        fortuneList.forEach(f -> {
            f.setCommissionPayoutStatus(fortuneCommissionPayoutStatus);
            f.setCommissionPayoutAt(new Date());
            f.setCommissionPayoutBy(Long.valueOf(loginId));
        });
        if (fortuneList.size() > 0) {
            customerFortuneDalService.updateBatch(fortuneList);
        }
    }

    private void validateClosed(List<PoOrder> orders, List<AclCustomerFortune> fortuneList, String status) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();
        Map<Long, String> orderIdPolicyNoMap = new HashMap<>();
        for (PoOrder o:orders) {
            orderIdPolicyNoMap.put(o.getId(), o.getPolicyNo());
        }
        for (AclCustomerFortune f:fortuneList) {
            if ("4".equals(f.getCommissionPayoutStatus())) {
                stringBuilder.append(orderIdPolicyNoMap.get(f.getOrderId())+" ");
            }
        }
        if (StringUtils.isNotEmpty(stringBuilder.toString())) {
            stringBuilder.append("订单下存在已发放的财富记录，不能改状态");
            if (!"3".equals(status)) {
                throw new Exception(stringBuilder.toString());
            }
        }
    }

    private PageInfo<ComeCommissionVO> queryComeCommissionListPage(QueryComeCommissionListRequestVO requestVO) {
        PageInfo<ComeCommissionVO> page = requestVO.getPage();

        String orderBy = "orderDate desc";

        PageHelper.startPage(page.getPageNum(), page.getPageSize(), orderBy);

        List<ComeCommissionVO> dataList = lifeCommissionMapper.queryComeCommissionList(requestVO);

        PageInfo<ComeCommissionVO> pageInfo = new PageInfo<>(dataList);

        return pageInfo;
    }

    private void setOrderCommissionCheckId(List<Long> orderIds, String status, Long checkBatchId, String loginId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("checkId", checkBatchId);
        paramMap.put("status", status);
        // 获取当前时间
        Date curDate = new Date();
        paramMap.put("checkAt", curDate);
        paramMap.put("checkBy", loginId);

        lifeCommissionMapper.setOrderCommissionCheckId(orderIds, paramMap);
    }

    private Long getOrderCommissionCheckBatch(String OrderCommissionCheckBatch, String loginId) {
        List<OrderCommissonCheck> list = lifeCommissionMapper.findByCheckYearmonth(OrderCommissionCheckBatch);
        OrderCommissonCheck orderCommissonCheck = null;
        if (list.size() > 0) {
            orderCommissonCheck = list.get(0);
        }
        if (orderCommissonCheck == null){
            // 获取当前时间
            Date curDate = new Date();
            orderCommissonCheck = new OrderCommissonCheck();
            orderCommissonCheck.setCheckYearmonth(OrderCommissionCheckBatch);
            orderCommissonCheck.setCreatedAt(curDate);
            orderCommissonCheck.setCreatedBy(loginId);
            orderCommissonCheck.setUpdatedAt(curDate);
            orderCommissonCheck.setUpdatedBy(loginId);
            lifeCommissionMapper.insertOrderCommissionCheck(orderCommissonCheck);
        }
        return orderCommissonCheck.getId();
    }

    private void createCSV(List<ComeCommissionVO> dataList, HttpServletResponse response) {
        String charset = "UTF-8"; // 读取字符编码
        String[] columnName = new String[]{"序号","检核年月","保险公司","保单号","保费","来佣率","来佣金额","来佣状态 ","经纪人","经纪人类型","下单时间","购买方案","产品险种","保险种类","缴费年限","保障期间"};
        String tableName = "YD_Export_ComeCommission";
        String CSV_COLUMN_SEPARATOR = ",";//CSV文件列分隔符
        String CSV_ROW_SEPARATOR = "\r\n";//CSV文件行分隔符
        // 保证线程安全
        StringBuilder buf = new StringBuilder();
        // 组装表头
        for (String title : columnName) {
            buf.append(title).append(CSV_COLUMN_SEPARATOR);
        }
        buf.append(CSV_ROW_SEPARATOR);
        // 组装数据
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (int i = 0; i < dataList.size(); i++) {
                ComeCommissionVO info = dataList.get(i);//遍历每个对象
                buf.append(i + 1).append(CSV_COLUMN_SEPARATOR);
                buf.append("\t").append(info.getCheckDate() == null ? "" : info.getCheckDate()).append("\t").append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getInsurerName()).append(CSV_COLUMN_SEPARATOR);
                buf.append("\t").append(info.getPolicyNo()).append("\t").append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getOrderPrice()).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getCommissionRate()).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getCommissionAmount()).append(CSV_COLUMN_SEPARATOR);
                buf.append(this.transferCommissionCheckStatus(info.getCommissionCheckStatus())).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getName() == null ? "/" : info.getName()).append(CSV_COLUMN_SEPARATOR);
                if ("27".equals(info.getPractitionerTypeId())) {
                    buf.append("产险").append(CSV_COLUMN_SEPARATOR);
                } else if ("28".equals(info.getPractitionerTypeId())) {
                    buf.append("寿险").append(CSV_COLUMN_SEPARATOR);
                } else {
                    buf.append("/").append(CSV_COLUMN_SEPARATOR);
                }
                buf.append("\t").append(info.getOrderDate()).append("\t").append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getPlanName()).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getPlanCategoryName()).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getCategoryName()).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getPayTerm() == null ? "/" : info.getPayTerm()).append(CSV_COLUMN_SEPARATOR);
                buf.append(info.getCoverageTerm() == null ? "/" : info.getCoverageTerm().substring(1)).append(CSV_COLUMN_SEPARATOR);
                buf.append(CSV_ROW_SEPARATOR);
            }
        }
        // 设置文件后缀
        String fn = tableName + System.currentTimeMillis()  + ".csv";
        String headStr = "attachment; filename=\"" + fn + "\"";
        // 设置响应
        response.setContentType("APPLICATION/ms-csv.numberformat");
        response.setCharacterEncoding(charset);
        response.setHeader("Content-Disposition", headStr);
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Pragma", "public");
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            os.write(buf.toString().getBytes("GBK"));
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private String transferCommissionCheckStatus(String commissionCheckStatus) {
        String result = "";
        switch (commissionCheckStatus) {
            case "1" :
                result = "待来佣";
                break;
            case "2" :
                result = "已比对";
                break;
            case "3" :
                result = "已退保";
                break;
        }
        return result;
    }

}
