package com.ningdatech.carapi.industry.manage;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
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.CollUtils;
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.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.MortarEnterpriseFilingCertificate;
import com.ningdatech.carapi.industry.entity.MortarEnterpriseFilingCertificateChange;
import com.ningdatech.carapi.industry.enums.AddTypeEnum;
import com.ningdatech.carapi.industry.model.dto.MortarEnterpriseFilingCertificateDTO;
import com.ningdatech.carapi.industry.model.dto.MortarEnterpriseFilingCertificateExportDto;
import com.ningdatech.carapi.industry.model.req.LabWorkerCertificateAuditReq;
import com.ningdatech.carapi.industry.model.req.LabWorkerCertificateListReq;
import com.ningdatech.carapi.industry.model.vo.MortarEnterpriseFilingCertificateChangeVO;
import com.ningdatech.carapi.industry.model.vo.MortarEnterpriseFilingCertificateVO;
import com.ningdatech.carapi.industry.service.IMortarEnterpriseFilingCertificateChangeService;
import com.ningdatech.carapi.industry.service.IMortarEnterpriseFilingCertificateService;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;

/**
 * <p>
 * MortarCompanyFilingCertificateManage
 * </p>
 *
 * @author WendyYang
 * @since 21:16 2022/11/8
 */
@Component
@AllArgsConstructor
public class MortarEnterpriseFilingCertificateManage {

    private final IMortarEnterpriseFilingCertificateService mortarEnterpriseFilingCertificateService;

    private final RegionsCacheHelper regionsCacheHelper;
    private final CompaniesCacheHelper companiesCacheHelper;

    private final IMortarEnterpriseFilingCertificateChangeService mortarEnterpriseFilingCertificateChangeService;

    public PageVo<MortarEnterpriseFilingCertificateVO> mortarEnterpriseFilingCertificateList(LabWorkerCertificateListReq req) {
        LambdaQueryWrapper<MortarEnterpriseFilingCertificate> wrapper = Wrappers.lambdaQuery(MortarEnterpriseFilingCertificate.class);
        MortarEnterpriseFilingCertificateManage context = (MortarEnterpriseFilingCertificateManage) AopContext.currentProxy();
        context.buildQuery(wrapper,req);
        Page<MortarEnterpriseFilingCertificate> page = mortarEnterpriseFilingCertificateService.page(req.page(), wrapper);
        if (page.getTotal() == 0) {
            return PageVo.empty();
        }
        List<MortarEnterpriseFilingCertificateVO> result = page.getRecords().stream().map(w -> {
            MortarEnterpriseFilingCertificateVO vo = BeanUtil.copyProperties(w, MortarEnterpriseFilingCertificateVO.class);
            vo.setProductionCapacity(w.getThroughput());
            vo.setRegionName(regionsCacheHelper.getDisplayName(w.getRegionId()));
            vo.setValidDate(w.getValidDate());
            vo.setStandards(w.getStandards());
            CodeUtil.searchCompanyName(vo);
            return vo;
        }).collect(Collectors.toList());
        return PageVo.of(result, page.getTotal());
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildQuery(LambdaQueryWrapper<MortarEnterpriseFilingCertificate> wrapper,LabWorkerCertificateListReq req) {
        wrapper.ge(Objects.nonNull(req.getStartDate()), MortarEnterpriseFilingCertificate::getConferDate,req.getStartDate())
                .le(Objects.nonNull(req.getEndDate()),MortarEnterpriseFilingCertificate::getConferDate,req.getEndDate())
                .like(StringUtils.isNotBlank(req.getCompanyName()),MortarEnterpriseFilingCertificate::getCompanyName,req.getCompanyName())
                .orderByDesc(MortarEnterpriseFilingCertificate::getUpdateOn);
    }

    public void saveOrUpdate(MortarEnterpriseFilingCertificateDTO req) {
        Long userId = LoginUserUtil.getUserId();
        Integer addType = req.getAddType();
        // 说明是新增证书
        if (AddTypeEnum.NEW.getCode().equals(addType)) {
            MortarEnterpriseFilingCertificate mortarEnterpriseFilingCertificate = new MortarEnterpriseFilingCertificate();
            if (Objects.nonNull(req.getId())){
                // 说明为编辑
                mortarEnterpriseFilingCertificate.setId(req.getId());
            }
            mortarEnterpriseFilingCertificate.setRegionId(req.getRegionId());
            mortarEnterpriseFilingCertificate.setCompanyId(req.getCompanyId());
            mortarEnterpriseFilingCertificate.setCompanyName(req.getCompanyName());
            mortarEnterpriseFilingCertificate.setRecordItem(req.getRecordItem());
            mortarEnterpriseFilingCertificate.setCertificateNo(req.getCertificateNo());
            mortarEnterpriseFilingCertificate.setConferDate(req.getConferDate());
            mortarEnterpriseFilingCertificate.setThroughput(req.getProductionCapacity());
            mortarEnterpriseFilingCertificate.setStandards(req.getStandards());
            mortarEnterpriseFilingCertificate.setRemark(req.getRemark());
            mortarEnterpriseFilingCertificate.setConferOrg(req.getConferOrg());

            mortarEnterpriseFilingCertificate.setCreateOn(LocalDateTime.now());
            mortarEnterpriseFilingCertificate.setCreateBy(userId);
            mortarEnterpriseFilingCertificate.setUpdateOn(LocalDateTime.now());
            mortarEnterpriseFilingCertificate.setUpdateBy(userId);

            mortarEnterpriseFilingCertificateService.saveOrUpdate(mortarEnterpriseFilingCertificate);
        } else if (AddTypeEnum.REPLACE.getCode().equals(req.getAddType())) {
            // 说明为换证
            MortarEnterpriseFilingCertificateChange mortarEnterpriseFilingCertificateChange = new MortarEnterpriseFilingCertificateChange();
            if (Objects.nonNull(req.getId())){
                // 说明为编辑
                mortarEnterpriseFilingCertificateChange.setId(req.getId());
            }
            mortarEnterpriseFilingCertificateChange.setCompanyName(req.getCompanyName());
            mortarEnterpriseFilingCertificateChange.setRegionId(req.getRegionId());
            mortarEnterpriseFilingCertificateChange.setCompanyId(req.getCompanyId());
            mortarEnterpriseFilingCertificateChange.setCertificateNo(req.getCertificateNo());
            mortarEnterpriseFilingCertificateChange.setRecordItem(req.getRecordItem());
            mortarEnterpriseFilingCertificateChange.setReplacementTime(req.getReplaceDate());
            mortarEnterpriseFilingCertificateChange.setConferOrg(req.getConferOrg());
            mortarEnterpriseFilingCertificateChange.setRemark(req.getRemark());
            mortarEnterpriseFilingCertificateChange.setApplicationItem(req.getApplicationItem());
            mortarEnterpriseFilingCertificateChange.setApplicationReason(req.getApplicationReason());
            mortarEnterpriseFilingCertificateChange.setValidDate(req.getValidDate());
            mortarEnterpriseFilingCertificateChange.setStandards(req.getStandards());

            mortarEnterpriseFilingCertificateChange.setCreateOn(LocalDateTime.now());
            mortarEnterpriseFilingCertificateChange.setCreateBy(userId);
            mortarEnterpriseFilingCertificateChange.setUpdateOn(LocalDateTime.now());
            mortarEnterpriseFilingCertificateChange.setUpdateBy(userId);
            mortarEnterpriseFilingCertificateChangeService.saveOrUpdate(mortarEnterpriseFilingCertificateChange);
        }
    }

    public void mortarEnterpriseFilingCertificateExport(HttpServletResponse response, LabWorkerCertificateListReq req) {
        req.page(CommonConstant.EXPORT_PAGE_NUMBER, CommonConstant.EXPORT_PAGE_SIZE);
        PageVo<MortarEnterpriseFilingCertificateVO> page = mortarEnterpriseFilingCertificateList(req);
        List<MortarEnterpriseFilingCertificateExportDto> collect = page.getRecords().stream().map(w -> {
            MortarEnterpriseFilingCertificateExportDto exportDto = new MortarEnterpriseFilingCertificateExportDto();
            BeanUtils.copyProperties(w, exportDto);
            String conferDateStr = NdDateUtils.format(w.getConferDate(), NdDateUtils.DEFAULT_DATE_FORMAT);
            exportDto.setConferDate(conferDateStr);
            String validDateStr = NdDateUtils.format(w.getValidDate(), NdDateUtils.DEFAULT_DATE_FORMAT);
            exportDto.setValidDate(validDateStr);
            exportDto.setStandard(w.getStandards());
            return exportDto;
        }).collect(Collectors.toList());
        String fileName = "砂浆企业备案证列表";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), MortarEnterpriseFilingCertificateExportDto.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public PageVo<MortarEnterpriseFilingCertificateChangeVO> changeList(LabWorkerCertificateListReq req) {
        LambdaQueryWrapper<MortarEnterpriseFilingCertificateChange> wrapper = Wrappers.lambdaQuery(MortarEnterpriseFilingCertificateChange.class);
        MortarEnterpriseFilingCertificateManage context = (MortarEnterpriseFilingCertificateManage) AopContext.currentProxy();
        context.buildMortarEnterpriseFilingCertificateChangeListQuery(wrapper,req);
        Page<MortarEnterpriseFilingCertificateChange> page = mortarEnterpriseFilingCertificateChangeService.page(req.page(), wrapper);
        if (page.getTotal() == 0){
            return PageVo.empty();
        }
        List<MortarEnterpriseFilingCertificateChangeVO> data = CollUtils.convert(page.getRecords(), w -> {
            MortarEnterpriseFilingCertificateChangeVO resVo = BeanUtil.copyProperties(w, MortarEnterpriseFilingCertificateChangeVO.class);
            resVo.setRegionName(regionsCacheHelper.getDisplayName(w.getRegionId()));
            resVo.setReplaceDate(w.getReplacementTime());
            return resVo;
        });
        return PageVo.of(data,page.getTotal());
    }

    @LambdaDataScope
    @BuildChildrenRegionWrapper
    public void buildMortarEnterpriseFilingCertificateChangeListQuery(LambdaQueryWrapper<MortarEnterpriseFilingCertificateChange> wrapper, LabWorkerCertificateListReq req) {
        wrapper.like(StrUtil.isNotBlank(req.getCompanyName()), MortarEnterpriseFilingCertificateChange::getCompanyName, req.getCompanyName())
                .ge(Objects.nonNull(req.getStartDate()),MortarEnterpriseFilingCertificateChange::getReplacementTime,req.getStartDate())
                .le(Objects.nonNull(req.getEndDate()),MortarEnterpriseFilingCertificateChange::getReplacementTime,req.getEndDate())
                .orderByDesc(MortarEnterpriseFilingCertificateChange::getUpdateOn);
    }

    public Boolean audit(LabWorkerCertificateAuditReq req, Long userId) {
        return mortarEnterpriseFilingCertificateService.audit(req,userId);
    }

    public void delete(Long id) {
        LambdaQueryWrapper<MortarEnterpriseFilingCertificate> wrapper = Wrappers.lambdaQuery(MortarEnterpriseFilingCertificate.class);
        MortarEnterpriseFilingCertificateManage context = (MortarEnterpriseFilingCertificateManage) AopContext.currentProxy();
        context.buildMortarQuery(wrapper, id);
        MortarEnterpriseFilingCertificate record = mortarEnterpriseFilingCertificateService.getOne(wrapper);
        if (Objects.isNull(record)){
            throw new BizException("无法删除!");
        }
        mortarEnterpriseFilingCertificateService.removeById(id);
    }

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