package cn.com.countrygarden.bi.main.service.mediaResource.impl;


import cn.com.countrygarden.bi.main.constant.mediaResource.MediaResourceConstant;
import cn.com.countrygarden.bi.main.core.AbstractService;
import cn.com.countrygarden.bi.main.dao.mediaResource.*;
import cn.com.countrygarden.bi.main.dto.mediaResource.MediaOrderBillDto;
import cn.com.countrygarden.bi.main.dto.mediaResource.MediaOrderDto;
import cn.com.countrygarden.bi.main.dto.mediaResource.MediaOrderRunDto;
import cn.com.countrygarden.bi.main.dto.mediaResource.MediaResourceDto;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.PageData;
import cn.com.countrygarden.bi.main.model.mediaResource.*;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysUser;
import cn.com.countrygarden.bi.main.service.mediaResource.CustomerService;
import cn.com.countrygarden.bi.main.service.mediaResource.MediaCommonService;
import cn.com.countrygarden.bi.main.service.mediaResource.MediaOrderService;
import cn.com.countrygarden.bi.main.service.mediaResource.MediaResourceNewService;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbSysUserService;
import cn.com.countrygarden.bi.main.util.AuditUtil;
import cn.com.countrygarden.bi.main.util.DateUtil;
import cn.com.countrygarden.bi.main.util.PageUtil;
import cn.com.countrygarden.bi.main.util.SnowflakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <pre>
 *  媒体资源订单服务
 * </pre>
 *
 * @author ferren  liao-r@neusoft.com
 * @version 1.00.00
 * <p>
 * <p>
 * <pre>
 * 修改记录
 *    修改后版本:     修改人：  修改日期:     修改内容:
 * </pre>
 */
@Service
public class MediaOrderServiceImpl extends AbstractService<MediaOrder> implements MediaOrderService {
    @Autowired
    private MediaOrderMapper mediaOrderMapper;
    @Autowired
    private MediaOrderBillMapper mediaOrderBillMapper;
    @Autowired
    private MediaOrderRunMapper mediaOrderRunMapper;
    @Autowired
    private MediaOrderRunBillMapper mediaOrderRunBillMapper;
    @Autowired
    private MediaOrderCycleMapper mediaOrderCycleMapper;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private TbSysUserService tbSysUserService;
    @Autowired
    private MediaResourceNewService mediaResourceNewService;
    @Autowired
    private MediaCommonService mediaCommonService;
    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private AdvertistingReserveMapper advertistingReserveMapper;

    @Override
    public PageData select(MediaOrderDto param) {
        PageUtil.setPageOffset(param);
        List<MediaOrderDto> list = mediaOrderMapper.findList(param);
        setProperty(list);
        Long total = mediaOrderMapper.findCount(param);
        return PageUtil.setPageData(param, total, list);
    }

    @Override
    public List<MediaOrderDto> selectList(MediaOrderDto param) {
        List<MediaOrderDto> list = mediaOrderMapper.findList(param);
        setProperty(list);
        return list;
    }

    /**
     * 设置业务属性
     *
     * @param list
     */
    private void setPropertyOfOrderBill(List<MediaOrderBillDto> list) {
        for (MediaOrderBillDto dto : list) {
            setNameOfOrderBill(dto);
        }
    }


    /**
     * 转换码值
     *
     * @param dto
     * @return
     */
    private MediaOrderBillDto setNameOfOrderBill(MediaOrderBillDto dto) {
        // 媒体类型
        Integer mediaType = dto.getMediaType();
        String mediaTypeName = MediaResourceConstant.MEDIA_TYPE.DES.getOrDefault(mediaType, "");
        dto.setMediaTypeName(mediaTypeName);
        // 订单类型
        Integer orderStatus = dto.getOrderStatus();
        String orderStatusName = MediaResourceConstant.ORDER_STATUS_TYPE.DES.getOrDefault(orderStatus, "");
        dto.setOrderStatusName(orderStatusName);
        // 客户类型
        Integer customerType = dto.getCustomerType();
        String customerTypeName = MediaResourceConstant.CUSTOMER_TYPE.DES.getOrDefault(customerType, "");
        dto.setCustomerTypeName(customerTypeName);
        // 资源状态
        Integer cycleStatus = dto.getCycleStatus();
        String cycleStatusName = MediaResourceConstant.CYCLE_STATUS.DES.getOrDefault(cycleStatus, "");
        dto.setCycleStatusName(cycleStatusName);
        // 资源形式
        String mediaForm = dto.getMediaForm();
        Integer form = mediaForm != null ? Integer.parseInt(mediaForm) : -1;
        String mediaFormName = MediaResourceConstant.MEDIA_FORM.DES.getOrDefault(form, "");
        dto.setMediaFormName(mediaFormName);
        return dto;
    }

    /**
     * 转换码值
     *
     * @param orderDto
     * @return
     */
    private MediaOrderDto setNameOfOrder(MediaOrderDto orderDto) {
        // 媒体类型
        Integer mediaType = orderDto.getMediaType();
        String mediaTypeName = MediaResourceConstant.MEDIA_TYPE.DES.getOrDefault(mediaType, "");
        orderDto.setMediaTypeName(mediaTypeName);
        // 订单状态
        Integer orderStatus = orderDto.getOrderStatus();
        String orderStatusName = MediaResourceConstant.ORDER_STATUS_TYPE.DES.getOrDefault(orderStatus, "");
        orderDto.setOrderStatusName(orderStatusName);

        // 在今天之后, 执行好的状态为已完成
        if (MediaResourceConstant.ORDER_STATUS_TYPE.RUN.equals(orderStatus)) {
            if (orderDto.getOrderEndDate().compareTo(DateUtil.parseDate(DateUtil.simpleFormat(new Date()))) <= 0) {
                orderDto.setOrderStatusName(MediaResourceConstant.ORDER_STATUS_TYPE.DES
                        .getOrDefault(MediaResourceConstant.ORDER_STATUS_TYPE.DONE, ""));
            }
        }

        // 客户类型
        Integer customerType = orderDto.getCustomerType();
        String customerTypeName = MediaResourceConstant.CUSTOMER_TYPE.DES.getOrDefault(customerType, "");
        orderDto.setCustomerTypeName(customerTypeName);
        // 资源形式
        String mediaForm = orderDto.getMediaForm();
        Integer form = mediaForm != null ? Integer.parseInt(mediaForm) : -1;
        String mediaFormName = MediaResourceConstant.MEDIA_FORM.DES.getOrDefault(form, "");
        orderDto.setMediaFormName(mediaFormName);
        return orderDto;
    }

    /**
     * 转换码值
     *
     * @param list
     * @return
     */
    private List<MediaOrderDto> setProperty(List<MediaOrderDto> list) {
        boolean adminRole = mediaCommonService.isAdminRole();
        for (MediaOrderDto orderDto : list) {
            setNameOfOrder(orderDto);
            if (!adminRole) {
                String userCode = tbSysUserService.getCurrentSysUser().getUserCode();
                if (!userCode.equals(orderDto.getCustomerCreateBy())) {
                    orderDto.setContactPhone("***");
                    orderDto.setContactName("***");
                }
                // boolean areaRole = mediaCommonService.isAreaRole();
            }

        }
        return list;
    }

    @Override
    public List<MediaOrderBillDto> selectBillList(String orderId) {
        List<MediaOrderBillDto> list = mediaOrderMapper.findBillList(orderId);
        setPropertyOfOrderBill(list);
        return list;
    }

    /**
     * 锁定订单
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    public boolean lockBill(MediaOrderDto param) {
        String orderId = param.getOrderId();
        if (param.getOrderId() == null) {
            throw new ServiceException("orderId 参数不能为空");
        }

        // 判断订单状态
        MediaOrder mediaOrder = mediaOrderMapper.selectByPrimaryKey(Long.parseLong(orderId));
        if (mediaOrder == null) {
            throw new ServiceException("不存在该订单!");
        }

        int orderStatus = mediaOrder.getOrderStatus();
        /*if (!MediaResourceConstant.ORDER_STATUS_TYPE.RESERVE.equals(orderStatus)) {
            throw new ServiceException("预定订单才能进行锁定操作");
        }*/

        List<MediaOrderBillDto> paramBillDtos = param.getOrderBillDtos();

        // 查询对应
        MediaOrderBill paramOrderBill = new MediaOrderBill();
        paramOrderBill.setIsDelete(0);
        paramOrderBill.setOrderId(Long.parseLong(orderId));
        List<MediaOrderBill> allOrderBills = mediaOrderBillMapper.select(paramOrderBill);

        updateOrderBillsOfLock(param, paramBillDtos, allOrderBills);
        MediaOrder order = new MediaOrder();
        updateOrderOfLock(order, param);

        return true;
    }

    /**
     * 执行订单
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    public boolean runBill(MediaOrderDto param) {
        String orderId = param.getOrderId();
        if (orderId == null) {
            throw new ServiceException("orderId 参数不能为空");
        }

        // 初始化参数
        List<MediaOrderBillDto> paramBillDtos = param.getOrderBillDtos();
        Date nowDate = new Date();
        param.setCreateTime(nowDate);

        // 判断订单状态
        MediaOrder order = mediaOrderMapper.selectByPrimaryKey(Long.parseLong(orderId));
        if (order == null || order.getIsDelete() == 1) {
            throw new ServiceException("该订单已不存在,请刷新后重试");
        }

        String customerId = order.getCustomerId();
        if (customerId == null) {
            if (param.getCustomerId() == null) {
                throw new ServiceException("请填入客户信息!");
            } else {
                order.setCustomerId(param.getCustomerId());
            }
        }
        Customer customer = customerMapper.selectByPrimaryKey(Long.parseLong(order.getCustomerId()));
        param.setCustomerType(customer.getCustomerType());

        // 新增执行单及明细
        MediaOrderRun run = new MediaOrderRun();
        insertOrderRun(order, run, param);
        insertRunBill(order, run, paramBillDtos);

        // 更新订单及明细
        updateOrderBillsOfRun(param, paramBillDtos);
        // 设置金额
        List<MediaOrderBillDto> byRunId = mediaOrderBillMapper.findByOrderId(run.getOrderId());
        BigDecimal orderAmount = new BigDecimal(0);
        for (MediaOrderBillDto ele : byRunId) {
            BigDecimal orderSingleAmount = ele.getOrderBillAmount();
            if (orderSingleAmount != null) {
                orderAmount = orderAmount.add(orderSingleAmount);
            }
        }
        //order.setOrderAmount(orderAmount);
        updateOrderOfRun(order, param);
        return true;
    }

    @Override
    @Transactional
    public boolean unlockBill(MediaOrderDto param) {
        String orderId = param.getOrderId();
        TbSysUser currentSysUser = tbSysUserService.getCurrentSysUser();
        // 初始化参数
        List<MediaOrderBillDto> paramBillDtos = param.getOrderBillDtos();
        Date nowDate = new Date();
        param.setCreateTime(nowDate);

        // 判断订单状态
        MediaOrder order = mediaOrderMapper.selectByPrimaryKey(Long.parseLong(orderId));

        int orderStatus = order.getOrderStatus();
        /*if (MediaResourceConstant.ORDER_STATUS_TYPE.RUN.equals(orderStatus)) {
            throw new ServiceException("订单已经开始执行，不允许取消锁定");
        }*/

        MediaOrderBill paramOrderBill = new MediaOrderBill();
        paramOrderBill.setIsDelete(0);
        paramOrderBill.setOrderId(order.getOrderId());
        List<MediaOrderBill> orderBills = mediaOrderBillMapper.select(paramOrderBill);
        List<String> orderBillIds = new ArrayList<>();
        for (MediaOrderBill orderBill : orderBills) {
            orderBillIds.add(orderBill.getOrderBillId());
        }

        int i = 0;
        // 解锁
        for (MediaOrderBillDto paramBillDto : paramBillDtos) {
            if (!orderBillIds.contains(paramBillDto.getOrderBillId())) {
                continue;
            } else {
                i = i + 1;
            }
            // todo 冗余
            MediaOrderBill orderBill = mediaOrderBillMapper.selectByPrimaryKey(paramBillDto.getOrderBillId());
            if (!MediaResourceConstant.CYCLE_STATUS.LOCK.equals(Integer.parseInt(orderBill.getCycleStatus()))) {
                String mediaCode = mediaOrderCycleMapper.findMediaResourceCode(orderBill.getMediaId());
                throw new ServiceException("锁定状态的资源才能进行解锁操作!" + "资源编号" + mediaCode + "非锁定状态");
            }

            // todo 校验数据
            Date lockStartDate = orderBill.getLockStartDate();
            Date lockEndDate = orderBill.getLockEndDate();
            // 解锁
            mediaOrderCycleMapper.deleteCycle(lockStartDate, lockEndDate, orderBill.mediaId);

            MediaOrderBill bill = new MediaOrderBill();
            bill.setOrderBillId(orderBill.orderBillId);
            bill.setCycleStatus(MediaResourceConstant.CYCLE_STATUS.NO_USE + "");
            AuditUtil.setAuditProperty(currentSysUser, false, bill, nowDate);
            mediaOrderBillMapper.updateByPrimaryKeySelective(bill);
        }
        // 全部解锁则终止
        MediaOrder paramOrder = new MediaOrder();

        // 全部终止 订单设置为终止
        MediaOrderBill paramFinal = new MediaOrderBill();
        paramFinal.setOrderId(Long.parseLong(orderId));
        List<MediaOrderBill> allOrderBills = mediaOrderBillMapper.select(paramOrderBill);
        int count = 0;
        for (MediaOrderBill allOrderBill : allOrderBills) {
            if (allOrderBill.getCycleStatus().equals(MediaResourceConstant.CYCLE_STATUS.NO_USE.toString())) {
                count = count + 1;
            }
        }

        if (count == orderBillIds.size()) {
            paramOrder.setOrderStatus(MediaResourceConstant.ORDER_STATUS_TYPE.FINAL);
        }

        paramOrder.setOrderId(order.getOrderId());
        AuditUtil.setAuditProperty(currentSysUser, false, paramOrder, nowDate);
        mediaOrderMapper.updateByPrimaryKeySelective(paramOrder);

        return true;
    }

    @Override
    public MediaOrderDto orderDetail(MediaOrderDto param) {

        return null;
    }

    @Override
    @Transactional
    public boolean finalBill(MediaOrderDto param) {
        String orderId = param.getOrderId();
        TbSysUser currentSysUser = tbSysUserService.getCurrentSysUser();
        // 初始化参数
        List<MediaOrderBillDto> paramBillDtos = param.getOrderBillDtos();
        Date nowDate = new Date();
        param.setCreateTime(nowDate);

        // 判断订单状态
        MediaOrder order = mediaOrderMapper.selectByPrimaryKey(Long.parseLong(orderId));
        if (!MediaResourceConstant.ORDER_STATUS_TYPE.RUN.equals(order.getOrderStatus())) {
            throw new ServiceException("执行状态的订单才能终止!");
        }

        // 查询非删除的项
        MediaOrderBill paramOrderBill = new MediaOrderBill();
        paramOrderBill.setIsDelete(0);
        paramOrderBill.setOrderId(order.getOrderId());
        List<MediaOrderBill> orderBills = mediaOrderBillMapper.select(paramOrderBill);

        List<String> orderBillIds = new ArrayList<>();
        for (MediaOrderBill orderBill : orderBills) {
            orderBillIds.add(orderBill.getOrderBillId());
        }

        // List转Map
        Map<String, MediaOrderBill> paramBillMap =
                orderBills.stream().collect(Collectors.toMap(MediaOrderBill::getOrderBillId, a -> a, (k1, k2) -> k1));

        int i = 0;
        for (MediaOrderBillDto paramBillDto : paramBillDtos) {
            if (!orderBillIds.contains(paramBillDto.getOrderBillId())) {
                continue;
            } else {
                i = i + 1;
            }
            MediaOrderBill orderBill = paramBillMap.get(paramBillDto.getOrderBillId());

            // todo 校验数据
            // 校验数据
            String cycleStatus = orderBill.getCycleStatus();
            if (!(MediaResourceConstant.CYCLE_STATUS.USE_OUT.equals(Integer.parseInt(cycleStatus)) ||
                    MediaResourceConstant.CYCLE_STATUS.USE_IN.equals(Integer.parseInt(cycleStatus)))) {
                throw new ServiceException("执行状态的订单才能终止!");
            }

            Date finalDate = param.getFinalDate();
            Date startDate = orderBill.getUseStartDate();
            Date endDate = orderBill.getUseEndDate();

            if (finalDate.after(endDate) || finalDate.equals(endDate)) {
                mediaOrderCycleMapper.deleteCycle(startDate, endDate, orderBill.mediaId);
                // 不用处理
            } else {
                mediaOrderCycleMapper.deleteCycle(startDate, endDate, orderBill.mediaId);
                endDate = finalDate;
            }

            /*MediaOrderRunBill paramRunBill = new MediaOrderRunBill();
            paramRunBill.setOrderBillId();
            List<MediaOrderRunBill> mediaOrderRunBills = mediaOrderRunBillMapper.selectByCondition(paramRunBill);
            MediaOrderRunBill runBill = mediaOrderRunBills.get(0);

            *//*BigDecimal amount = orderBill.getOrderBillAmount()
                    .multiply(new BigDecimal(30))
                    .divide(new BigDecimal(mediaCommonService.dayDiff(startDate, endDate)), 4, BigDecimal.ROUND_HALF_UP);*//*
            //runBill.setOrderSingleAmount(paramBillDto.getOrderBillAmount());

            MediaOrderRunBill newRunBill = new MediaOrderRunBill();
            newRunBill.setOrderRunBillId(runBill.getOrderRunBillId());
            newRunBill.setOrderSingleAmount(paramBillDto.getOrderBillAmount());
            mediaOrderRunBillMapper.updateByPrimaryKeySelective(newRunBill);*/

            MediaOrderBill bill = new MediaOrderBill();
            bill.setOrderBillId(orderBill.orderBillId);
            bill.setCycleStatus(MediaResourceConstant.CYCLE_STATUS.NO_USE + "");
            // 4 位
            bill.setIsFinal(1);
            bill.setFinalDate(finalDate);
            AuditUtil.setAuditProperty(currentSysUser, false, bill, nowDate);
            mediaOrderBillMapper.updateByPrimaryKeySelective(bill);
        }
        MediaOrder paramOrder = new MediaOrder();

        // 全部终止 订单设置为终止
        MediaOrderBill paramFinal = new MediaOrderBill();
        paramFinal.setOrderId(Long.parseLong(orderId));
        List<MediaOrderBill> allOrderBills = mediaOrderBillMapper.select(paramOrderBill);
        int count = 0;
        for (MediaOrderBill allOrderBill : allOrderBills) {
            if (allOrderBill.getCycleStatus().equals(MediaResourceConstant.CYCLE_STATUS.NO_USE.toString())) {
                count = count + 1;
            }
        }

        if (count == allOrderBills.size()) {
            paramOrder.setOrderStatus(MediaResourceConstant.ORDER_STATUS_TYPE.FINAL);
        }


        paramOrder.setOrderId(order.getOrderId());
        AuditUtil.setAuditProperty(currentSysUser, false, paramOrder, nowDate);
        paramOrder.setBackAmount(param.getBackAmount());
        mediaOrderMapper.updateByPrimaryKeySelective(paramOrder);
        return true;
    }


    @Override
    public boolean delById(String orderId) {
        TbSysUser currentSysUser = tbSysUserService.getCurrentSysUser();

        // 将订单置位状态删除
        MediaOrder recordOrder = new MediaOrder();
        recordOrder.setOrderId(Long.parseLong(orderId));
        recordOrder.setIsDelete(1);
        mediaOrderMapper.updateByPrimaryKeySelective(recordOrder);
        // 插件问题
        List<MediaOrderBillDto> orderBills = mediaOrderBillMapper.findByOrderId(orderId);

        // 将订单明细状态为删除
        MediaOrderBill param = new MediaOrderBill();
        param.setOrderId(Long.parseLong(orderId));

        mediaOrderBillMapper.delByOrderId(orderId, currentSysUser.getUserCode(), currentSysUser.getUserName(), new Date());

        // todo 如果被多个定单占用则不做删除处理
        for (MediaOrderBillDto orderBill : orderBills) {
            Date startDate = orderBill.getOrderBillStartDate();
            Date endDate = orderBill.getOrderBillEndDate();
            String mediaId = orderBill.getMediaId();
            mediaOrderCycleMapper.deleteCycle(startDate, endDate, mediaId);
        }
        return true;
    }

    /**
     * 执行操作更新订单
     *
     * @param order
     * @param param
     */
    private void updateOrderOfRun(MediaOrder order, MediaOrderDto param) {
        order.setOrderStartDate(param.getOrderStartDate());
        order.setOrderEndDate(param.getOrderEndDate());
        order.setCustomerId(param.getCustomerId());
        // order.setOrderAmount(order.);
        order.setRemark(param.getRemark());
        TbSysUser currentSysUser = tbSysUserService.getCurrentSysUser();
        order.setOrderStatus(MediaResourceConstant.ORDER_STATUS_TYPE.RUN);
        AuditUtil.setAuditProperty(currentSysUser, false, order, param.getCreateTime());
        mediaOrderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public PageData selectBillPageList(MediaOrderBillDto param) {
        PageUtil.setPageOffset(param);
        List<MediaOrderBillDto> list = mediaOrderBillMapper.findList(param);
        setPropertyOfOrderBill(list);
        Long total = mediaOrderBillMapper.findCount(param);
        return PageUtil.setPageData(param, total, list);
    }

    /**
     * 锁定时更新orderBill
     *
     * @param paramBillDtos
     * @return
     */
    private void updateOrderBillsOfLock(MediaOrderDto param, List<MediaOrderBillDto> paramBillDtos, List<MediaOrderBill> allOrderBills) {
        // List转Map
        Map<String, MediaOrderBillDto> paramBillDtoMap =
                paramBillDtos.stream().collect(Collectors.toMap(MediaOrderBillDto::getOrderBillId, a -> a, (k1, k2) -> k1));
        // 要锁定的信息
        List<String> orderBillIds = new ArrayList<>();
        for (MediaOrderBillDto orderBillDto : paramBillDtos) {
            orderBillIds.add(orderBillDto.getOrderBillId());
        }
        // 所有订单信息
        Map<String, MediaOrderBill> allOrderBillMap =
                allOrderBills.stream().collect(Collectors.toMap(MediaOrderBill::getOrderBillId, a -> a, (k1, k2) -> k1));

        List<String> allBillIds = new ArrayList<>();
        for (MediaOrderBill orderBill : allOrderBills) {
            allBillIds.add(orderBill.getOrderBillId());
        }
        allBillIds.removeAll(orderBillIds);

        List<MediaOrderBill> orderBills = mediaOrderBillMapper.selectByIds(StringUtils.collectionToDelimitedString(orderBillIds, ","));
        for (MediaOrderBill orderBill : orderBills) {
            String cycleStatus = orderBill.getCycleStatus();
            if (!MediaResourceConstant.CYCLE_STATUS.RESERVE.equals(Integer.parseInt(cycleStatus))) {
                String mediaCode = mediaOrderCycleMapper.findMediaResourceCode(orderBill.getMediaId());
                throw new ServiceException("预定的资源才能进行锁定操作!" + "资源编号" + mediaCode + "非预定状态");
            }
        }

        BigDecimal orderAmount = new BigDecimal(0); // 合同金额
        // 设置将更新的属性
        for (MediaOrderBill orderBill : orderBills) {
            MediaOrderBillDto paramOrderBillDto = paramBillDtoMap.get(orderBill.getOrderBillId());
            MediaOrderBill newOrderBill = new MediaOrderBill();
            newOrderBill.setOrderBillId(paramOrderBillDto.getOrderBillId());
            newOrderBill.setCycleStatus(MediaResourceConstant.CYCLE_STATUS.LOCK.toString());

            Date startDate = DateUtil.parseDate(paramOrderBillDto.getOrderBillStartDateStr());
            Date endDate = DateUtil.parseDate(paramOrderBillDto.getOrderBillEndDateStr());
            newOrderBill.setLockStartDate(startDate);
            newOrderBill.setLockEndDate(endDate);
            newOrderBill.setOrderBillStartDate(startDate);
            newOrderBill.setOrderBillEndDate(endDate);

            // 计算金额
            MediaResourceDto mediaResource = mediaResourceNewService.getMediaResource(orderBill.orderBillId);

            int mediaType = paramOrderBillDto.getMediaType();
            BigDecimal orderBillAmount = paramOrderBillDto.getOrderBillAmount();
            int mediaWidth = Integer.parseInt(paramOrderBillDto.getMediaWidth() == null ? "0" : paramOrderBillDto.getMediaWidth());
            int mediaHeight = Integer.parseInt(paramOrderBillDto.getMediaHeight() == null ? "0" : paramOrderBillDto.getMediaHeight());
            Integer mediaForm = strToInteger(mediaResource.getMediaForm(), 0);
            BigDecimal unitAmount = mediaCommonService.calculateUnitAmount(startDate, endDate, mediaType, mediaForm, orderBillAmount, mediaWidth, mediaHeight);
            newOrderBill.setOrderBillUnitAmount(unitAmount.setScale(4, BigDecimal.ROUND_HALF_UP));
            newOrderBill.setOrderBillAmount(paramOrderBillDto.getOrderBillAmount().setScale(2, BigDecimal.ROUND_HALF_UP));
            mediaOrderBillMapper.updateByPrimaryKeySelective(newOrderBill);

            dealCycleDate(orderBill.getOrderBillStartDate(), orderBill.getOrderBillEndDate(), startDate, endDate,
                    orderBill.getMediaId(), MediaResourceConstant.CYCLE_STATUS.LOCK);

            orderAmount = orderAmount.add(paramOrderBillDto.getOrderBillAmount());
        }
        // 释放预定的资源
        cancelReserve(allBillIds, allOrderBillMap);

        // 设置订单信息
        param.setOrderAmount(orderAmount);
    }

    /**
     * 取消预定
     *
     * @param reserveBillIds
     */
    private void cancelReserve(List<String> reserveBillIds, Map<String, MediaOrderBill> allOrderBillMap) {
        // 释放资源
        if (reserveBillIds != null && reserveBillIds.size() > 0) {
            for (String reserveBillId : reserveBillIds) {
                MediaOrderBill orderBill = allOrderBillMap.get(reserveBillId);
                mediaOrderCycleMapper.deleteCycle(orderBill.getOrderBillStartDate(), orderBill.getOrderBillEndDate(), orderBill.getMediaId());
            }
        }
        // 修改状态
        for (String reserveBillId : reserveBillIds) {
            MediaOrderBill newOrderBill = new MediaOrderBill();
            newOrderBill.setOrderBillId(reserveBillId);
            newOrderBill.setIsDelete(1);
            mediaOrderBillMapper.updateByPrimaryKeySelective(newOrderBill);
        }
    }

    /**
     * 处理周期时间
     *
     * @param oldStartDate
     * @param oldEndDate
     * @param newStartDate
     * @param newEndDate
     */
    // batchList(orderBill.getMediaId(), MediaResourceConstant.CYCLE_STATUS.LOCK,  betweenDay, startDate );
    private void dealCycleDate(Date oldStartDate, Date oldEndDate, Date newStartDate, Date newEndDate,
                               String mediaId, int cycleStatus) {
        if (!oldStartDate.equals(newStartDate)) {
            if (oldStartDate.after(newStartDate)) {
                int useNum = mediaOrderCycleMapper.findUseNum(newStartDate, oldEndDate, mediaId, ">=", "<");
                if (useNum > 0) {
                    String mediaCode = mediaOrderCycleMapper.findMediaResourceCode(mediaId);
                    String oldStartDateStr = DateUtil.simpleFormat(oldStartDate);
                    String newStartDateStr = DateUtil.simpleFormat(newStartDate);
                    throw new ServiceException("资源编号" + mediaCode + "已被占用" + newStartDateStr + oldStartDateStr);
                }
            }
        } else if (!oldEndDate.equals(newEndDate)) {
            if (oldEndDate.before(newEndDate)) {
                int useNum = mediaOrderCycleMapper.findUseNum(oldEndDate, newEndDate, mediaId, ">", "<=");
                if (useNum > 0) {
                    String mediaCode = mediaOrderCycleMapper.findMediaResourceCode(mediaId);
                    String oldEndDateStr = DateUtil.simpleFormat(oldEndDate);
                    String newEndDateStr = DateUtil.simpleFormat(newEndDate);
                    throw new ServiceException("资源编号" + mediaCode + "已被占用" + oldEndDateStr + newEndDateStr);
                }
            }
        }
        if (cycleStatus == MediaResourceConstant.CYCLE_STATUS.LOCK) {
            int betweenDay = mediaCommonService.dayDiff(newStartDate, newEndDate);
            // 去除排期
            mediaOrderCycleMapper.deleteCycle(oldStartDate, oldEndDate, mediaId);
            batchList(mediaId, cycleStatus, betweenDay, newStartDate);
        } else if (cycleStatus == MediaResourceConstant.CYCLE_STATUS.USE_OUT
                || cycleStatus == MediaResourceConstant.CYCLE_STATUS.USE_IN ) {
            int betweenDay = mediaCommonService.dayDiff(newStartDate, newEndDate);
            // 去除排期
            mediaOrderCycleMapper.deleteCycle(oldStartDate, oldEndDate, mediaId);
            batchList(mediaId, cycleStatus, betweenDay, newStartDate);
        }
    }


    /**
     * 批量插入排期表数据
     *
     * @param mediaId
     * @param cycleStatus
     * @param betweenDay
     * @param startDate
     */
    private void batchList(String mediaId, int cycleStatus, int betweenDay, Date startDate) {
        List<MediaCycle> mediaCycleList = new ArrayList<>();
        for (int i = 0; i < betweenDay; i++) {
            Calendar calendar = Calendar.getInstance();
            Date date = startDate;
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, i);//+1今天的时间加一天
            date = calendar.getTime();
            //保存排期表
            MediaCycle cycle = new MediaCycle();
            Long cycleId = SnowflakeUtil.INSTANCE.getId();
            cycle.setCycleId(cycleId);
            cycle.setCycleTime(date);
            cycle.setCycleStatus(cycleStatus);// 2预定
            cycle.setMediaId(Long.parseLong(mediaId));
            cycle.setIsDelete(0);
            cycle.setSort(0);
            cycle.setVersion(0);
            mediaCycleList.add(cycle);
        }
        advertistingReserveMapper.insertList(mediaCycleList);
    }

    /**
     * 执行时更新orderBill
     *
     * @param paramBillDtos
     * @return
     */
    private void updateOrderBillsOfRun(MediaOrderDto param, List<MediaOrderBillDto> paramBillDtos) {
        // List转Map
        Map<String, MediaOrderBillDto> paramBillDtoMap =
                paramBillDtos.stream().collect(Collectors.toMap(MediaOrderBillDto::getOrderBillId, a -> a, (k1, k2) -> k1));

        List<String> orderBillIds = new ArrayList<>();
        for (MediaOrderBillDto orderBillDto : paramBillDtos) {
            orderBillIds.add(orderBillDto.getOrderBillId());
        }
        List<MediaOrderBill> orderBills = mediaOrderBillMapper.selectByIds(StringUtils.collectionToDelimitedString(orderBillIds, ","));
        /*for (MediaOrderBill orderBill : orderBills) {
            if(!MediaResourceConstant.CYCLE_STATUS.LOCK.equals(Integer.parseInt(orderBill.getCycleStatus()))){

                throw new ServiceException("存在非锁定状态的资源,不能执行");
            }
        }*/

        BigDecimal orderAmount = new BigDecimal(0); // 合同金额
        // 设置将更新的属性
        for (MediaOrderBill oldOrderBill : orderBills) {
            MediaOrderBillDto paramOrderBillDto = paramBillDtoMap.get(oldOrderBill.getOrderBillId());
            MediaOrderBill newOrderBill = new MediaOrderBill();
            newOrderBill.setOrderBillId(paramOrderBillDto.getOrderBillId());


            // TODO 集团内部还是外部
            String cycleStatus = "0";
            if (MediaResourceConstant.CUSTOMER_TYPE.JT.equals(param.getCustomerType())) {
                cycleStatus = MediaResourceConstant.CYCLE_STATUS.USE_IN.toString();
            } else {
                cycleStatus = MediaResourceConstant.CYCLE_STATUS.USE_OUT.toString();
            }
            newOrderBill.setCycleStatus(cycleStatus);
            Date startDate = DateUtil.parseDate(paramOrderBillDto.getOrderBillStartDateStr());
            Date endDate = DateUtil.parseDate(paramOrderBillDto.getOrderBillEndDateStr());
            newOrderBill.setUseStartDate(startDate);
            newOrderBill.setUseEndDate(endDate);
            /*newOrderBill.setOrderBillStartDate(startDate);
            newOrderBill.setOrderBillEndDate(endDate);*/
            if (!startDate.equals(oldOrderBill.getOrderBillStartDate())) {
                throw new ServiceException("目前执行时的资源上刊时间只能等于订单中资源上刊时间!");
            }
            if (!endDate.equals(oldOrderBill.getOrderBillEndDate())) {
                throw new ServiceException("目前执行时的资源下刊时间只能等于订单中资源上刊时间!");
            }
            // 计算金额
            BigDecimal orderBillAmount = calculateBillAmount(oldOrderBill, paramOrderBillDto, startDate, endDate);
            //newOrderBill.setOrderBillAmount(orderBillAmount);
            //newOrderBill.setOrderBillAmount(paramOrderBillDto.getOrderBillAmount());
            mediaOrderBillMapper.updateByPrimaryKeySelective(newOrderBill);
            orderAmount = orderAmount.add(paramOrderBillDto.getOrderBillAmount());

            dealCycleDate(oldOrderBill.getOrderBillStartDate(), oldOrderBill.getOrderBillEndDate(), startDate, endDate,
                    oldOrderBill.getMediaId(), Integer.parseInt(cycleStatus));
        }

        // 设置订单信息
        param.setOrderAmount(orderAmount);
    }

    /**
     * 更新订单
     *
     * @param order
     * @param param
     */
    private void updateOrderOfLock(MediaOrder order, MediaOrderDto param) {
        order.setSignDate(param.getSignDate());
        order.setOrderStartDate(param.getOrderStartDate());
        order.setOrderEndDate(param.getOrderEndDate());
        order.setOrderStatus(MediaResourceConstant.ORDER_STATUS_TYPE.LOCKING);
        order.setRemark(param.getRemark());
        order.setCustomerId(param.getCustomerId());
        order.setOrderAmount(param.getOrderAmount());
        order.setOrderId(Long.parseLong(param.getOrderId()));
        int i = mediaOrderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 执行时更新orderBill
     *
     * @param paramBillDtos
     * @param run           执行单
     * @return
     */
    private MediaOrder insertRunBill(MediaOrder order, MediaOrderRun
            run, List<MediaOrderBillDto> paramBillDtos) {
        // List转Map
        Map<String, MediaOrderBillDto> paramBillDtoMap =
                paramBillDtos.stream().collect(Collectors.toMap(MediaOrderBillDto::getOrderBillId, a -> a, (k1, k2) -> k1));

        List<String> orderBillIds = new ArrayList<>();
        for (MediaOrderBillDto orderBillDto : paramBillDtos) {
            orderBillIds.add(orderBillDto.getOrderBillId());
        }
        List<MediaOrderBill> orderBills = mediaOrderBillMapper.selectByIds(StringUtils.collectionToDelimitedString(orderBillIds, ","));

        for (MediaOrderBill oldOrderBill : orderBills) {
            // 校验 todo 可优化
            String cycleStatus = oldOrderBill.getCycleStatus();
            if (!MediaResourceConstant.CYCLE_STATUS.LOCK.equals(Integer.parseInt(cycleStatus))) {
                String mediaCode = mediaOrderCycleMapper.findMediaResourceCode(oldOrderBill.getMediaId());
                throw new ServiceException("锁定状态的订单明细才能进行执行操作! 资源" + mediaCode + "非锁定状态");
            }

            MediaOrderBillDto paramOrderBillDto = paramBillDtoMap.get(oldOrderBill.getOrderBillId());
            Date startDate = DateUtil.parseDate(paramOrderBillDto.getOrderBillStartDateStr());
            Date endDate = DateUtil.parseDate(paramOrderBillDto.getOrderBillEndDateStr());
            paramOrderBillDto.setOrderBillStartDate(startDate);
            paramOrderBillDto.setOrderBillEndDate(endDate);
            // 更新订单明细
            MediaOrderBill newOrderBill = new MediaOrderBill();
            updateOrderBill(newOrderBill, oldOrderBill, paramOrderBillDto);
            // 新增执行单明细
            MediaOrderRunBill runBill = new MediaOrderRunBill();
            // 计算金额
            // BigDecimal orderBillAmount = calculateBillAmount(oldOrderBill, paramOrderBillDto, startDate, endDate);
            // todo bug
            runBill.setOrderSingleAmount(paramOrderBillDto.getOrderBillAmount());
            insertOrderRunBill(runBill, run, oldOrderBill, paramOrderBillDto);
        }

        MediaOrder newOrder = new MediaOrder();
        // todo 待处理
        return newOrder;
    }

    /**
     * 计算明细金额
     *
     * @param oldOrderBill
     * @param paramOrderBillDto
     * @param startDate
     * @param endDate
     * @return
     */
    private BigDecimal calculateBillAmount(MediaOrderBill oldOrderBill, MediaOrderBillDto
            paramOrderBillDto, Date startDate, Date endDate) {
        MediaResourceDto mediaResource = mediaResourceNewService.getMediaResource(oldOrderBill.orderBillId);
        Integer mediaType = strToInteger(mediaResource.getMediaType(), 0);
        Integer mediaForm = strToInteger(mediaResource.getMediaForm(), 0);

        BigDecimal orderBillUnitAmount = oldOrderBill.getOrderBillUnitAmount();
        int mediaWidth = Integer.parseInt(paramOrderBillDto.getMediaWidth() == null ? "0" : paramOrderBillDto.getMediaWidth());
        int mediaHeight = Integer.parseInt(paramOrderBillDto.getMediaHeight() == null ? "0" : paramOrderBillDto.getMediaHeight());

        BigDecimal orderBillAmount =
                mediaCommonService.calculateBillAmount(startDate, endDate, mediaType, mediaForm, orderBillUnitAmount, mediaWidth, mediaHeight);

        return orderBillAmount.setScale(4, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * str转换为int
     */
    private Integer strToInteger(String str, Integer defaultInt) {
        if (!StringUtils.hasText(str)) {
            // todo 换为日志记录
            System.out.println("str转换数据为空");
            return defaultInt;
        } else {
            return Integer.parseInt(str);
        }
    }

    /**
     * 更新订单明细
     *
     * @param newOrderBill
     * @param oldOrderBill
     * @param paramOrderBillDto
     */
    private void updateOrderBill(MediaOrderBill newOrderBill, MediaOrderBill
            oldOrderBill, MediaOrderBillDto paramOrderBillDto) {
        newOrderBill.setOrderBillId(paramOrderBillDto.getOrderBillId());
        Date startDate = paramOrderBillDto.getOrderBillStartDate();
        Date endDate = paramOrderBillDto.getOrderBillEndDate();
        newOrderBill.setUseStartDate(startDate);
        newOrderBill.setUseEndDate(endDate);
        newOrderBill.setOrderBillStartDate(startDate);
        newOrderBill.setOrderBillEndDate(endDate);
        // 计算订单明细金额
        //BigDecimal orderBillAmount = oldOrderBill.getOrderBillUnitAmount().multiply(new BigDecimal(mediaCommonService.dayDiff(startDate, endDate)));
        //newOrderBill.setOrderBillAmount(orderBillAmount.setScale(4, BigDecimal.ROUND_HALF_UP));
        mediaOrderBillMapper.updateByPrimaryKeySelective(newOrderBill);
    }


    /**
     * 新增执行单
     *
     * @param order
     * @param run
     */
    private void insertOrderRun(MediaOrder order, MediaOrderRun run, MediaOrderDto param) {
        run.setRemark(param.getRemark());
        String orderRunId = SnowflakeUtil.INSTANCE.getId().toString();
        run.setOrderRunId(orderRunId);
        run.setOrderId(order.getOrderId().toString());
        run.setCreateTime(param.getCreateTime());
        // 处理序号的递增
        MediaOrderRunDto orderRunDto = mediaOrderRunMapper.findOrderRunNear(run.getOrderId());
        String orderCode = order.getOrderCode();
        String orderRunCode = orderRunDto.getOrderRunCode();
        int sort = 0;
        if (orderRunCode == null) {
            // 第一个执行单
            orderRunCode = orderCode + "_1";
        } else {
            sort = orderRunDto.getSort() + 1;
            orderRunCode = orderCode + "_" + (sort + 1);
        }


        AuditUtil.setAuditProperty(tbSysUserService.getCurrentSysUser(), true, run, order.getCreateTime());
        run.setSort(sort);
        run.setIsDelete(0);
        run.setVersion(0);
        run.setOrderRunCode(orderRunCode);
        mediaOrderRunMapper.insertSelective(run);
    }

    /**
     * 新增执行单明细
     *
     * @param runBill
     * @param run
     */
    private void insertOrderRunBill(MediaOrderRunBill runBill, MediaOrderRun run, MediaOrderBill
            orderBill, MediaOrderBillDto paramOrderBillDto) {
        String runBillId = SnowflakeUtil.INSTANCE.getId().toString();
        runBill.setOrderRunBillId(runBillId);
        runBill.setOrderBillId(orderBill.getOrderBillId());
        runBill.setOrderRunId(run.getOrderRunId());
        runBill.setRunBillStartDate(paramOrderBillDto.getOrderBillStartDate());
        runBill.setRunBillEndDate(paramOrderBillDto.getOrderBillEndDate());
        TbSysUser currentSysUser = tbSysUserService.getCurrentSysUser();
        AuditUtil.setAuditProperty(currentSysUser, true, runBill, run.getCreateTime());
        runBill.setVersion(0);
        runBill.setSort(0);
        runBill.setIsDelete(0);
        mediaOrderRunBillMapper.insert(runBill);
    }


}
