package com.ningdatech.carapi.industry.manage;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

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

import com.alibaba.excel.EasyExcel;
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.basic.util.NdDateUtils;
import com.ningdatech.carapi.common.aop.BuildChildrenRegionWrapper;
import com.ningdatech.carapi.common.constant.CommonConstant;
import com.ningdatech.carapi.common.constant.VehicleTypeEnum;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.common.util.ExcelDownUtil;
import com.ningdatech.carapi.common.util.ExcelExportStyle;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.datascope.contants.LambdaDataScopeTypeEnum;
import com.ningdatech.carapi.industry.entity.PassportInfo;
import com.ningdatech.carapi.industry.model.dto.PassportExportDTO;
import com.ningdatech.carapi.industry.model.dto.PassportPageParamDTO;
import com.ningdatech.carapi.industry.model.dto.PassportSaveDTO;
import com.ningdatech.carapi.industry.model.dto.PassportUpdateDTO;
import com.ningdatech.carapi.industry.model.vo.PassportVO;
import com.ningdatech.carapi.industry.service.IPassportInfoService;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;

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

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

    private final IPassportInfoService passportInfoService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final CompaniesCacheHelper companiesCacheHelper;

    public PageVo<PassportVO> infoList(PassportPageParamDTO param) {
        Page<PassportInfo> page = param.page();
        LambdaQueryWrapper<PassportInfo> wrapper = Wrappers.lambdaQuery(PassportInfo.class);
        PassportManage context = (PassportManage) AopContext.currentProxy();
        context.search(page,wrapper,param);
        if(CollUtil.isEmpty(page.getRecords())){
            return PageVo.of(Collections.emptyList(), page.getTotal());
        }
        List<PassportVO> data = page.getRecords().stream().map(w -> convert(w)).collect(Collectors.toList());
        return PageVo.of(data, page.getTotal());
    }

    public PassportVO details(Long id) {

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

        return convert(record);
    }

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

    /**
     * 查询
     * @param page
     * @param param
     */
    @LambdaDataScope(wrapperIndex = 1)
    @BuildChildrenRegionWrapper(wrapperIndex = 1,entityIndex = 2)
    public void search(Page<PassportInfo> page,LambdaQueryWrapper<PassportInfo> wrapper,PassportPageParamDTO param) {
        wrapper.like(StringUtils.isNotBlank(param.getCompanyName()), PassportInfo::getCompanyName, param.getCompanyName())
                .like(StringUtils.isNotBlank(param.getCarPlate()), PassportInfo::getCarPlate, param.getCarPlate())
                .eq(Objects.nonNull(param.getVehicleType()), PassportInfo::getVehicleType, param.getVehicleType())
                .ge(Objects.nonNull(param.getStartTime()), PassportInfo::getExpirationDate, param.getStartTime())
                .le(Objects.nonNull(param.getEndTime()), PassportInfo::getExpirationDate, param.getEndTime())
                .orderBy(Boolean.TRUE,Boolean.FALSE, PassportInfo::getUpdateOn);
        passportInfoService.page(page, wrapper);
    }

    private PassportVO convert(PassportInfo passport) {
        if(Objects.isNull(passport)){
            return null;
        }
        PassportVO vo = BeanUtil.copyProperties(passport, PassportVO.class);
        CodeUtil.searchCompanyNameAndRegionName(vo);
        return vo;
    }


    public PassportVO save(PassportSaveDTO passportSave, Long userId) {
        PassportInfo passportInfo = BeanUtil.copyProperties(passportSave, PassportInfo.class);
        CodeUtil.searchCompanyNameAndRegionName(passportInfo);
        if(Objects.nonNull(passportSave.getVehicleType())){
            Optional.ofNullable(VehicleTypeEnum.getDescByCode(passportSave.getVehicleType())).ifPresent(v ->
                    passportInfo.setVehicleTypeName(v));

        }
        passportInfo.setCreateBy(userId);
        passportInfo.setUpdateBy(userId);
        passportInfoService.save(passportInfo);
        return BeanUtil.copyProperties(passportInfo, PassportVO.class);
    }

    public PassportVO modify(PassportUpdateDTO passportUpdate, Long userId) {
        PassportInfo passportInfo = BeanUtil.copyProperties(passportUpdate, PassportInfo.class);
        CodeUtil.searchCompanyNameAndRegionName(passportInfo);
        if(Objects.nonNull(passportUpdate.getVehicleType())){
            Optional.ofNullable(VehicleTypeEnum.getDescByCode(passportUpdate.getVehicleType())).ifPresent(v ->
                    passportInfo.setVehicleTypeName(v));
        }
        passportInfo.setUpdateBy(userId);
        passportInfoService.updateById(passportInfo);
        return BeanUtil.copyProperties(passportInfo, PassportVO.class);
    }

    public Boolean remove(Long id, Long userId) {
        LambdaQueryWrapper<PassportInfo> wrapper = Wrappers.lambdaQuery(PassportInfo.class);
        PassportManage context = (PassportManage) AopContext.currentProxy();
        context.buildQuery(wrapper, id);
        PassportInfo record = passportInfoService.getOne(wrapper);
        if (Objects.isNull(record)){
            throw new BizException("无法删除!");
        }
        passportInfoService.removeById(id);
        return Boolean.TRUE;
    }

    public void infoListExport(HttpServletResponse response, PassportPageParamDTO param) {
        param.page(CommonConstant.EXPORT_PAGE_NUMBER, CommonConstant.EXPORT_PAGE_SIZE);
        PageVo<PassportVO> page = infoList(param);
        List<PassportExportDTO> collect = page.getRecords().stream().map(r -> {
            PassportExportDTO exportDTO = new PassportExportDTO();
            BeanUtils.copyProperties(r, exportDTO);
            String expirationDateStr = NdDateUtils.format(r.getExpirationDate(), NdDateUtils.DEFAULT_DATE_TIME_FORMAT);
            exportDTO.setExpirationDate(expirationDateStr);
            return exportDTO;
        }).collect(Collectors.toList());
        String fileName = "通行证证书列表";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), PassportExportDTO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
