package com.sckw.transport.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sckw.core.common.enums.NumberConstant;
import com.sckw.core.model.enums.CarWaybillEnum;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.utils.BeanUtils;
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.fleet.api.RemoteFleetService;
import com.sckw.fleet.api.model.vo.RTruckVo;
import com.sckw.mongo.model.SckwWaybillOrder;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import com.sckw.transport.dao.KwtWaybillOrderAddressMapper;
import com.sckw.transport.dao.KwtWaybillOrderMapper;
import com.sckw.transport.dao.KwtWaybillOrderTicketMapper;
import com.sckw.transport.dao.KwtWaybillOrderTrackMapper;
import com.sckw.transport.model.KwtWaybillOrderAddress;
import com.sckw.transport.model.KwtWaybillOrderTicket;
import com.sckw.transport.model.KwtWaybillOrderTrack;
import com.sckw.transport.model.dto.WayBillDetailDTO;
import com.sckw.transport.model.dto.WaybillOrderDTO;
import com.sckw.transport.model.vo.*;
import jakarta.validation.constraints.NotBlank;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.ibatis.annotations.Param;
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.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author jc
 * @description 运单相关服务
 * @date 2023-06-29 15:06:45
 */
@Slf4j
@Service
public class WaybillManagementService {

    @DubboReference(version = "1.0.0", group = "design", check = false)
    RemoteFleetService remoteFleetService;

    @DubboReference(version = "2.0.0", group = "design", check = false)
    RemoteSystemService remoteSystemService;

    @Autowired
    public KwtWaybillOrderMapper kwtWaybillOrderMapper;

    @Autowired
    public KwtWaybillOrderAddressMapper kwtWaybillOrderAddressMapper;

    @Autowired
    public KwtWaybillOrderTicketMapper kwtWaybillOrderTicketMapper;

    @Autowired
    public KwtWaybillOrderTrackMapper kwtWaybillOrderTrackMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 运单详情
     *
     * @param id
     * @return
     */
    public HttpResult waybillData(@Param("id") Long id) {
        WayBillDetailDTO kwtWaybillOrder = kwtWaybillOrderMapper.selectWaybillRelate(id);
        // 收发地址
        List<KwtWaybillOrderAddress> kwtWaybillOrderAddressList = kwtWaybillOrderAddressMapper.selectList(new LambdaQueryWrapper<KwtWaybillOrderAddress>()
                .eq(KwtWaybillOrderAddress::getWOrderId, kwtWaybillOrder.getLOrderId()));
        if (CollectionUtils.isNotEmpty(kwtWaybillOrderAddressList)) {
            for (KwtWaybillOrderAddress kwtWaybillOrderAddress : kwtWaybillOrderAddressList) {
                // 1装货地址、2卸货地址
                if (kwtWaybillOrderAddress.getAddressType().equals(NumberConstant.ONE)) {
                    kwtWaybillOrder.setStartLocationName(kwtWaybillOrderAddress.getName());
                    kwtWaybillOrder.setStartLocationAddress(kwtWaybillOrderAddress.getDetailAddress());
                }
                if (kwtWaybillOrderAddress.getAddressType().equals(NumberConstant.TWO)) {
                    kwtWaybillOrder.setEndLocationName(kwtWaybillOrderAddress.getName());
                    kwtWaybillOrder.setEndLocationAddress(kwtWaybillOrderAddress.getDetailAddress());
                }
            }
        }
        WaybillDataVO waybillDataVO = new WaybillDataVO();
        waybillDataVO.setTransportMessage(kwtWaybillOrder);

        // 车辆信息
        List<String> list = new ArrayList<>(NumberConstant.SIXTEEN);
        list.add(kwtWaybillOrder.getTruckNo());
        Map<String, RTruckVo> trucks = remoteFleetService.findTruck(list);
        WaybillCarVO waybillCarVO = new WaybillCarVO();
        if (CollectionUtils.isNotEmpty(trucks)) {
            waybillCarVO.setType(trucks.get(0).getTruckType());
            waybillCarVO.setTruckId(String.valueOf(trucks.get(0).getId()));
            waybillCarVO.setTrailerNo(trucks.get(0).getTrailerNo());
        }
        waybillCarVO.setDriverId(String.valueOf(kwtWaybillOrder.getDriverId()))
                .setTruckNo(kwtWaybillOrder.getTruckNo())
                .setDriverName(kwtWaybillOrder.getDriverName())
                .setDriverPhone(kwtWaybillOrder.getDriverPhone());
        waybillDataVO.setCarMessage(waybillCarVO);
        // 履约信息
        List<KwtWaybillOrderTicket> kwtWaybillOrderTicket = kwtWaybillOrderTicketMapper.selectList(new LambdaQueryWrapper<KwtWaybillOrderTicket>()
                .eq(KwtWaybillOrderTicket::getWOrderId, kwtWaybillOrder.getWOrderId()));
        WaybillTicketVO waybillTicketVO = new WaybillTicketVO();
        if (CollectionUtils.isNotEmpty(kwtWaybillOrderTicket)) {
            for (KwtWaybillOrderTicket ticket : kwtWaybillOrderTicket) {
                // 装货
                if (ticket.getType().equals(NumberConstant.ONE)) {
                    waybillTicketVO.setLoadUrl(ticket.getUrls())
                            .setLoadWeight(String.valueOf(ticket.getGrossAmount()))
                            .setLoadTime(String.valueOf(ticket.getCreateTime()));
                }
                // 卸货
                if (ticket.getType().equals(NumberConstant.TWO)) {
                    waybillTicketVO.setUnloadUrl(ticket.getUrls())
                            .setUnloadWeight(String.valueOf(ticket.getGrossAmount()))
                            .setUnloadTime(String.valueOf(ticket.getCreateTime()));
                }
            }
        }
        waybillDataVO.setAgreementMessage(waybillTicketVO);
        // 业务日志
        List<WaybillTrackVO> waybillTrackVOS = new ArrayList<>();
        List<KwtWaybillOrderTrack> kwtWaybillOrderTracks = kwtWaybillOrderTrackMapper.selectList(new LambdaQueryWrapper<KwtWaybillOrderTrack>()
                .eq(KwtWaybillOrderTrack::getWOrderId, kwtWaybillOrder.getWOrderId()));
        if (CollectionUtils.isNotEmpty(kwtWaybillOrderTracks)) {
            List<Long> userIds = new ArrayList<>();
            for (KwtWaybillOrderTrack track : kwtWaybillOrderTracks) {
                userIds.add(track.getCreateBy());
            }
            List<UserCacheResDto> users = remoteSystemService.queryUserCacheByIds(userIds);
            for (KwtWaybillOrderTrack track : kwtWaybillOrderTracks) {
                WaybillTrackVO waybillTrackVO = new WaybillTrackVO();
                waybillTrackVO.setId(String.valueOf(track.getId()))
                        .setRemark(track.getRemark())
                        .setStatus(String.valueOf(track.getStatus()))
                        .setCreateBy(String.valueOf(track.getCreateBy()));
                for (UserCacheResDto user : users) {
                    if (Long.valueOf(user.getId()).equals(track.getCreateBy())) {
                        waybillTrackVO.setCreateByName(user.getName())
                                .setCreateByPhone(user.getPhone());
                        break;
                    }
                }
                waybillTrackVOS.add(waybillTrackVO);
            }
        }
        waybillDataVO.setLogsMessage(waybillTrackVOS);
        return HttpResult.ok(waybillDataVO);
    }

    /**
     * 运单看板列表
     * @return
     */
    public HttpResult waybillIndex(WaybillOrderDTO query) {
        // mongo查询列数据，不足的数据单独关联表查询
        // 状态查询 status [2-8]
        List<Integer> statuses = new ArrayList<>();
        statuses.add(CarWaybillEnum.PENDING_VEHICLE.getCode());
        statuses.add(CarWaybillEnum.EXIT_COMPLETED.getCode());
        statuses.add(CarWaybillEnum.WAIT_LOADING.getCode());
        statuses.add(CarWaybillEnum.COMPLETION_LOADING.getCode());
        statuses.add(CarWaybillEnum.WAIT_UNLOADING.getCode());
        statuses.add(CarWaybillEnum.COMPLETION_UNLOADING.getCode());
        statuses.add(CarWaybillEnum.APPROVAL_COMPLETED.getCode());
        // 初始化各状态
        List<WaybillStatusVO> statusVOS = new ArrayList<>();
        statuses.forEach(e -> {
            WaybillStatusVO waybillStatusVO = new WaybillStatusVO();
            waybillStatusVO.setStatus(false);
            waybillStatusVO.setCode(e);
            switch (e){
                case 2 -> waybillStatusVO.setDestination("司机接单");
                case 3 -> waybillStatusVO.setDestination("出车");
                case 4 -> waybillStatusVO.setDestination("到装货地");
                case 5 -> waybillStatusVO.setDestination("装货");
                case 6 -> waybillStatusVO.setDestination("到卸货地");
                case 7 -> waybillStatusVO.setDestination("卸货");
                case 8 -> waybillStatusVO.setDestination("核单");
            }
            statusVOS.add(waybillStatusVO);
        });

        Criteria criteria = new Criteria();
        criteria.and("entId").is(LoginUserHolder.getEntId());
        criteria.and("delFlag").is(NumberConstant.ZERO);

        if (StringUtils.isNotBlank(query.getStatus())) {
            criteria.and("status").is(query.getStatus());
        } else {
            criteria.and("status").in(statuses);
        }
        // 装载时间
        if (StringUtils.isNotBlank(query.getStartLoadTime()) && StringUtils.isNotEmpty(query.getEndLoadTime())) {
            criteria.andOperator(Criteria.where("loadTime").gte(query.getStartLoadTime()), Criteria.where("loadTime")
                    .lte(query.getEndLoadTime()));
        }
        if (StringUtils.isNotBlank(query.getStartLoadTime()) && StringUtils.isNotEmpty(query.getEndLoadTime())) {
            criteria.andOperator(Criteria.where("loadTime").gte(query.getStartLoadTime()), Criteria.where("loadTime")
                    .lte(query.getEndLoadTime()));
        }
        // 派车时间
        if (StringUtils.isNotBlank(query.getStartSendCarTime()) && StringUtils.isNotEmpty(query.getEndSendCarTime())) {
            criteria.andOperator(Criteria.where("sendCarTime").gte(query.getStartSendCarTime()), Criteria.where("sendCarTime")
                    .lte(query.getEndSendCarTime()));
        }
        // 卸货时间
        if (StringUtils.isNotBlank(query.getStartUnloadTime()) && StringUtils.isNotEmpty(query.getEndUnloadTime())) {
            criteria.andOperator(Criteria.where("unloadTime").gte(query.getStartUnloadTime()), Criteria.where("unloadTime")
                    .lte(query.getEndUnloadTime()));
        }
        // 多条件模糊查询
        List<Criteria> orCriteria = new ArrayList<>();
        if (StringUtils.isNotBlank(query.getKeywords())) {
            /*Pattern pattern = Pattern.compile("^.*" + query.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
            orCriteria.add(Criteria.where("wOrderNo").regex(pattern));
            orCriteria.add(Criteria.where("truckNo").regex(pattern));
            orCriteria.add(Criteria.where("driverName").regex(pattern));
            orCriteria.add(Criteria.where("firmName").regex(pattern));
            orCriteria.add(Criteria.where("loadAddress").regex(pattern));
            orCriteria.add(Criteria.where("unloadAddress").regex(pattern));
            criteria.orOperator(orCriteria);*/
        }
        Query queryFormat = new Query(criteria);
        long total = mongoTemplate.count(queryFormat, SckwWaybillOrder.class);
        queryFormat.with(PageRequest.of(query.getPage() - 1, query.getPageSize(),
                Sort.by(Sort.Order.desc("createTime"))));
        // 执行查询
        List<SckwWaybillOrder> list = mongoTemplate.find(queryFormat, SckwWaybillOrder.class);
        // 查询关联单据信息
        List<WaybillBoardListVO> orders = new ArrayList<>();
        for (SckwWaybillOrder sckwWaybillOrder:list) {
            WaybillBoardListVO waybillBoardListVO = new WaybillBoardListVO();
            waybillBoardListVO.setWOrderId(String.valueOf(sckwWaybillOrder.getWOrderId()));
            waybillBoardListVO.setWOrderNo(String.valueOf(sckwWaybillOrder.getWOrderNo()));
            waybillBoardListVO.setGoodsName(String.valueOf(sckwWaybillOrder.getGoodsName()));
            waybillBoardListVO.setLoadDetailAddress(String.valueOf(sckwWaybillOrder.getLoadDetailAddress()));
            waybillBoardListVO.setUnloadDetailAddress(String.valueOf(sckwWaybillOrder.getUnloadDetailAddress()));
            waybillBoardListVO.setStartTime(DateUtil.getDateTime(sckwWaybillOrder.getStartTime()));
            waybillBoardListVO.setEndTime(DateUtil.getDateTime(sckwWaybillOrder.getEndTime()));
            waybillBoardListVO.setFirmName(String.valueOf(sckwWaybillOrder.getFirmName()));
            waybillBoardListVO.setCreateByName(String.valueOf(sckwWaybillOrder.getCreateByName()));
            waybillBoardListVO.setCreateTime(DateUtil.getDateTime(sckwWaybillOrder.getCreateTime()));
            waybillBoardListVO.setDriverName(String.valueOf(sckwWaybillOrder.getDriverName()));
            waybillBoardListVO.setDriverPhone(String.valueOf(sckwWaybillOrder.getDriverPhone()));
            waybillBoardListVO.setTruckNo(String.valueOf(sckwWaybillOrder.getTruckNo()));
            waybillBoardListVO.setLoadGrossAmount(sckwWaybillOrder.getLoadGrossAmount() != null ? String.valueOf(sckwWaybillOrder.getLoadGrossAmount()) : null);
            waybillBoardListVO.setUnloadGrossAmount(sckwWaybillOrder.getUnloadGrossAmount() != null ? String.valueOf(sckwWaybillOrder.getUnloadGrossAmount()) : null);
            waybillBoardListVO.setLoadUrls(sckwWaybillOrder.getLoadUrls() != null ? String.valueOf(sckwWaybillOrder.getLoadUrls()) : null);
            waybillBoardListVO.setUnloadUrls(sckwWaybillOrder.getUnloadUrls() != null ? String.valueOf(sckwWaybillOrder.getUnloadUrls()) : null);
            // 运单进度
            List<WaybillStatusVO> statusVOS2 = new ArrayList<>();
            BeanUtils.copyProperties(statusVOS, statusVOS2);
            log.error("XXXX-11 {}", statusVOS);
            log.error("XXXX-12 {}", statusVOS2);
            List<KwtWaybillOrderTrack> kwtWaybillOrderTracks = kwtWaybillOrderTrackMapper.selectList(new LambdaQueryWrapper<KwtWaybillOrderTrack>()
                    .eq(KwtWaybillOrderTrack::getWOrderId, sckwWaybillOrder.getWOrderId()));
            if (CollectionUtils.isNotEmpty(kwtWaybillOrderTracks)) {
                for (WaybillStatusVO waybillStatusVO: statusVOS2) {
                    for (KwtWaybillOrderTrack waybillOrderTrack: kwtWaybillOrderTracks) {
                        log.error("XXXX-1 {}", waybillStatusVO.getCode());
                        log.error("XXXX-2 {}", waybillOrderTrack.getStatus());
                        if(waybillStatusVO.getCode().equals(waybillOrderTrack.getStatus())) {
                            waybillStatusVO.setStatus(true);
                            waybillStatusVO.setCreateTime(DateUtil.getDateTime(waybillOrderTrack.getCreateTime()));
                            waybillStatusVO.setCreateByName(String.valueOf(waybillOrderTrack.getCreateBy()));
                        }
                    }
                }
            }
            waybillBoardListVO.setTracks(statusVOS);
            orders.add(waybillBoardListVO);
        }

        PageResult build = PageResult.build(query.getPage(), query.getPageSize(), total, orders);
        return HttpResult.ok(build);
    }
}
