package com.ningdatech.carapi.industry.manage;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoService;
import com.ningdatech.carapi.common.aop.BuildChildrenRegionWrapper;
import com.ningdatech.carapi.common.constant.UserRoleTypeEnum;
import com.ningdatech.carapi.common.constant.VehicleTypeEnum;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.datascope.contants.LambdaDataScopeTypeEnum;
import com.ningdatech.carapi.industry.entity.RegistrationRecord;
import com.ningdatech.carapi.industry.model.dto.RegistrationRecordPageParamDTO;
import com.ningdatech.carapi.industry.model.dto.RegistrationRecordSaveDTO;
import com.ningdatech.carapi.industry.model.dto.RegistrationRecordUpdateDTO;
import com.ningdatech.carapi.industry.model.vo.RegistrationRecordVO;
import com.ningdatech.carapi.industry.service.IRegistrationRecordService;
import com.ningdatech.carapi.sys.entity.dto.OperatorQueryDTO;
import com.ningdatech.carapi.sys.helper.OperatorsCacheHelper;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @Classname RegistrationRecordManage
 * @Description
 * @Date 2022/11/06 17:57
 * @Created by PoffyZhang
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class RegistrationRecordManage {

    private final IRegistrationRecordService registrationRecordService;
    private final OperatorsCacheHelper operatorsCacheHelper;
    private final IVehicleBaseInfoService vehicleBaseInfoService;

    public PageVo<RegistrationRecordVO> infoList(RegistrationRecordPageParamDTO param) {
        Page<RegistrationRecord> page = param.page();

        // 按照登录用户，如果是运营商账号登录，删选出该运营商关联的车辆信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Long roleId = userDetail.getRoleId();
        if (UserRoleTypeEnum.OPERATOR_ROLE_ID.getId().equals(roleId)) {
            String companyName = userDetail.getCompanyName();
            // 暂时控制运营商名称和运营商所在企业名称相同
            OperatorQueryDTO operatorQueryDTO = operatorsCacheHelper.getByName(companyName);
            // 获取运营商ID
            Long operatorId = operatorQueryDTO.getId();
            // 查询出该运营商下所有车辆
            List<NdVehicleBaseInfo> baseInfoList = vehicleBaseInfoService.list(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
                    .eq(NdVehicleBaseInfo::getOperatorId, operatorId));
            List<String> carPlateList = baseInfoList.stream().map(NdVehicleBaseInfo::getCarPlate).collect(Collectors.toList());
            param.setCarPlateList(carPlateList);
        }

        LambdaQueryWrapper<RegistrationRecord> wrapper = Wrappers.lambdaQuery(RegistrationRecord.class);
        RegistrationRecordManage context = (RegistrationRecordManage) AopContext.currentProxy();
        context.search(page,wrapper,param);
        if(CollUtil.isEmpty(page.getRecords())){
            return PageVo.empty();
        }
        List<RegistrationRecordVO> data = page.getRecords().stream().map(w -> convert(w)).collect(Collectors.toList());
        return PageVo.of(data, page.getTotal());
    }

    public RegistrationRecordVO details(Long id) {

        LambdaQueryWrapper<RegistrationRecord> wrapper = Wrappers.lambdaQuery(RegistrationRecord.class);
        RegistrationRecordManage context = (RegistrationRecordManage) AopContext.currentProxy();
        context.buildQuery(wrapper, id);
        RegistrationRecord record = registrationRecordService.getOne(wrapper);
        if (Objects.isNull(record)){
            return null;
        }
        //RegistrationRecord record = registrationRecordService.getById(id);
        return convert(record);
    }

    @LambdaDataScope(type = LambdaDataScopeTypeEnum.ALL)
    public void buildQuery(LambdaQueryWrapper<RegistrationRecord> wrapper, Long id) {
        wrapper.eq(RegistrationRecord::getId,id);
    }


    /**
     * 查询
     * @param page
     * @param param
     */
    @LambdaDataScope(wrapperIndex = 1)
    @BuildChildrenRegionWrapper(wrapperIndex = 1,entityIndex = 2)
    public void search(Page<RegistrationRecord> page,LambdaQueryWrapper<RegistrationRecord> wrapper,RegistrationRecordPageParamDTO param) {
        wrapper.like(StringUtils.isNotBlank(param.getCompanyName()), RegistrationRecord::getCompanyName, param.getCompanyName())
                .like(StringUtils.isNotBlank(param.getCarPlate()), RegistrationRecord::getCarPlate, param.getCarPlate())
                .like(StringUtils.isNotBlank(param.getRegistrationRecord()), RegistrationRecord::getRegistrationRecord, param.getRegistrationRecord())
                .eq(Objects.nonNull(param.getVehicleType()), RegistrationRecord::getVehicleType, param.getVehicleType())
                .in(CollUtil.isNotEmpty(param.getCarPlateList()),RegistrationRecord::getCarPlate,param.getCarPlateList())
                .orderBy(Boolean.TRUE,Boolean.FALSE, RegistrationRecord::getUpdateOn);
        registrationRecordService.page(page, wrapper);
    }

    private RegistrationRecordVO convert(RegistrationRecord record) {
        if(Objects.isNull(record)){
            return null;
        }
        RegistrationRecordVO vo = BeanUtil.copyProperties(record, RegistrationRecordVO.class);
        CodeUtil.searchCompanyNameAndRegionName(vo);
        return vo;
    }


    public RegistrationRecordVO save(RegistrationRecordSaveDTO data, Long userId) {
        RegistrationRecord record = BeanUtil.copyProperties(data, RegistrationRecord.class);
        CodeUtil.searchCompanyNameAndRegionName(record);
        if(Objects.nonNull(data.getVehicleType())){
            Optional.ofNullable(VehicleTypeEnum.getDescByCode(data.getVehicleType())).ifPresent(v ->
                    record.setVehicleTypeName(v));
        }
        record.setCreateBy(userId);
        record.setUpdateBy(userId);
        registrationRecordService.save(record);
        return BeanUtil.copyProperties(record, RegistrationRecordVO.class);
    }

    public RegistrationRecordVO modify(RegistrationRecordUpdateDTO data, Long userId) {
        RegistrationRecord record = BeanUtil.copyProperties(data, RegistrationRecord.class);
        CodeUtil.searchCompanyNameAndRegionName(record);
        if(Objects.nonNull(data.getVehicleType())){
            Optional.ofNullable(VehicleTypeEnum.getDescByCode(data.getVehicleType())).ifPresent(v ->
                    record.setVehicleTypeName(v));
        }
        record.setUpdateBy(userId);
        registrationRecordService.updateById(record);
        return BeanUtil.copyProperties(record, RegistrationRecordVO.class);
    }

    public Boolean remove(Long id, Long userId) {

        LambdaQueryWrapper<RegistrationRecord> wrapper = Wrappers.lambdaQuery(RegistrationRecord.class);
        RegistrationRecordManage context = (RegistrationRecordManage) AopContext.currentProxy();
        context.buildQuery(wrapper, id);
        RegistrationRecord record = registrationRecordService.getOne(wrapper);
        if (Objects.isNull(record)){
            throw new BizException("无法删除!");
        }

        registrationRecordService.removeById(id);
        return Boolean.TRUE;
    }
}
