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.AgPoOrderCommission;
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.commission.AgPoOrderCommissionMapper;
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.CommonUtil;
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;
    @Autowired
    private AgPoOrderCommissionMapper orderCommissionMapper;


    @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<ComeCommissionParams> paramsList = requestVO.getParamsList();
        String status = requestVO.getCheckStatus();
        String loginId = requestVO.getLoginId();
        String checkBatch = requestVO.getCheckBatch();

        if (StringUtils.isBlank(checkBatch)) {
            resp.setCommonResult(new CommonResult(false, "检核日期不能为空"));
            return resp;
        }

        try {
            // 1.检核续年佣金时先判断，前面期数的佣金是否检核过
            this.validateContinuePremium(paramsList);

            // 2.更新财富等信息
            this.processOrderAndFortune(paramsList, status, loginId, checkBatch);

            // 3.更新多年期佣金
            this.updateOrderCommission(paramsList, status, loginId, checkBatch);

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

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

    private void validateContinuePremium(List<ComeCommissionParams> paramsList) throws Exception {
        // 提示信息
        StringBuffer stringBuffer = new StringBuffer("以下来佣的往期来佣未检核： ");

        List<String> commissionNos = new ArrayList<>();
        for (ComeCommissionParams params: paramsList) {
            if (StringUtils.isNotBlank(params.getCommissionNo())) {
                commissionNos.add(params.getCommissionNo());
            }
        }
        String str ="";
        String prefix ="";
        String suffix ="";
        boolean flag = false;
        for (String commissionNo: commissionNos) {

            str = commissionNo;

            if (!"1".equals(suffix)) {

                prefix = str.substring(0, str.length() -1);
                suffix = str.substring(str.length()-1) ;
                // 前一期的来佣编号
                String preCommissionNo = prefix + (Integer.valueOf(suffix) - 1);

                AgPoOrderCommission agPoOrderCommission = orderCommissionMapper.selectByCommissionNo(preCommissionNo);
                if (agPoOrderCommission != null && "1".equals(agPoOrderCommission.getCommissionStatus())) {
                    stringBuffer.append(preCommissionNo).append(" ");
                    flag = true;
                }
            }
        }

        if (flag) {
            throw new Exception(stringBuffer.toString());
        }
    }

    private void processOrderAndFortune(List<ComeCommissionParams> paramsList, String status, String loginId, String checkBatch) {
        // 获取首年度佣金的orderId， 只有首年佣金才更新order记录和fortune记录
        List<Long> orderIds = new ArrayList<>();
        for (ComeCommissionParams params: paramsList) {
            if ("1".equals(params.getCommissionPeriod())) {
                orderIds.add(params.getOrderId());
            }
        }
        if (orderIds.size() == 0) {
            return;
        }

        // 操作前先检查是否已关账
        // 查询对应订单记录
        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);
        }

    }

    private void updateOrderCommission(List<ComeCommissionParams> paramsList, String status, String loginId, String checkBatch) {

        // 获取续年度来佣编号
        List<String> commissionNos = new ArrayList<>();
        for (ComeCommissionParams params: paramsList) {
            if (StringUtils.isNotBlank(params.getCommissionNo())) {
                commissionNos.add(params.getCommissionNo());
            }
        }

        // 获取批次号（如2020-11的字符串）
        Long checkBatchId = this.getOrderCommissionCheckBatch(checkBatch, loginId);
        // 更新检核状态
        for (String commissionNo: commissionNos) {
            AgPoOrderCommission orderCommission = new AgPoOrderCommission();
            orderCommission.setCommissionNo(commissionNo);
            orderCommission.setCommissionCheckId(checkBatchId);
            orderCommission.setCommissionStatus(status);
            orderCommission.setCommissionTime(checkBatch);
            orderCommission.setUpdatedBy(Long.valueOf(loginId));
            orderCommission.setUpdatedAt(new Date());

            orderCommissionMapper.updateBycommissionNo(orderCommission);
        }
    }

    @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(info.getCommissionNo()).append(CSV_COLUMN_SEPARATOR);
                buf.append("\t").append(info.getCommissionYear()).append("\t").append(CSV_COLUMN_SEPARATOR);
                buf.append("\t").append(info.getCommissionTime() == null ? "" : info.getCommissionTime()).append("\t").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;
    }

}
