package com.bcxin.ins.service.preservation.impl;

import com.alibaba.fastjson.JSONObject;
import com.bcxin.ins.core.util.SysDictUtils;
import com.bcxin.ins.dto.Result;
import com.bcxin.ins.service.order.PolicyService;
import com.bcxin.ins.dao.preservation.InsPreservationPayAPIDao;
import com.bcxin.ins.service.preservation.InsPreservationPayAPIService;
import com.bcxin.ins.service.preservation.InsPreservationRecordAPIService;
import com.bcxin.ins.service.preservation.InsPreservationResultSetAPIService;
import com.bcxin.ins.service.user.ClientUserService;
import com.bcxin.ins.core.service.ComDeployConfigService;
import com.bcxin.ins.entity.policy_core.InsPreservationPay;
import com.bcxin.ins.entity.policy_core.InsPreservationRecord;
import com.bcxin.ins.entity.user.SysClientUser;
import com.bcxin.ins.third.gzzrx.changan.GZZRX_CARequestService;
import com.bcxin.ins.third.tyx.changan.TYX_CARequestService;
import com.bcxin.ins.util.*;
import com.bcxin.ins.util.email.EmailModel;
import com.bcxin.ins.util.email.EmailMsgRecordType;
import com.bcxin.ins.util.email.SendEmailAndMsgUtil;
import com.bcxin.ins.vo.*;
import com.bcxin.ins.vo.ConstProp;
import com.bcxin.ins.vo.excel.InsPreservationPayChildExcelVo;
import com.bcxin.ins.vo.excel.InsPreservationPayExcelVo;
import com.bcxin.ins.vo.excel.InsPreservationSettlementExcelVo;
import com.bcxin.ins.vo.excel.RecordDetailExcelVo;
import com.bcxin.mybatisplus.plugins.Page;
import com.bcxin.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.xiaoleilu.hutool.date.DateField;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class InsPreservationPayAPIServiceImpl extends ServiceImpl<InsPreservationPayAPIDao, InsPreservationPay> implements InsPreservationPayAPIService {

    private Logger log =  LoggerFactory.getLogger(InsPreservationPayAPIServiceImpl.class);

    @Autowired
    private InsPreservationPayAPIDao insPreservationPayAPIDao;
    @Autowired
    private InsPreservationRecordAPIService insPreservationRecordAPIService;
    @Autowired
    private ClientUserService userService;
    @Autowired
    private PolicyService policyService;
    @Autowired
    private ComDeployConfigService comDeployConfigService;
    @Autowired
    private InsPreservationResultSetAPIService insPreservationResultSetAPIService;
    @Autowired
    private GZZRX_CARequestService gZZRX_CARequestService;
    @Autowired
    private TYX_CARequestService tYX_CARequestService;

    /**
     * <b>根据前台用户id跟保全缴费条件查询保全缴费表并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param pay_status 批改状态
     * @param start_time 结算开始时间
     * @param end_time 结算最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPay> findInsPreservationPayByKeyword(DwzPage page, Long userId, String pay_status, String start_time, String end_time, String keyword){
        Page<InsPreservationPay> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPay> list = insPreservationPayAPIDao.findInsPreservationPayByKeyword( pageHelper, userId, pay_status, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }

    /**
     * <b>根据前台用户id跟保全缴费条件查询保全缴费表并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param pay_status 批改状态
     * @param start_time 结算开始时间
     * @param end_time 结算最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPayVo> findInsPreservationPayVoByKeyword(DwzPage page, Long userId, String pay_status, String start_time, String end_time, String keyword){
        Page<InsPreservationPayVo> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationPayVoByKeyword( pageHelper, userId, pay_status, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }


    /**
     * <b>根据前台用户id跟保全账单条件查询保全账单并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param pay_status 账单状态
     * @param start_time 账单开始时间
     * @param end_time 账单最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPay> findInsPreservationBillByKeyword(DwzPage page, Long userId, String pay_status, String start_time, String end_time, String keyword){
        Page<InsPreservationPay> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPay> list = insPreservationPayAPIDao.findInsPreservationBillByKeyword( pageHelper, userId, pay_status, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }

    /**
     * <b>根据前台用户id跟保全账单条件查询保全账单并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param pay_status 账单状态
     * @param start_time 账单开始时间
     * @param end_time 账单最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPayVo> findInsPreservationBillVoByKeyword(DwzPage page, Long userId, String pay_status, String start_time, String end_time, String keyword){
        Page<InsPreservationPayVo> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationBillVoByKeyword( pageHelper, userId, pay_status, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }

    /**
     * <b>根据前台用户id跟保全结算条件查询结算单并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param start_time 账单开始时间
     * @param end_time 账单最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPayVo> findInsPreservationSettlementVoByKeyword(DwzPage page, Long userId, String start_time, String end_time, String keyword){
        Page<InsPreservationPayVo> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationSettlementVoByKeyword( pageHelper, userId, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }

    /**
     * <b> 汇总账单导出 </b>
     * @author ZXF
     * @create 2024/04/28 0028 16:14
     * @version
     * @注意事项 </b>
     */
    public void downBillPay(Long userId, String pay_status, String start_time, String end_time, String keyword, HttpServletResponse response){
        Page<InsPreservationPayVo> pageHelper = new Page(1, 65535);
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationBillVoByKeyword( pageHelper, userId, pay_status, start_time, end_time, keyword);
        com.bcxin.ins.util.excel.ExcelUtil<InsPreservationPayExcelVo> util = new com.bcxin.ins.util.excel.ExcelUtil(InsPreservationPayExcelVo.class);
        response.setContentType("application/vnd.ms-excel");
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String((keyword+"汇总账单清单.xls").getBytes("gb2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try(OutputStream os = response.getOutputStream();) {
            List<InsPreservationPayExcelVo> addMap = Lists.newArrayList();
            for(InsPreservationPayVo vo : list){
                addMap.add(new InsPreservationPayExcelVo(vo.getExternal_reference(), vo.getCompany_name(), vo.getApp_role_name(), vo.getRecord_count()
                        , vo.getPredict_total_amount()
                        , vo.getStar_pay_time(), vo.getEnd_pay_time()
                        , vo.getBuild_data()
                        , SysDictUtils.getDictLabel(vo.getPay_status(),"billPayStatus","")
                        , vo.getIs_part()==1?"部分账单":"汇总账单"
                        , vo.getIs_fp()==1?"是":"否"));
            }
            util.exportExcel(addMap, keyword+"汇总账单清单", 65535, os);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <b> 结算单导出 </b>
     * @author ZXF
     * @create 2024/04/28 0028 16:14
     * @version
     * @注意事项 </b>
     */
    public void downSettlementPay(Long userId, String start_time, String end_time, String keyword, HttpServletResponse response){
        Page<InsPreservationPayVo> pageHelper = new Page(1, 65535);
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationSettlementVoByKeyword( pageHelper, userId, start_time, end_time, keyword);
        com.bcxin.ins.util.excel.ExcelUtil<InsPreservationSettlementExcelVo> util = new com.bcxin.ins.util.excel.ExcelUtil(InsPreservationSettlementExcelVo.class);
        response.setContentType("application/vnd.ms-excel");
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String((keyword+"结算单清单.xls").getBytes("gb2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try(OutputStream os = response.getOutputStream();) {
            List<InsPreservationSettlementExcelVo> addMap = Lists.newArrayList();
            for(InsPreservationPayVo vo : list){
                addMap.add(new InsPreservationSettlementExcelVo(vo.getExternal_reference(), vo.getCompany_name(), vo.getRecord_count()
                        , vo.getFact_total_amount()
                        , vo.getBuild_data()
                        , ConstProp.DIGIT_THREE.equals(vo.getPay_status())?"已结算":"-"));
            }
            util.exportExcel(addMap, keyword+"结算单清单", 65535, os);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <b> 汇总账单下属子账单导出 </b>
     * @author ZXF
     * @create 2024/04/28 0028 16:14
     * @version
     * @注意事项 </b>
     */
    public void downChildBillPay(Long userId, Long parentPayId, String pay_status, String start_time, String end_time, String keyword, HttpServletResponse response){
        Page<InsPreservationPayVo> pageHelper = new Page(1, 65535);
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationChildBillVoByKeyword( pageHelper, userId, parentPayId, pay_status, start_time, end_time, keyword);
        com.bcxin.ins.util.excel.ExcelUtil<InsPreservationPayChildExcelVo> util = new com.bcxin.ins.util.excel.ExcelUtil(InsPreservationPayChildExcelVo.class);
        response.setContentType("application/vnd.ms-excel");
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String((keyword+"子账单清单.xls").getBytes("gb2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try(OutputStream os = response.getOutputStream();) {
            List<InsPreservationPayChildExcelVo> addMap = Lists.newArrayList();
            for(InsPreservationPayVo vo : list){
                addMap.add(new InsPreservationPayChildExcelVo(vo.getExternal_reference(), vo.getCompany_name(),vo.getInsurance_name(), vo.getApp_role_name()
                        , SysDictUtils.getDictLabel(vo.getPay_status(),"payStatus","")
                        , vo.getRecord_count(), vo.getAdd_count(), vo.getMinus_count(), vo.getReplace_count(), vo.getPredict_total_amount()
                        , vo.getFact_total_amount(), vo.getStar_pay_time(), vo.getEnd_pay_time()));
            }
            util.exportExcel(addMap, keyword+"子账单清单", 65535, os);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <b> 结算单下属子账单导出 </b>
     * @author ZXF
     * @create 2024/04/28 0028 16:14
     * @version
     * @注意事项 </b>
     */
    public void downChildSettlementBillPay(Long userId, Long parentPayId, String start_time, String end_time, String keyword, HttpServletResponse response){
        Page<InsPreservationPayVo> pageHelper = new Page(1, 65535);
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationChildSettlementVoByKeyword( pageHelper, userId, parentPayId, start_time, end_time, keyword);
        com.bcxin.ins.util.excel.ExcelUtil<InsPreservationPayChildExcelVo> util = new com.bcxin.ins.util.excel.ExcelUtil(InsPreservationPayChildExcelVo.class);
        response.setContentType("application/vnd.ms-excel");
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String((keyword+"子账单清单.xls").getBytes("gb2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try(OutputStream os = response.getOutputStream();) {
            List<InsPreservationPayChildExcelVo> addMap = Lists.newArrayList();
            for(InsPreservationPayVo vo : list){
                addMap.add(new InsPreservationPayChildExcelVo(vo.getExternal_reference(), vo.getCompany_name(),vo.getInsurance_name(), vo.getApp_role_name()
                        , SysDictUtils.getDictLabel(vo.getPay_status(),"payStatus","")
                        , vo.getRecord_count(), vo.getAdd_count(), vo.getMinus_count(), vo.getReplace_count(), vo.getPredict_total_amount()
                        , vo.getFact_total_amount(), vo.getStar_pay_time(), vo.getEnd_pay_time()));
            }
            util.exportExcel(addMap, keyword+"子账单清单", 65535, os);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <b>根据前台用户id/汇总账单id跟保全账单条件查询保全账单并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param parentPayId 汇总账单id
     * @param pay_status 账单状态
     * @param start_time 账单开始时间
     * @param end_time 账单最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPayVo> findInsPreservationChildBillVoByKeyword(DwzPage page, Long userId, Long parentPayId, String pay_status, String start_time, String end_time, String keyword){
        Page<InsPreservationPayVo> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationChildBillVoByKeyword( pageHelper, userId, parentPayId, pay_status, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }

    /**
     * <b>根据前台用户id/结算单id跟保全账单条件查询保全账单并进行分页 </b>
     *
     * @param page 分页
     * @param userId 用户id
     * @param parentPayId 结算单id
     * @param start_time 账单开始时间
     * @param end_time 账单最后时间
     * @param keyword 关键字
     * @return
     * @author ZXF
     * @date 2017年8月3日 下午17:19:24
     * @注意事项 </b>
     * <b>
     */
    public List<InsPreservationPayVo> findInsPreservationChildSettlementVoByKeyword(DwzPage page, Long userId, Long parentPayId, String start_time, String end_time, String keyword){
        Page<InsPreservationPayVo> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
        List<InsPreservationPayVo> list = insPreservationPayAPIDao.findInsPreservationChildSettlementVoByKeyword( pageHelper, userId, parentPayId, start_time, end_time, keyword);
        page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
        return list;
    }

    /**
     * <b>根据页面勾选条目生成部分账单 </b>
     * @param isSummaryBill 是否为汇总账单
     * @param payIds 勾选数据列的id集合
     * @author ZXF
     * @create 2024/04/26 0026 11:07
     * @version
     * @注意事项 </b>
     */
    public JSONObject createPartBill(String isSummaryBill, String[] payIds){

        JSONObject json = new JSONObject();
        if(payIds==null || payIds.length<1){
            json.put("status", ConstProp.CODE_FAILURE);
            json.put("msg", "无有效账单");
            return json;
        }
        //TODO 需要判断如果不是汇总账单id归属账单不能只有这单一单，如果是汇总账单id不能只有1个
        if(ConstProp.DIGIT_ONE.equals(isSummaryBill)){
            //汇总账单
            //payIds>1
            if(payIds.length<2){
                json.put("status", ConstProp.CODE_FAILURE);
                json.put("msg", "单条汇总账单可直接完成缴费业务");
                return json;
            }
            //未被标记的子账单数大于1，并且分属多个汇总账单（>1）（子账单都被生成部分账单的，列表控制不能勾选）

        }else{
            //子账单
            //payIds不能包含有被标记的记录
            String partBillSign = insPreservationPayAPIDao.isPartBillSign(payIds);
            if(StringUtils.isNotEmpty(partBillSign)){
                json.put("status", ConstProp.CODE_FAILURE);
                json.put("msg", "这些账单编码已生成部分账单，无法重复生成："+partBillSign);
                return json;
            }
            //同个上级账单
            List<Map<String,String>> isConsistentSummaryBill = insPreservationPayAPIDao.isConsistentSummaryBill(payIds);
            if(isConsistentSummaryBill.size() == 1){
                Map<String,String> map = isConsistentSummaryBill.get(0);
                if(ConstProp.DIGIT_ONE.equals(map.get("isAll"))){
                    json.put("status", ConstProp.CODE_FAILURE);
                    json.put("msg", "操作对象归属同一账单，无法重复生成："+map.get("external_reference"));
                    return json;
                }
            }
        }

        //是否险种一致
        int isConsistent = insPreservationPayAPIDao.isConsistentInsurancePlan(isSummaryBill,payIds);
        if(isConsistent>1){
            json.put("status", ConstProp.CODE_FAILURE);
            json.put("msg", "账单险种不一致，无法合并");
            return json;
        }

        List<InsPreservationPay> billMergeList = insPreservationPayAPIDao.consistentBillMerge(isSummaryBill,payIds);
        IdWorker idWorker = new IdWorker(ConstProp.INT_NUMBER_WORKERID, ConstProp.INT_NUMBER_ZERO);
        Long ins_preservation_pay_id;
        String[] pays;
        for (InsPreservationPay ipPay:billMergeList) {
            ins_preservation_pay_id = idWorker.nextId();
            ipPay.setExternal_reference("BFZD"+ins_preservation_pay_id);
            ipPay.setIns_preservation_pay_id(ins_preservation_pay_id);
            ipPay.setParent_part_bill_id(ins_preservation_pay_id);//父部分账单id是自己
            pays = ipPay.getPay_list().split(",");
            insertOrUpdate(ipPay);
            //状态都改成 支付中
            insPreservationPayAPIDao.updateParentPartBillId(ins_preservation_pay_id,ConstProp.DIGIT_FIVE,pays);
        }

        json.put("status", ConstProp.CODE_SUCCESS);
        json.put("msg", "部分账单完成合并");
        return json;
    }

    public JSONObject createPartBillByNo(String isSummaryBill, String[] payNos){
        String payIds = insPreservationPayAPIDao.findPayIdsByPayNos(payNos);
        return createPartBill(isSummaryBill,payIds.split(","));
    }

    /**
     * 根据保全缴费id查询保全缴费详情及关联保全申请单信息
     * @param oid
     * @return
     */
    public InsPreservationPayVo findIPPayVoById(Long oid){
        return insPreservationPayAPIDao.findInsPreservationPayVoById(oid);
    }

    /**
     * 根据保全缴费id查询保全缴费详情及关联保全申请单信息
     * @param oid
     * @return
     */
    public InsPreservationPayVo findInsPreservationPayVoById(Long oid){
        InsPreservationPayVo vo = insPreservationPayAPIDao.findInsPreservationPayVoById(oid);
        vo.setInsPreservationRecordVoList(insPreservationRecordAPIService.findInsPreservationRecordVoByPayId(null,oid, ConstProp.BLANK_CHAR));
        return vo;
    }

    /**
     * 文件上传并返回下载地址
     * @param roleFile 上传文件
     * @param savePath 文件要保存的文件夹地址（/policy/）
     * @return /getResource?path=/policy/1231231.jpg
     */
    public String uploadFile(MultipartFile roleFile,String savePath){
        String result = "";
        if (!roleFile.isEmpty()) {
            try {
                String fileName = roleFile.getOriginalFilename(); 	//上传文件名
                String materialFileType = fileName.split("\\.")[1]; //文件类型
                String files = DateUtil.generatorRadomNumber() + "." + materialFileType;
                result = savePath + files;
                String path = GlobalResources.COM_IMG_RE+savePath;
                FileHelp.mFile(roleFile, path, files);
                result = "/getResource?path="+result;
            } catch (Exception e) {
                e.printStackTrace();
                result = "";
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
        return result;
    }

    public boolean savePayPath(Long oid, String path){
        boolean flag = true;
        try {
            InsPreservationPay insPreservationPay = selectById(oid);
            if(StringUtils.isNotEmpty(insPreservationPay.getPay_order_path())){
                path = insPreservationPay.getPay_order_path()+"||"+path;
            }
            insPreservationPay.setPay_order_path(path);
            insPreservationPay.setPay_status(DictConst.RECORD_PAY_STATUS_DSH);
            updateById(insPreservationPay);
//            sendEmailByCheckPending(insPreservationPay);
        } catch (Exception e) {
            flag = false;
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return flag;
    }

    /**
     * 保全缴费-待审核 发送邮件
     * 发送方：系统（bot）
     * 接收方：运营人员
     *
     * @param ipp 保全缴费类
     */
    private void sendEmailByCheckPending(InsPreservationPay ipp) {
        SysClientUser user = userService.selectById(ipp.getSys_client_user_id());
        String[] arrs = comDeployConfigService.getValueByKey("exmail").split(ConstProp.SEMICOLON);
        EmailModel emailModel = new EmailModel(EmailMsgRecordType.PAY_CHECK_PENDING, user.getReal_name()==null? ConstProp.MINUS : user.getReal_name(), user.getLogin_name(), ipp.getExternal_reference(), DateUtil.convertDateToString(ipp.getStar_pay_time(),DateUtil.FORMAT2), DateUtil.convertDateToString(ipp.getEnd_pay_time(),DateUtil.FORMAT2) );
        log.info("保全缴费上传支付凭证邮件发送（内容htmlContent）:"+emailModel.getContent());
        List<String> emailList = new ArrayList<String>();
        for(int i=0;i<arrs.length;i++){
            if(StringUtils.isNotBlank(arrs[i]) && !arrs[i].contains(ConstProp.COLON)){
                emailList.add(arrs[i].trim()); // 发送地址
                log.info("保全缴费上传支付凭证邮件发送（收件人Email-"+(i+1)+"）:"+arrs[i]);
            }
        }
        if(emailList.size()>0){
            emailModel.setTo(emailList);
            SendEmailAndMsgUtil.sendEmail(emailModel);
        }
    }

    /**
     * 根据不同的结算类型检索状态为4的保全缴费单，对其做状态变更为0
     * @param paymentType
     */
    public void findInsPreservationPayByPaymentType(String paymentType){
        List<String> idList = insPreservationPayAPIDao.findInsPreservationPayIdsByPaymentType(paymentType);
        if(idList.size()>0){
            insPreservationPayAPIDao.updateStatusById(DictConst.RECORD_PAY_STATUS_DZF,(String[])idList.toArray());
        }
    }

    /**
     * <b> 每月汇总分组账单，并对归属账单做标记（设置上级账单） </b>
     * @author ZXF
     * @create 2024/04/23 0023 15:10
     * @version
     * @注意事项 </b>
     */
    public void createInsPreservationBillByThisMonth(String lastMonth){
        List<InsPreservationPay> ippInitList = insPreservationPayAPIDao.selectRecordBillBylastMonth(lastMonth);
        IdWorker idWorker = new IdWorker(ConstProp.INT_NUMBER_WORKERID, ConstProp.INT_NUMBER_ZERO);
        Long ins_preservation_pay_id;
        String[] pays;
        for (InsPreservationPay ipPay:ippInitList) {
            ins_preservation_pay_id = idWorker.nextId();
            ipPay.setExternal_reference("ZD"+ins_preservation_pay_id);
            ipPay.setIns_preservation_pay_id(ins_preservation_pay_id);
            pays = ipPay.getPay_list().split(",");
            insertOrUpdate(ipPay);
            insPreservationPayAPIDao.updateParentPayId(ins_preservation_pay_id,pays);
        }

    }

    /**
     * <b> 生成保单初始月结账单记录 </b>
     * @author ZXF
     * @create 2024/04/23 0023 15:10
     * @version
     * @注意事项 </b>
     */
    public void createInsPreservationPayByThisMonth(String policyNo,Date star,Date end){
        //查询所有有效保单：当月、未生成交易记录、产品为雇主或团意险
        try {
            List<InsPreservationPay> ippInitList = insPreservationPayAPIDao.selectNotHavePayByThisMonth(policyNo,star,end);
            IdWorker idWorker = new IdWorker(ConstProp.INT_NUMBER_WORKERID, ConstProp.INT_NUMBER_ZERO);
            for (InsPreservationPay ipPay:ippInitList) {
                ipPay.setIns_preservation_pay_id(idWorker.nextId());
                insertOrUpdate(ipPay);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * <b>
     *     统计多保全申请单人员及统计保险费用，设置到保全缴费单中
     *     通过保全单信息初始化生成保全缴费记录
     *     TODO 根据具体情况可能需要传入参数：支付号，支付地址
     * </b>
     * @param record 保全信息
     * @param map 批改接口信息
     * @author ZXF
     * @create 2018/05/31 0031 17:12
     * @version
     * @注意事项 </b>
     */
    @Override
    public boolean setIPPay(InsPreservationRecord record, Map<String,String> map) {
        try {
            //如果增员在线支付直接生成支付记录
            if(DictConst.REVISE_TYPE_Z.equals(record.getRevise_type())
                    &&DictConst.REVISE_STATUS_TG.equals(record.getRevise_status())
                    &&StringUtils.isNotEmpty(record.getRevise_pay())){
                InsPreservationPay ipPay = new InsPreservationPay();
                IdWorker idWorker = new IdWorker(ConstProp.INT_NUMBER_WORKERID, ConstProp.INT_NUMBER_ZERO);
                ipPay.setSys_client_user_id(record.getSys_client_user_id());
                ipPay.setSys_ins_company_id(record.getSys_ins_company_id());
                ipPay.setIns_insurance_slip_id(record.getIns_insurance_slip_id());
                ipPay.setExternal_reference(record.getExternal_reference());
                ipPay.setApp_role_name(record.getApp_role_name());
                ipPay.setIns_preservation_pay_id(idWorker.nextId());
                ipPay.setStar_pay_time(record.getStart_time());
                ipPay.setEnd_pay_time(new Date());
                ipPay.setPay_status(DictConst.RECORD_PAY_STATUS_YZF);
                ipPay.setRecord_count(1);
                ipPay.setAdd_count(record.getAdd_count());
                ipPay.setReplace_count(0);
                ipPay.setMinus_count(0);
                ipPay.setPredict_total_amount(record.getTotal_premium());
                ipPay.setPay_url(record.getRevise_pay());
                System.out.println("=========== setIPPay:1");
                insPreservationPayAPIDao.insert(ipPay);
                System.out.println("=========== setIPPay:2");
                record.setIns_preservation_pay_id(ipPay.getIns_preservation_pay_id());//将随机生成的payid设置到record中去
                insPreservationRecordAPIService.updateById(record);
                System.out.println("=========== setIPPay:3");
                insPreservationResultSetAPIService.updateResultSet(record.getIns_preservation_record_id(),record.getRevise_type());//人员更新结果集
                return true;
            }

            System.out.println("=========== setIPPay:4");
            Date star = DateUtil.convertString2Date(DateUtil.convertDateToString(DateUtil.getFirstDayOfThisMonth(),DateUtil.FORMAT2)+" 00:00:00");
            Date end = DateUtil.convertString2Date(DateUtil.convertDateToString(DateUtil.getLastDayOfThisMonth(),DateUtil.FORMAT2)+" 23:59:59");
            //查询保单号、月份已初始化的账单记录
            InsPreservationPay ipPay = insPreservationPayAPIDao.getPayExAndMonth(record.getExternal_reference(), star, end);
            if(ipPay == null){
                System.out.println("=========== setIPPay:5");
                //先检测保单号是否已经初始化账单记录，没有就初始化
                createInsPreservationPayByThisMonth(record.getExternal_reference(), star, end);
                ipPay = insPreservationPayAPIDao.getPayExAndMonth(record.getExternal_reference(), star, end);
            }
            String payStatus = ConstProp.DIGIT_FOUR;//支付状态先设置为 4 暂存单
            BigDecimal premium = record.getTotal_premium();
            int recordCount= ipPay.getRecord_count();
            int addCount= ipPay.getAdd_count();
            int minusCount= ipPay.getMinus_count();
            int replaceCount = ipPay.getReplace_count();
            BigDecimal predictTotal=ipPay.getPredict_total_amount();

            predictTotal = predictTotal.add(premium);
            record.setIns_preservation_pay_id(ipPay.getIns_preservation_pay_id());//将随机生成的payid设置到record中去
            System.out.println("=========== setIPPay:6");
            insPreservationRecordAPIService.updateById(record);
            System.out.println("=========== setIPPay:7");
            insPreservationResultSetAPIService.updateResultSet(record.getIns_preservation_record_id(),record.getRevise_type());//人员更新结果集
            //每一单更新的数据

            System.out.println("=========== setIPPay:8");
            //计算，每一单都要
            recordCount++;
            //增员人员统计
            addCount += record.getAdd_count();
            minusCount += record.getMinus_count();//减员人员统计
            replaceCount += record.getReplace_count();//替换人员统计
            //总金额累加
            ipPay.setPay_status(payStatus);
            ipPay.setRecord_count(recordCount);
            ipPay.setAdd_count(addCount);
            ipPay.setReplace_count(replaceCount);
            ipPay.setMinus_count(minusCount);
            ipPay.setPredict_total_amount(predictTotal);

            if (!insertOrUpdate(ipPay)) {
                System.out.println("=========== setIPPay:9");
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;
            }
            System.out.println("=========== setIPPay:10");
            return true;
        } catch (Exception e) {
            log.error("保全缴费信息初始化插入，事务发现异常，回滚数据", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    /**
     * <b>
     *     根据批改单号查询保全缴费单，修改状态为已支付
     * </b>
     * @param serial_num 批改单号
     * @author ZXF
     * @create 2018/06/06 0006 17:54
     * @version
     * @注意事项 </b>
     */
    public boolean updatePayStatusBySerialNum(String serial_num){
        InsPreservationRecord record = insPreservationRecordAPIService.findInsPreservationRecordByBySerialNum(serial_num);
        if(record != null){
            InsPreservationPay pay = selectById(record.getIns_preservation_pay_id());
            if(pay != null){
                pay.setPay_status(DictConst.RECORD_PAY_STATUS_YZF);
                pay.setFact_total_amount(pay.getPredict_total_amount());
                pay.setEnd_pay_time(new Date());
                updateById(pay);
                return true;
            }
        }
        return false;
    }

    /**
     * <b> 获取缴费记录的电子发票 </b>
     * @author ZXF
     * @create 2021/11/04 0004 15:15
     * @version
     * @注意事项 </b>
     */
    @Override
    public Result getFP(Long oid){
        InsPreservationPay pay = selectById(oid);
        if(pay==null){
            return Result.fail("账单记录不存在！");
        }
        if(StringUtils.isNotEmpty(pay.getFp_url())){
            return Result.success(Result.SUCCESS_MSG,pay.getFp_url());
        }
        pay.setIs_fp(1);
        insPreservationPayAPIDao.updateById(pay);
        return Result.success("申请已成功提交！");
        /*String rec = insPreservationPayAPIDao.getRecordCode(oid);
        if(StringUtils.isEmpty(rec)){
            return Result.fail("记录未关联有效批单！");
        }
        OrderFormVo vo = policyService.accordingToOrderIDToGetPolicyDto(pay.getIns_insurance_slip_id());
        if(vo == null){
            return Result.fail("未找到有效订单！");
        }
        String result = "300#该保单未开通在线开票功能";
        if(vo.getProduct_code().contains("GZZRX-CA")){
            result = gZZRX_CARequestService.request_ca_dzfp(pay.getIns_insurance_slip_id()
                    ,"22",rec
                    ,DateUtil.convertDateToString(pay.getStar_pay_time(),DateUtil.FORMAT2)
                    ,DateUtil.convertDateToString(pay.getEnd_pay_time(),DateUtil.FORMAT2));
        }else if(vo.getProduct_code().contains("TYX-CA")){
            result = tYX_CARequestService.request_ca_dzfp(pay.getIns_insurance_slip_id()
                    ,"22",rec
                    ,DateUtil.convertDateToString(pay.getStar_pay_time(),DateUtil.FORMAT2)
                    ,DateUtil.convertDateToString(pay.getEnd_pay_time(),DateUtil.FORMAT2));
        }
        if(result.contains("200#")){
            String url = result.replace("200#","");
            insPreservationPayAPIDao.updateFpUrl(oid,url);
            return Result.success(Result.SUCCESS_MSG,url);
        }
        return Result.fail(result.replace("300#",""));*/
    }

    @Override
    public boolean getFPTask(Long oid){
        InsPreservationPay pay = selectById(oid);
        if(pay==null){
            return true;
        }
        if(StringUtils.isNotEmpty(pay.getFp_url())){
            return true;
        }
        String rec = insPreservationPayAPIDao.getRecordCode(oid);
        if(StringUtils.isEmpty(rec)){
            return true;
        }
        OrderFormVo vo = policyService.accordingToOrderIDToGetPolicyDto(pay.getIns_insurance_slip_id());
        if(vo == null){
            return true;
        }
        String result = "300#该保单未开通在线开票功能";
        if(vo.getProduct_code().contains("GZZRX-CA")){
            result = gZZRX_CARequestService.request_ca_dzfp(pay.getIns_insurance_slip_id()
                    ,"22",rec
                    ,DateUtil.convertDateToString(pay.getStar_pay_time(),DateUtil.FORMAT2)
                    ,DateUtil.convertDateToString(pay.getEnd_pay_time(),DateUtil.FORMAT2));
        }else if(vo.getProduct_code().contains("TYX-CA")){
            result = tYX_CARequestService.request_ca_dzfp(pay.getIns_insurance_slip_id()
                    ,"22",rec
                    ,DateUtil.convertDateToString(pay.getStar_pay_time(),DateUtil.FORMAT2)
                    ,DateUtil.convertDateToString(pay.getEnd_pay_time(),DateUtil.FORMAT2));
        }
        if(result.contains("200#")){
            String url = result.replace("200#","");
            url = url.replace("*","#");
            insPreservationPayAPIDao.updateFpUrl(oid,url);
            return true;
        }
        return false;
    }
}
