package com.prolog.rdc.tms.service.intelligent.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.dao.mapper.TmsBaseBranchMapper;
import com.prolog.rdc.tms.dao.mapper.TmsBaseCustomerMapper;
import com.prolog.rdc.tms.dao.mapper.TmsBaseVehicleMapper;
import com.prolog.rdc.tms.dao.mapper.TmsBaseVehicleTypeMapper;
import com.prolog.rdc.tms.dao.mapper.TmsCustomerConsigneeMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillHeaderMapper;
import com.prolog.rdc.tms.model.dto.intelligent.BranchDTO;
import com.prolog.rdc.tms.model.dto.intelligent.ConsigneeDTO;
import com.prolog.rdc.tms.model.dto.intelligent.CustomerDTO;
import com.prolog.rdc.tms.model.dto.intelligent.VehicleDTO;
import com.prolog.rdc.tms.model.dto.intelligent.VehicleTypeDTO;
import com.prolog.rdc.tms.model.dto.intelligent.VehicleTypeVehicleDTO;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.model.entity.line.TmsBaseBranchModel;
import com.prolog.rdc.tms.model.entity.line.TmsBaseCustomerModel;
import com.prolog.rdc.tms.model.entity.line.TmsBaseVehicleModel;
import com.prolog.rdc.tms.model.entity.line.TmsBaseVehicleTypeModel;
import com.prolog.rdc.tms.model.entity.line.TmsCustomerConsignee;
import com.prolog.rdc.tms.service.SysRefdatadService;
import com.prolog.rdc.tms.service.intelligent.IntelligentVehicleService;
import com.prolog.rdc.tms.util.PublicMethods;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author hongbo.pan
 * @date 2023/8/28
 */
@Slf4j
@Service
public class IntelligentVehicleServiceImpl implements IntelligentVehicleService {

    @Autowired
    private TmsBaseVehicleTypeMapper vehicleTypeMapper;

    @Autowired
    private TmsBaseVehicleMapper vehicleMapper;

    @Autowired
    private TmsBaseBranchMapper branchMapper;

    @Autowired
    private TmsBaseCustomerMapper customerMapper;

    @Autowired
    private TmsCustomerConsigneeMapper consigneeMapper;

    @Autowired
    private TmsLoadingBillHeaderMapper loadingBillHeaderMapper;

    @Autowired
    private SysRefdatadService sysRefdatadService;

    @Override
    public List<VehicleTypeVehicleDTO> groupByVehicleType() {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        return vehicleTypeMapper.groupByVehicleType(user.getEnterpriseId());
    }

    @Override
    public List<VehicleTypeVehicleDTO> groupByVehicle() {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        List<VehicleTypeVehicleDTO> vehicleTypeDTOList = vehicleTypeMapper.groupByVehicleType(user.getEnterpriseId());
        if (CollectionUtil.isNotEmpty(vehicleTypeDTOList)) {
            List<Map<String, Object>> vehicleTypeBrand = sysRefdatadService.getDropDownById(DataDictionaryConstant.VEHICLE_TYPE_BRAND, null, null, null);
            List<Map<String, Object>> vehicleTypeCategory = sysRefdatadService.getDropDownById(DataDictionaryConstant.VEHICLE_TYPE_CATEGORY, null, null, null);
            List<Map<String, Object>> vehicleType = sysRefdatadService.getDropDownById(DataDictionaryConstant.VEHICLE_TYPE, null, null, null);
            vehicleTypeDTOList.forEach(vehicleTypeVehicleDTO -> {
                vehicleTypeVehicleDTO.setBrandName(PublicMethods.change(vehicleTypeBrand, String.valueOf(vehicleTypeVehicleDTO.getBrand())));
                vehicleTypeVehicleDTO.setTypeName(PublicMethods.change(vehicleTypeCategory, String.valueOf(vehicleTypeVehicleDTO.getType())));
                Criteria criteria = Criteria.forClass(TmsBaseVehicleModel.class);
                Restriction r1 = Restrictions.eq(TmsBaseVehicleModel::getVehicleTypeId, vehicleTypeVehicleDTO.getId());
                Restriction r2 = Restrictions.eq(TmsBaseVehicleModel::getStatus, StatusConstant.STATUS_ENABLE);
                Restriction r3 = Restrictions.eq(TmsBaseVehicleModel::getEnterpriseId, user.getEnterpriseId());
                criteria.setRestriction(Restrictions.and(r1, r2, r3));
                List<TmsBaseVehicleModel> vehicleModelList = vehicleMapper.findByCriteria(criteria);
                if (CollectionUtil.isNotEmpty(vehicleModelList)) {
                    vehicleTypeVehicleDTO.setVehicleDTOList(vehicleModelList.stream().map(vehicleModel -> {
                        VehicleDTO vehicleDTO = BeanUtil.copyProperties(vehicleModel, VehicleDTO.class);
                        vehicleDTO.setTypeName(PublicMethods.change(vehicleType, String.valueOf(vehicleDTO.getType())));
                        Criteria cl = Criteria.forClass(TmsLoadingBillHeaderModel.class);
                        Restriction rl1 = Restrictions.eq(TmsLoadingBillHeaderModel::getVehicleId,vehicleDTO.getId());
                        Restriction rl2 = Restrictions.ge(TmsLoadingBillHeaderModel::getCreatetime, DateUtil.today());
                        Restriction rl3 = Restrictions.lt(TmsLoadingBillHeaderModel::getCreatetime, DateUtil.tomorrow().toDateStr());
                        Restriction rl4 = Restrictions.eq(TmsLoadingBillHeaderModel::getEnterpriseId, user.getEnterpriseId());
                        cl.setRestriction(Restrictions.and(rl1, rl2, rl3, rl4));
                        List<TmsLoadingBillHeaderModel> loadingBillHeaderList = loadingBillHeaderMapper.findByCriteria(cl);
                        if (CollectionUtil.isEmpty(loadingBillHeaderList) || loadingBillHeaderList.stream().allMatch(
                                loadingBillHeader -> loadingBillHeader.getStatus() > DataDictionaryConstant.LOADING_BILL_STATUS_SD)) {
                            vehicleDTO.setVehicleStatus(0);
                            vehicleDTO.setVehicleStatusName("闲");
                        } else {
                            vehicleDTO.setVehicleStatus(1);
                            vehicleDTO.setVehicleStatusName("送");
                        }
                        return vehicleDTO;
                    }).collect(Collectors.toList()));
                }
            });
        }
        return vehicleTypeDTOList;
    }

    @Override
    public List<VehicleDTO> findVehicleByPlateNumberList(List<String> plateNumberList) {
        Criteria criteria = Criteria.forClass(TmsBaseVehicleModel.class);
        Restriction r1 = Restrictions.in(TmsBaseVehicleModel::getPlateNumber, plateNumberList);
        criteria.setRestriction(Restrictions.and(r1));
        List<TmsBaseVehicleModel> vehicleList = vehicleMapper.findByCriteria(criteria);
        return vehicleList.stream().map(vehicle -> BeanUtil.copyProperties(vehicle, VehicleDTO.class)).collect(Collectors.toList());
    }

    @Override
    public List<VehicleDTO> findVehicleByIdList(List<Long> idList) {
        List<TmsBaseVehicleModel> vehicleList = vehicleMapper.findByIds(TmsBaseVehicleModel.class, idList.toArray(), null);
        return vehicleList.stream().map(vehicle -> BeanUtil.copyProperties(vehicle, VehicleDTO.class)).collect(Collectors.toList());
    }

    @Override
    public List<VehicleTypeDTO> findVehicleTypeByIdList(List<Long> idList) {
        List<TmsBaseVehicleTypeModel> vehicleTypeList = vehicleTypeMapper.findByIds(TmsBaseVehicleTypeModel.class, idList.toArray(), null);
        return vehicleTypeList.stream().map(vehicleType -> BeanUtil.copyProperties(vehicleType, VehicleTypeDTO.class)).collect(Collectors.toList());
    }

    @Override
    public List<BranchDTO> findBranchByIdList(List<Long> idList) {
        List<TmsBaseBranchModel> branchList = branchMapper.findByIds(TmsBaseBranchModel.class, idList.toArray(), null);
        return branchList.stream().map(branch -> BeanUtil.copyProperties(branch, BranchDTO.class)).collect(Collectors.toList());
    }

    @Override
    public List<CustomerDTO> findCustomerByIdList(List<Long> idList) {
        List<TmsBaseCustomerModel> customerList = customerMapper.findByIds(TmsBaseCustomerModel.class, idList.toArray(), null);
        return customerList.stream().map(customer -> BeanUtil.copyProperties(customer, CustomerDTO.class)).collect(Collectors.toList());
    }

    @Override
    public List<ConsigneeDTO> findConsigneeByIdList(List<Long> idList) {
        List<TmsCustomerConsignee> consigneeList = consigneeMapper.findByIds(TmsCustomerConsignee.class, idList.toArray(), null);
        return consigneeList.stream().map(consignee -> BeanUtil.copyProperties(consignee, ConsigneeDTO.class)).collect(Collectors.toList());
    }

}
