package com.clx.performance.service.impl;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.clx.order.feign.AddressFeign;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignAddressVO;
import com.clx.order.vo.feign.FeignOrderVO;
import com.clx.performance.dao.OrderChildImageDao;
import com.clx.performance.dto.gd.GdPosDTO;
import com.clx.performance.dto.gd.GdRouteDTO;
import com.clx.performance.enums.PowerTypeEnum;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.OrderChildImage;
import com.clx.performance.model.OrderGoods;
import com.clx.performance.model.settle.SettlementDriverDetail;
import com.clx.performance.model.settle.SettlementOwnerDetail;
import com.clx.performance.param.feign.transport.*;
import com.clx.performance.service.TransportSyncService;
import com.clx.performance.utils.gd.GdService;
import com.clx.user.feign.DriverFeign;
import com.clx.user.feign.TruckFeign;
import com.clx.user.vo.feign.*;
import com.msl.common.base.Optional;
import com.msl.common.utils.DateUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class TransportSyncServiceImpl implements TransportSyncService {

    private final OrderChildImageDao orderChildImageDao;
    private final AddressFeign addressFeign;
    private final OrderFeign orderFeign;
    private final TruckFeign truckFeign;
    private final DriverFeign driverFeign;
    private final GdService gdService;

    @Override
    public ThirdOrderChildBrokerParam generateOrderChildSync(OrderChild orderChild, OrderGoods orderGoods, SettlementOwnerDetail settlementOwnerDetail,SettlementDriverDetail settlementDriverDetail) {
        FeignOrderVO orderInfoFeign = orderFeign.getOrderInfoFeign(orderGoods.getOrderNo());
        ThirdOrderChildBrokerParam param = new ThirdOrderChildBrokerParam();
        FeignAddressVO data = addressFeign.getSendAndReceiveAddress(orderChild.getSendAddressId(), orderChild.getReceiveAddressId()).getData();
        FeignAddressVO.Address receiveAddress = data.getReceiveAddress();
        FeignAddressVO.Address sendAddress = data.getSendAddress();
        //生成基础参数
        generateBaseInfo(orderChild, orderGoods, param, sendAddress, receiveAddress, orderInfoFeign, settlementOwnerDetail,settlementDriverDetail);
        //生成货单数据
        generateOrderGoods(orderGoods, orderChild, sendAddress, receiveAddress, param);
        //生成车辆信息
        generateTruckInfo(orderChild, param);
        List<GdRouteDTO> route = gdService.getRoute(orderGoods.getSendLongitude().setScale(4, RoundingMode.DOWN)
                , orderGoods.getSendLatitude().setScale(4, RoundingMode.DOWN),
                orderGoods.getReceiveLongitude().setScale(4, RoundingMode.DOWN),
                orderGoods.getReceiveLatitude().setScale(4, RoundingMode.DOWN));
        GdRouteDTO gdRouteDTO = route.get(0);
        BigDecimal divide = new BigDecimal(gdRouteDTO.getDistance()).divide(new BigDecimal(1000));
        param.setDistance(divide);


        SyncOrderChildVO syncOrderChildVO = driverFeign.getSyncOrderChild(orderChild.getDriverUserNo(), orderChild.getTruckOwnUserNo()).getData();
        DriverInfoFeignVo truckOwnerInfo = syncOrderChildVO.getTruckOwnerInfo();
        DriverInfoFeignVo diverInfo = syncOrderChildVO.getDiverInfo();
        BankCardVO driverBankCard = syncOrderChildVO.getDriverBankCard();
        UserIdCardVO driverUserIdCardVO = syncOrderChildVO.getDriverUserIdCardVO();
        BankCardVO truckOwnerBankCard = syncOrderChildVO.getTruckOwnerBankCard();
        UserIdCardVO truckOwnerUserIdCardVO = syncOrderChildVO.getTruckOwnerUserIdCardVO();
        DriverLicenceFeignVO driverLicenceFeignVO = syncOrderChildVO.getDriverLicenceFeignVO();
        DriverLicenceFeignVO truckOwnerLicenceFeignVO = syncOrderChildVO.getTruckOwnerLicenceFeignVO();
        log.info("=============================================================");
        log.info("orderChild:{}", JSONUtil.parse(orderChild));
        log.info("orderGoods:{}", JSONUtil.parse(orderGoods));
        log.info("orderInfoFeign:{}", JSONUtil.parse(orderInfoFeign));
        log.info("settlementOwnerDetail:{}", JSONUtil.parse(settlementOwnerDetail));
        log.info("route:{}", JSONUtil.parse(route));
        log.info("syncOrderChildVO:{}", JSONUtil.parse(syncOrderChildVO));
        log.info("receiveAddress:{}", JSONUtil.parse(receiveAddress));
        log.info("sendAddress:{}", JSONUtil.parse(sendAddress));
        log.info("=============================================================");
        //设置司机银行卡
        generateDriverBankCard(driverBankCard, driverUserIdCardVO, param);
        //设置车主银行卡
        generateTruckDriverBankCard(truckOwnerBankCard, truckOwnerUserIdCardVO, param);
        //司机信息
        generateDriverInfoDTO(diverInfo, driverLicenceFeignVO, driverUserIdCardVO, param);
        //车主信息
        generateTruckDriverInfoDTO(truckOwnerInfo, truckOwnerLicenceFeignVO, truckOwnerUserIdCardVO, param);
        //设置轨迹
        generateRouteList(gdRouteDTO, param);
        return param;
    }

    private void generateBaseInfo(OrderChild orderChild, OrderGoods orderGoods, ThirdOrderChildBrokerParam param,
                                  FeignAddressVO.Address sendAddress,
                                  FeignAddressVO.Address receiveAddress, FeignOrderVO orderInfoFeign,
                                  SettlementOwnerDetail settlementOwnerDetail,
                                  SettlementDriverDetail settlementDriverDetail
    ) {
        param.setChildNo(orderChild.getChildNo());
        param.setTruckNo(orderChild.getTruckNo());
        param.setFreightPrice(Integer.valueOf(orderChild.getFreightPrice().toString()));
        param.setFreight(Integer.valueOf(orderChild.getFreight().toString()));
        param.setLoadNet(orderChild.getLoadNet());
        param.setNet(orderChild.getUnloadNet());
        param.setSendAddress(orderGoods.getSendAddressShorter());
        param.setSendProvince(sendAddress.getProvince());
        param.setSendCity(sendAddress.getCity());
        param.setSendCounty(sendAddress.getCounty());
        param.setSendTown(sendAddress.getTown());
        param.setSendName(sendAddress.getContact());
        param.setSendMobile(sendAddress.getContactPhone());
        param.setFreightNoCard(settlementDriverDetail.getSettlementFreight().intValue());
        param.setReceiveAddress(orderChild.getReceiveAddress());
        param.setReceiveProvince(receiveAddress.getProvince());
        param.setReceiveCity(receiveAddress.getCity());
        param.setReceiveCounty(receiveAddress.getCounty());
        param.setReceiveTown(receiveAddress.getTown());
        param.setReceiveName(receiveAddress.getContact());
        param.setReceiveMobile(receiveAddress.getContactPhone());
        param.setLoadLongitude(orderGoods.getSendLongitude().toString());
        param.setLoadLatitude(orderGoods.getSendLatitude().toString());
        param.setUnloadLongitude(orderGoods.getReceiveLongitude().toString());
        param.setUnloadLatitude(orderGoods.getReceiveLatitude().toString());
        param.setPayTime(DateUtils.formatDateTime(orderChild.getPayTime()).get());
        param.setLoadTime(DateUtils.formatDateTime(orderChild.getLoadTime()).get());
        param.setUnloadTime(DateUtils.formatDateTime(orderChild.getUnloadTime()).get());
        param.setPayFinishedTime(DateUtils.formatDateTime(orderChild.getFinishTime()).get());
        param.setReceiveNet(orderChild.getUnloadNet());
        param.setAdvanceType(0);

        param.setSourceOrderNo(orderChild.getOrderNo());
        param.setSourceGoodsNo(orderChild.getOrderGoodsNo());
        param.setSourceInvoicingType(settlementOwnerDetail.getSettlementWay());
        param.setSourceFreightPrice(settlementOwnerDetail.getFreightPrice());
        param.setSourceInvoicingPrice(settlementOwnerDetail.getInvoiceFreight());
        param.setSourceLossPrice(settlementOwnerDetail.getLossFreight());

        param.setInvoiceRelationNo(orderInfoFeign.getContactPhoneOwner());
        Optional<List<OrderChildImage>> listOptional = orderChildImageDao.listLoadAndUnload(orderChild.getChildNo());
        if (listOptional.isPresent()) {
            List<OrderChildImage> orderChildImages = listOptional.get();
            List<String> loadPoundImages = orderChildImages.stream().filter(i -> {
                        return i.getType().equals(1);
                    }
            ).map(OrderChildImage::getImage).collect(Collectors.toList());
            List<String> unLoadPoundImages = orderChildImages.stream().filter(i -> {
                        return i.getType().equals(2);
                    }
            ).map(OrderChildImage::getImage).collect(Collectors.toList());
            param.setLoadPoundImages(loadPoundImages);
            param.setUnLoadPoundImages(unLoadPoundImages);
        }

    }

    //处理货单数据
    private void generateOrderGoods(OrderGoods orderGoods, OrderChild orderChild, FeignAddressVO.Address sendAddress,
                                    FeignAddressVO.Address receiveAddress, ThirdOrderChildBrokerParam param) {
        ThirdOrderInfoDTO orderGoodsDto = new ThirdOrderInfoDTO();
        orderGoodsDto.setOrderNo(orderGoods.getOrderGoodsNo());
        orderGoodsDto.setGoodsName(orderGoods.getGoodsName());
        orderGoodsDto.setSendProvince(sendAddress.getProvince());
        orderGoodsDto.setSendCity(sendAddress.getCity());
        orderGoodsDto.setSendCounty(sendAddress.getCounty());
        orderGoodsDto.setSendTown(sendAddress.getTown());
        orderGoodsDto.setSendAddress(sendAddress.getAddress());
        orderGoodsDto.setSendName(sendAddress.getContact());
        orderGoodsDto.setSendMobile(sendAddress.getContactPhone());
        orderGoodsDto.setLoadLongitude(orderGoods.getSendLongitude().toString());
        orderGoodsDto.setLoadLatitude(orderGoods.getSendLatitude().toString());
        orderGoodsDto.setReceiveAddress(orderChild.getReceiveAddress());
        orderGoodsDto.setReceiveProvince(receiveAddress.getProvince());
        orderGoodsDto.setReceiveCity(receiveAddress.getCity());
        orderGoodsDto.setReceiveCounty(receiveAddress.getCounty());
        orderGoodsDto.setReceiveTown(receiveAddress.getTown());
        orderGoodsDto.setReceiveName(receiveAddress.getContact());
        orderGoodsDto.setReceiveMobile(receiveAddress.getContactPhone());
        orderGoodsDto.setUnloadLongitude(orderGoods.getReceiveLongitude().toString());
        orderGoodsDto.setUnloadLatitude(orderGoods.getReceiveLatitude().toString());
        orderGoodsDto.setGoodsPrice(Integer.valueOf(orderChild.getOrderFreightPrice().toString()));
        orderGoodsDto.setTransPrice(Integer.valueOf(orderChild.getFreightPrice().toString()));
        orderGoodsDto.setGoodsAmount(orderGoods.getExtractWeight());
        orderGoodsDto.setExtractTime(DateUtils.formatDateTime(orderGoods.getLastLoadTime()).get());
        orderGoodsDto.setArriveTime(DateUtils.formatDateTime(orderGoods.getLastArriveSendTime()).get());
        param.setOrderInfoDTO(orderGoodsDto);
    }

    //车辆信息
    public void generateTruckInfo(OrderChild orderChild, ThirdOrderChildBrokerParam param) {
        TruckInfoFeignVo truckInfoFeignVo = truckFeign.getTruckInfo(orderChild.getTruckId()).getData();
        log.info("++++++++++++++++++++++++++++++++++++++++++++++++++truckInfoFeignVo++++++++++++++++" + JSONUtil.parse(truckInfoFeignVo));
        OrderChildTruckInfoDTO truckInfoDTO = new OrderChildTruckInfoDTO();
        DriverInfoFeignVo ownerInfo = driverFeign.getDriverInfo(orderChild.getTruckOwnUserNo()).getData();
        truckInfoDTO.setMobile(ownerInfo.getMobile());
        truckInfoDTO.setTruckNo(orderChild.getTruckNo());
        truckInfoDTO.setTruckNoColor(truckInfoFeignVo.getTruckNoColor());
        truckInfoDTO.setModel(truckInfoFeignVo.getModel());
        truckInfoDTO.setLoad(truckInfoFeignVo.getLoad());
        truckInfoDTO.setGrossMass(truckInfoFeignVo.getGrossMass() == null ? null : truckInfoFeignVo.getGrossMass().intValue());
        truckInfoDTO.setRoadTransportCertificateNo(truckInfoFeignVo.getRoadTransportCertificateNo());
        truckInfoDTO.setLicenceImgMain(truckInfoFeignVo.getLicenceImgMain());
        truckInfoDTO.setLicenceImgSecond(truckInfoFeignVo.getLicenceImgSecond());
        truckInfoDTO.setLicenceImgSecondBack(truckInfoFeignVo.getLicenceImgSecondBack());
        truckInfoDTO.setTransportLicenceImg(truckInfoFeignVo.getTransportLicenceImg());
        if (StringUtils.isNotBlank(truckInfoFeignVo.getPowerType())) {
            //"车辆燃料类型 1：柴油 2 天然气 3其他 4新能源/电"
            truckInfoDTO.setPowerType(PowerTypeEnum.Type.getCodeByName(truckInfoFeignVo.getPowerType()));
        }
        truckInfoDTO.setUseNature(truckInfoFeignVo.getUseNature());
        truckInfoDTO.setIdentifyCode(truckInfoFeignVo.getIdentifyCode());
        truckInfoDTO.setLicenceIssueOrganization(truckInfoFeignVo.getLicenceIssueOrganization());
        truckInfoDTO.setRegisterDate(truckInfoFeignVo.getRegisterDate() == null ? null : DateUtils.formatDateTime(truckInfoFeignVo.getRegisterDate()).get());
        truckInfoDTO.setLicenceIssueDate(truckInfoFeignVo.getLicenceIssueDate() == null ? null : DateUtils.formatDateTime(truckInfoFeignVo.getLicenceIssueDate()).get());
        truckInfoDTO.setDrivingLicenseEndTime(truckInfoFeignVo.getLicenceImgMainEndTime() == null ? null : DateUtils.formatDateTime(truckInfoFeignVo.getLicenceImgMainEndTime()).get());
        param.setTruckInfoDTO(truckInfoDTO);
    }

    //车主信息
    public void generateTruckDriverInfoDTO(DriverInfoFeignVo truckOwnerInfo, DriverLicenceFeignVO licenceVO, UserIdCardVO idCardVO, ThirdOrderChildBrokerParam param) {
        OrderChildDriverInfoDTO dto = new OrderChildDriverInfoDTO();
        dto.setMobile(truckOwnerInfo.getMobile());
        dto.setName(truckOwnerInfo.getName());
        dto.setSex(idCardVO.getSex());
        dto.setCardNo(idCardVO.getCardNo());
        dto.setCardStartTime(idCardVO.getCardStartTime());
        dto.setCardEndTime(idCardVO.getCardEndTime());
        dto.setCardLongTerm(idCardVO.getCardLongTerm());
        dto.setCardFrontImg(idCardVO.getCardFaceImg());
        dto.setCardBackImg(idCardVO.getCardBackImg());
        dto.setFaceCardImg(idCardVO.getCardFaceImg());
        dto.setLicenceNo(licenceVO.getLicenceNo());
        dto.setLicenseTime(licenceVO.getLicenceTime() == null ? null : DateUtils.formatDateTime(licenceVO.getLicenceTime()).get());
        dto.setLicenceClass(licenceVO.getLicenceClass());
        dto.setLicenceImg(licenceVO.getLicenceImg());
        dto.setLicenceBackImg(licenceVO.getLicenceBackImg());
        dto.setLicenceStartTime(Optional.ofNullable(licenceVO.getLicenceStartTime()).isPresent() ?  DateUtils.formatDateTime(licenceVO.getLicenceStartTime()).get() : null);
        dto.setLicenceEndTime(Optional.ofNullable(licenceVO.getLicenceEndTime()).isPresent() ? DateUtils.formatDateTime(licenceVO.getLicenceEndTime()).get() : "2099-12-31 00:00:00");
        dto.setOccupationalLicenceNo(licenceVO.getOccupationalLicenceNo());
        dto.setOccupationalLicenceImg(licenceVO.getOccupationalLicenceImg());
        dto.setOccupationalStartTime(licenceVO.getOccupationalLicenceStartTime() == null ? null : DateUtils.formatDateTime(licenceVO.getOccupationalLicenceStartTime()).get());
        dto.setOccupationalEndTime(licenceVO.getOccupationalLicenceEndTime() == null ? null : DateUtils.formatDateTime(licenceVO.getOccupationalLicenceEndTime()).get());
        dto.setLicenceIssueOrganization(licenceVO.getLicenceIssueOrganization());
        dto.setIdCardAddress(idCardVO.getAddress());
        param.setTruckDriverInfoDTO(dto);
    }

    //司机信息
    public void generateDriverInfoDTO(DriverInfoFeignVo driverInfo, DriverLicenceFeignVO licenceVO, UserIdCardVO idCardVO, ThirdOrderChildBrokerParam param) {
        OrderChildDriverInfoDTO dto = new OrderChildDriverInfoDTO();
        dto.setMobile(driverInfo.getMobile());
        dto.setName(driverInfo.getName());
        dto.setSex(idCardVO.getSex());
        dto.setCardNo(idCardVO.getCardNo());
        dto.setCardStartTime(idCardVO.getCardStartTime());
        dto.setCardEndTime(idCardVO.getCardEndTime());
        dto.setCardLongTerm(idCardVO.getCardLongTerm());
        dto.setCardFrontImg(idCardVO.getCardFaceImg());
        dto.setCardBackImg(idCardVO.getCardBackImg());
        dto.setFaceCardImg(idCardVO.getCardFaceImg());
        dto.setLicenceNo(licenceVO.getLicenceNo());
        dto.setLicenseTime(licenceVO.getLicenceTime() == null ? null : DateUtils.formatDateTime(licenceVO.getLicenceTime()).get());
        dto.setLicenceClass(licenceVO.getLicenceClass());
        dto.setLicenceImg(licenceVO.getLicenceImg());
        dto.setLicenceBackImg(licenceVO.getLicenceBackImg());
        dto.setLicenceStartTime(licenceVO.getLicenceStartTime() == null ? null : DateUtils.formatDateTime(licenceVO.getLicenceStartTime()).get());
        dto.setLicenceEndTime(Optional.ofNullable(licenceVO.getLicenceEndTime()).isPresent() ? DateUtils.formatDateTime(licenceVO.getLicenceEndTime()).get() : "2099-12-31 00:00:00");
        dto.setOccupationalLicenceNo(licenceVO.getOccupationalLicenceNo());
        dto.setOccupationalLicenceImg(licenceVO.getOccupationalLicenceImg());
        dto.setOccupationalStartTime(licenceVO.getOccupationalLicenceStartTime() == null ? null : DateUtils.formatDateTime(licenceVO.getOccupationalLicenceStartTime()).get());
        dto.setOccupationalEndTime(licenceVO.getOccupationalLicenceEndTime() == null ? null : DateUtils.formatDateTime(licenceVO.getOccupationalLicenceEndTime()).get());
        dto.setLicenceIssueOrganization(licenceVO.getLicenceIssueOrganization());
        dto.setIdCardAddress(idCardVO.getAddress());
        param.setDriverInfoDTO(dto);
    }

    //司机银行卡
    public void generateDriverBankCard(BankCardVO bankCardVO, UserIdCardVO idCardVO, ThirdOrderChildBrokerParam param) {
        OrderChildBankInfoDTO dto = new OrderChildBankInfoDTO();
        dto.setName(bankCardVO.getName());
        dto.setCardNo(bankCardVO.getCardNo());
        dto.setMobile(bankCardVO.getMobile());
        dto.setAccountType(StringUtils.isBlank(bankCardVO.getAccountType()) ? null : Integer.valueOf(bankCardVO.getAccountType()));
        dto.setType(bankCardVO.getType());
        dto.setIdCard(bankCardVO.getIdCard());
        dto.setBank(bankCardVO.getBank());
        dto.setBankCode(bankCardVO.getBankCode());
        dto.setIdCardFrontImg(idCardVO.getCardFaceImg());
        dto.setIdCardBackImg(idCardVO.getCardBackImg());
        param.setDriverBankInfoDTO(dto);
    }

    //车主银行卡
    public void generateTruckDriverBankCard(BankCardVO bankCardVO, UserIdCardVO idCardVO, ThirdOrderChildBrokerParam param) {
        OrderChildBankInfoDTO dto = new OrderChildBankInfoDTO();
        dto.setName(bankCardVO.getName());
        dto.setCardNo(bankCardVO.getCardNo());
        dto.setMobile(bankCardVO.getMobile());
        dto.setAccountType(StringUtils.isBlank(bankCardVO.getAccountType()) ? null : Integer.valueOf(bankCardVO.getAccountType()));
        dto.setType(bankCardVO.getType());
        dto.setIdCard(bankCardVO.getIdCard());
        dto.setBank(bankCardVO.getBank());
        dto.setBankCode(bankCardVO.getBankCode());
        dto.setIdCardFrontImg(idCardVO.getCardFaceImg());
        dto.setIdCardBackImg(idCardVO.getCardBackImg());
        param.setTruckDriverBankInfoDTO(dto);
    }

    public void generateRouteList(GdRouteDTO gdRouteDTO, ThirdOrderChildBrokerParam param) {
        List<OrderChildTruckTraceDTO> list = new LinkedList<>();
        log.info("轨迹我"+ JSONUtil.parse(gdRouteDTO));
        for (int i = 0; i < gdRouteDTO.getPosList().size(); i++) {
            if (i == 6) {
                OrderChildTruckTraceDTO dto = new OrderChildTruckTraceDTO();
                GdPosDTO gdPosDTO = gdRouteDTO.getPosList().get(gdRouteDTO.getPosList().size() - 1);
                BigDecimal longitude = gdPosDTO.getLongitude();
                BigDecimal latitude = gdPosDTO.getLatitude();
                String address = gdService.getLonLat(longitude + "," + latitude);
                dto.setLocationAddress(address);
                dto.setLocationTime(LocalDateTime.now().toString());
                dto.setLocationLon(longitude.toString());
                dto.setLocationLat(latitude.toString());
                list.add(dto);
                return;
            }
            if (i == 0) {
                OrderChildTruckTraceDTO dto = new OrderChildTruckTraceDTO();
                GdPosDTO gdPosDTO = gdRouteDTO.getPosList().get(i);
                BigDecimal longitude = gdPosDTO.getLongitude();
                BigDecimal latitude = gdPosDTO.getLatitude();
                String address = gdService.getLonLat(longitude + "," + latitude);
                dto.setLocationAddress(address);
                dto.setLocationTime(LocalDateTime.now().toString());
                dto.setLocationLon(longitude.toString());
                dto.setLocationLat(latitude.toString());
                list.add(dto);
            } else {
                OrderChildTruckTraceDTO dto = new OrderChildTruckTraceDTO();
                int randomNum = (int) (Math.random() * (gdRouteDTO.getPosList().size() - 1) + 1);

                GdPosDTO gdPosDTO = gdRouteDTO.getPosList().get(randomNum);
                BigDecimal longitude = gdPosDTO.getLongitude();
                BigDecimal latitude = gdPosDTO.getLatitude();
                String address = gdService.getLonLat(longitude + "," + latitude);
                dto.setLocationAddress(address);
                dto.setLocationTime(LocalDateTime.now().toString());
                dto.setLocationLon(longitude.toString());
                dto.setLocationLat(latitude.toString());
                list.add(dto);
            }
        }
        param.setBrokerTraceList(list);
    }
}
