package com.sckw.report.service;

import com.sckw.core.common.enums.NumberConstant;
import com.sckw.core.model.enums.LogisticsOrderEnum;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.HttpResult;
import com.sckw.excel.utils.DateUtil;
import com.sckw.mongo.model.SckwLogisticsOrder;
import com.sckw.mongo.model.TableTops;
import com.sckw.report.service.param.ConsignOrderQuery;
import com.sckw.report.service.vo.ConsignOrderExcelVo;
import com.sckw.report.service.vo.ConsignOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author lfdc
 * @description 托运service
 * @date 2023-07-24 13:07:47
 */
@Slf4j
@Service
public class KwConsignService {

    @Autowired
    public MongoTemplate mongoTemplate;

    @Autowired
    public KwTransportService transportService;

    /**
     * 托运订单列表查询
     *
     * @param query
     * @return
     * @throws ParseException
     */
    public HttpResult selectConsignOrderList(ConsignOrderQuery query, String unitType) {
        //模糊匹配
        //根据条件查询所有并排序，且分页
        //设置模糊查询匹配规则  忽略大小写
        // 创建条件对象
        Criteria criteria = new Criteria();
        // 1. 全等于
        //判断承运还是托运企业
        if (unitType.equals(NumberConstant.ONE)) {
            criteria.and("checkEntId").is(LoginUserHolder.getEntId());
        } else {
            criteria.and("carrierEntId").is(LoginUserHolder.getEntId());
        }
        if (StringUtils.isNotBlank(query.getLoadAddress())) {
            criteria.and("loadDetailAddress").is(query.getLoadAddress());
        }
        if (StringUtils.isNotBlank(query.getUnloadAddress())) {
            criteria.and("unloadDetailAddress").is(query.getUnloadAddress());
        }
        if (StringUtils.isNotBlank(query.getStatus())) {
            criteria.and("status").is(query.getStatus());
        }
        criteria.and("delFlag").is(String.valueOf(NumberConstant.ZERO));
        // 4. 日期范围
        if (StringUtils.isNotEmpty(query.getStartDateTime()) && StringUtils.isNotEmpty(query.getEndDateTime())) {
            criteria.andOperator(Criteria.where("createTime").gte(query.getStartDateTime()), Criteria.where("createTime")
                    .lte(query.getEndDateTime()));
        }
        //多条件模糊查询
        Criteria c1 = new Criteria();
        Criteria c2 = new Criteria();
        Criteria c3 = new Criteria();
        Criteria c4 = new Criteria();
        Criteria c5 = new Criteria();
        if (StringUtils.isNotBlank(query.getKeywords())) {
            Pattern pattern = Pattern.compile("^.*" + query.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
            c1 = Criteria.where("firmName").regex(pattern);
            c2 = Criteria.where("carrierFirmName").regex(pattern);
            c3 = Criteria.where("checkFirmName").regex(pattern);
            c4 = Criteria.where("tOrderNo").regex(pattern);
            c5 = Criteria.where("lOrderNo").regex(pattern);
            criteria.orOperator(c1, c2, c3, c4, c5);
        }

        Query query1 = new Query(criteria);
        //in查询
        if (CollectionUtils.isNotEmpty(query.getIds())) {
            query1.addCriteria(Criteria.where("lOrderId").in(query.getIds()));
        }
        // 12. 总记录数
        long total = mongoTemplate.count(query1, SckwLogisticsOrder.class);
        // 10. 分页
        query1.with(PageRequest.of(query.getPage() - 1, query.getPageSize(),
                // 11. 排序list = {ArrayList@27436}  size = 3returnList = {ArrayList@27393}  size = 3
                Sort.by(Sort.Order.desc("createTime"))));
        // 执行查询
        List<SckwLogisticsOrder> list = mongoTemplate.find(query1, SckwLogisticsOrder.class);
        List<ConsignOrderVo> returnList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            packageReturnList(list, returnList);
        }
        PageResult build = PageResult.build(query.getPage(), query.getPageSize(), total, returnList);
        return HttpResult.ok(build);
    }

    /**
     * 组装托运列表分页查询
     *
     * @param list
     * @param returnList
     */
    private void packageReturnList(List<SckwLogisticsOrder> list, List<ConsignOrderVo> returnList) {
        for (SckwLogisticsOrder logisticsOrder : list) {
            ConsignOrderVo vo = new ConsignOrderVo();
            vo.setAccountsCycle(logisticsOrder.getSettlementCycle() == null ?
                    null : String.valueOf(logisticsOrder.getSettlementCycle()));
            vo.setAppointor(logisticsOrder.getCreateByName());
            vo.setBillingMode(logisticsOrder.getBillingMode());
            vo.setCarrierCompany(logisticsOrder.getCarrierFirmName());
            vo.setCarrierOrder(logisticsOrder.getWOrderNo());
            vo.setCarrierPhone(logisticsOrder.getCarrierPhone());
            vo.setCarryingCapacity(logisticsOrder.getCarryingCapacity() == null ?
                    null : String.valueOf(logisticsOrder.getCarryingCapacity()));
            vo.setConsignCompany(logisticsOrder.getCheckFirmName());
            vo.setConsignContacts(logisticsOrder.getCheckContacts());
            vo.setConsignPhone(logisticsOrder.getCheckPhone());
            vo.setContract(logisticsOrder.getContractName());
            vo.setDeficitAmount(logisticsOrder.getDeficitAmount() == null ?
                    null : String.valueOf(logisticsOrder.getDeficitAmount()));
            vo.setGoodsName(logisticsOrder.getGoodsName());
            vo.setLoadAddress(logisticsOrder.getLoadDetailAddress());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setLOrderId(String.valueOf(logisticsOrder.getLOrderId()));
            vo.setLOrderNo(logisticsOrder.getLOrderNo());
            vo.setLoss(logisticsOrder.getLoss() == null ?
                    null : String.valueOf(logisticsOrder.getLoss()));
            vo.setPrice(logisticsOrder.getPrice() == null ?
                    null : String.valueOf(logisticsOrder.getPrice()));
            vo.setReceiveGoodsContacts(logisticsOrder.getUnloadContacts());
            vo.setReceiveGoodsPhone(logisticsOrder.getUnloadPhone());
            vo.setRemark(logisticsOrder.getRemark());
            vo.setShipmentsContacts(logisticsOrder.getLoadContacts());
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setShipmentsDateTime(logisticsOrder.getLoadTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getLoadTime()));
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setSigning(logisticsOrder.getContractSigningWay());
            vo.setStatus(logisticsOrder.getStatus());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setWOrderNo(logisticsOrder.getWOrderNo());
            vo.setCreateTime(logisticsOrder.getCreateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getCreateTime()));
            vo.setUpdateTime(logisticsOrder.getUpdateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getUpdateTime()));
            returnList.add(vo);
        }
    }

    /**
     * 托运订单导出
     *
     * @param query
     * @param unitType
     * @return
     */
    public List<ConsignOrderExcelVo> exportConsign(ConsignOrderQuery query, String unitType) {
        //模糊匹配
        //根据条件查询所有并排序，且分页
        //设置模糊查询匹配规则  忽略大小写
        // 创建条件对象
        Criteria criteria = new Criteria();
        // 1. 全等于
        Query query1 = new Query();
        if (unitType.equals(NumberConstant.ONE)) {
            criteria.and("checkEntId").is(LoginUserHolder.getEntId());
        } else {
            criteria.and("carrierEntId").is(LoginUserHolder.getEntId());
        }
        criteria.and("delFlag").is(String.valueOf(NumberConstant.ZERO));
        if (CollectionUtils.isEmpty(query.getIds())) {
            if (StringUtils.isNotBlank(query.getLoadAddress())) {
                criteria.and("loadDetailAddress").is(query.getLoadAddress());
            }
            if (StringUtils.isNotBlank(query.getUnloadAddress())) {
                criteria.and("unloadDetailAddress").is(query.getUnloadAddress());
            }
            if (StringUtils.isNotBlank(query.getStatus())) {
                criteria.and("status").is(query.getStatus());
            }
            // 4. 日期范围
            if (StringUtils.isNotEmpty(query.getStartDateTime()) && StringUtils.isNotEmpty(query.getEndDateTime())) {
                criteria.andOperator(Criteria.where("createTime").gte(query.getStartDateTime()), Criteria.where("createTime")
                        .lte(query.getEndDateTime()));
            }
            //多条件模糊查询
            Criteria c1 = new Criteria();
            Criteria c2 = new Criteria();
            Criteria c3 = new Criteria();
            Criteria c4 = new Criteria();
            Criteria c5 = new Criteria();
            if (StringUtils.isNotBlank(query.getKeywords())) {
                Pattern pattern = Pattern.compile("^.*" + query.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
                c1 = Criteria.where("firmName").regex(pattern);
                c2 = Criteria.where("carrierFirmName").regex(pattern);
                c3 = Criteria.where("checkFirmName").regex(pattern);
                c4 = Criteria.where("tOrderNo").regex(pattern);
                c5 = Criteria.where("lOrderNo").regex(pattern);
                criteria.orOperator(c1, c2, c3, c4, c5);
            }
            query1.addCriteria(criteria);
            if (CollectionUtils.isNotEmpty(query.getIds())) {
                query1.addCriteria(Criteria.where("lOrderId").in(query.getIds()));
            }
        } else {
            query1.addCriteria(criteria);
            if (CollectionUtils.isNotEmpty(query.getIds())) {
                query1.addCriteria(Criteria.where("lOrderId").in(query.getIds()));
            }
        }
        // 执行查询
        List<SckwLogisticsOrder> list = mongoTemplate.find(query1, SckwLogisticsOrder.class);
        List<ConsignOrderExcelVo> returnList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            packageReturnExcelList(list, returnList);
        }
        return returnList;
    }

    private void packageReturnExcelList(List<SckwLogisticsOrder> list, List<ConsignOrderExcelVo> returnList) {
        for (SckwLogisticsOrder logisticsOrder : list) {
            ConsignOrderExcelVo vo = new ConsignOrderExcelVo();
            vo.setAccountsCycle(logisticsOrder.getSettlementCycle() == null ?
                    null : String.valueOf(logisticsOrder.getSettlementCycle()));
            vo.setAppointor(logisticsOrder.getCreateByName());
            vo.setBillingMode(logisticsOrder.getBillingMode());
            vo.setCarrierCompany(logisticsOrder.getCarrierFirmName());
            vo.setCarrierOrder(logisticsOrder.getWOrderNo());
            vo.setCarrierPhone(logisticsOrder.getCarrierPhone());
            vo.setCarryingCapacity(logisticsOrder.getCarryingCapacity() == null ?
                    null : String.valueOf(logisticsOrder.getCarryingCapacity()));
            vo.setConsignCompany(logisticsOrder.getCheckFirmName());
            vo.setConsignContacts(logisticsOrder.getCheckContacts());
            vo.setConsignPhone(logisticsOrder.getCheckPhone());
            vo.setContract(logisticsOrder.getContractName());
            vo.setDeficitAmount(logisticsOrder.getDeficitAmount() == null ?
                    null : String.valueOf(logisticsOrder.getDeficitAmount()));
            vo.setGoodsName(logisticsOrder.getGoodsName());
            vo.setLoadAddress(logisticsOrder.getLoadDetailAddress());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setLOrderId(String.valueOf(logisticsOrder.getLOrderId()));
            vo.setLOrderNo(logisticsOrder.getLOrderNo());
            vo.setLoss(logisticsOrder.getLoss() == null ?
                    null : String.valueOf(logisticsOrder.getLoss()));
            vo.setPrice(logisticsOrder.getPrice() == null ?
                    null : String.valueOf(logisticsOrder.getPrice()));
            vo.setReceiveGoodsContacts(logisticsOrder.getUnloadContacts());
            vo.setReceiveGoodsPhone(logisticsOrder.getUnloadPhone());
            vo.setRemark(logisticsOrder.getRemark());
            vo.setShipmentsContacts(logisticsOrder.getLoadContacts());
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setShipmentsDateTime(logisticsOrder.getLoadTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getLoadTime()));
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setSigning(logisticsOrder.getContractSigningWay());
            vo.setStatus(logisticsOrder.getStatus());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setWOrderNo(logisticsOrder.getWOrderNo());
            vo.setCreateTime(logisticsOrder.getCreateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getCreateTime()));
            vo.setUpdateTime(logisticsOrder.getUpdateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getUpdateTime()));
            returnList.add(vo);
        }
    }

    public HttpResult statisticsConsign(ConsignOrderQuery param, String unitType) {
        //模糊匹配
        //根据条件查询所有并排序，且分页
        //设置模糊查询匹配规则  忽略大小写
        // 创建条件对象
        Criteria criteria = new Criteria();
        // 1. 全等于
        //判断承运还是托运企业
        if (unitType.equals(NumberConstant.ONE)) {
            criteria.and("checkEntId").is(LoginUserHolder.getEntId());
        } else {
            criteria.and("carrierEntId").is(LoginUserHolder.getEntId());
        }
        if (StringUtils.isNotBlank(param.getLoadAddress())) {
            criteria.and("loadDetailAddress").is(param.getLoadAddress());
        }
        if (StringUtils.isNotBlank(param.getUnloadAddress())) {
            criteria.and("unloadDetailAddress").is(param.getUnloadAddress());
        }
        if (StringUtils.isNotBlank(param.getStatus())) {
            criteria.and("status").is(param.getStatus());
        }
        criteria.and("delFlag").is(String.valueOf(NumberConstant.ZERO));
        // 4. 日期范围
        if (StringUtils.isNotEmpty(param.getStartDateTime()) && StringUtils.isNotEmpty(param.getEndDateTime())) {
            criteria.andOperator(Criteria.where("createTime").gte(param.getStartDateTime()), Criteria.where("createTime")
                    .lte(param.getEndDateTime()));
        }
        if (CollectionUtils.isNotEmpty(param.getIds())) {
            criteria = Criteria.where("lOrderId").in(param.getIds());
        }
        //多条件模糊查询
        Criteria c1 = new Criteria();
        Criteria c2 = new Criteria();
        Criteria c3 = new Criteria();
        Criteria c4 = new Criteria();
        Criteria c5 = new Criteria();
        if (StringUtils.isNotBlank(param.getKeywords())) {
            Pattern pattern = Pattern.compile("^.*" + param.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
            c1 = Criteria.where("firmName").regex(pattern);
            c2 = Criteria.where("carrierFirmName").regex(pattern);
            c3 = Criteria.where("checkFirmName").regex(pattern);
            c4 = Criteria.where("tOrderNo").regex(pattern);
            c5 = Criteria.where("lOrderNo").regex(pattern);
            criteria.orOperator(c1, c2, c3, c4, c5);
        }
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("status").count().as("total"),
                Aggregation.project("total").and("value").previousOperation()
        );
        AggregationResults<TableTops> outputTypeCount = mongoTemplate.aggregate(aggregation, SckwLogisticsOrder.class, TableTops.class);
        List<TableTops> mappedResults = outputTypeCount.getMappedResults();
        List<TableTops> arrayList = new ArrayList<>();
        arrayList.addAll(mappedResults);
        /**补全数据状态不齐的情况*/
        packageReturnStatistics(mappedResults, arrayList);
        // 查询结果
        Map<String, Object> map = new HashMap<>(NumberConstant.SIXTEEN);
        map.put("tableTop",arrayList);
        return HttpResult.ok(map);
    }


    /**
     * 组装返回数据
     *
     * @param mappedResults
     * @param arrayList
     */
    private void packageReturnStatistics(List<TableTops> mappedResults, List<TableTops> arrayList) {
        List<String> codeList = LogisticsOrderEnum.getCodeStringList();
        List<String> collect = mappedResults.stream().map(e -> e.getValue()).collect(Collectors.toList());
        List<String> diffrentList = transportService.getDiffrentList(collect, codeList);
        if (CollectionUtils.isNotEmpty(mappedResults)) {
            if (CollectionUtils.isNotEmpty(diffrentList)) {
                for (String s : diffrentList) {
                    TableTops top = new TableTops();
                    top.setValue(s);
                    top.setTotal(NumberConstant.ZERO);
                    arrayList.add(top);
                }
            }
            for (TableTops top : arrayList) {
                top.setName(LogisticsOrderEnum.getName(Integer.valueOf(top.getValue())));
            }
        } else {
            for (LogisticsOrderEnum logisticsOrderEnum : LogisticsOrderEnum.values()) {
                TableTops top = new TableTops();
                top.setName(logisticsOrderEnum.getDestination());
                top.setValue(logisticsOrderEnum.getStatus());
                top.setTotal(NumberConstant.ZERO);
                arrayList.add(top);
            }
        }
    }

}
