package com.casic.missiles.service.Impl.customer;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.casic.missiles.config.message.ReminderNodeConfig;
import com.casic.missiles.core.base.service.IBaseExportService;
import com.casic.missiles.core.model.auth.AuthUser;
import com.casic.missiles.core.page.PageFactory;
import com.casic.missiles.core.shiro.ShiroKit;
import com.casic.missiles.dto.ReturnDTO;
import com.casic.missiles.dto.ReturnUtil;
import com.casic.missiles.dto.customer.sample.*;
import com.casic.missiles.dto.customer.MeasureRecordsResponse;
import com.casic.missiles.enums.BusinessExceptionEnum;
import com.casic.missiles.enums.ExportEnum;
import com.casic.missiles.enums.PrefixCodeEnum;
import com.casic.missiles.enums.sample.CertificationExpireStatusEnum;
import com.casic.missiles.exception.BusinessException;
import com.casic.missiles.mapper.business.BusinessOrderSampleRelationMapper;
import com.casic.missiles.mapper.customer.CustomerMapper;
import com.casic.missiles.mapper.customer.customize.CustomerSampleListResponseMapper;
import com.casic.missiles.mapper.customer.CustomerSampleMapper;
import com.casic.missiles.model.business.BusinessOrderSampleRelation;
import com.casic.missiles.model.customer.CustomerInfo;
import com.casic.missiles.model.customer.CustomerSampleInfo;
import com.casic.missiles.model.meter.MeterTraceSupplier;
import com.casic.missiles.service.customer.CustomerSampleService;
import com.casic.missiles.utils.DictCodeUtils;
import com.casic.missiles.utils.NumberGeneratorUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class CustomerSampleServiceImpl extends ServiceImpl<CustomerSampleMapper, CustomerSampleInfo> implements CustomerSampleService, CertificationExpireStatusEnum, PrefixCodeEnum {

    private final CustomerSampleListResponseMapper customerSampleListResponseMapper;

    private final ReminderNodeConfig reminderNodeConfig;
    private final CustomerMapper customerMapper;
    private final IBaseExportService iBaseExportService;
    private final BusinessOrderSampleRelationMapper sampleRelationMapper;

    @Override
    public Page<CustomerSampleListResponse> listPage(Page<CustomerSampleListResponse> page, CustomerSampleListRequest request) throws Exception {
        QueryWrapper<CustomerSampleListResponse> wrapper = listParamWrapper(request);
        Page<CustomerSampleListResponse> customerSamplePage = customerSampleListResponseMapper.selectPage(page, wrapper);
        customerSamplePage.getRecords()
                .forEach(customerSample -> {
                    BusinessOrderSampleRelation businessOrderSampleRelation = this.getSampleStatusById(customerSample.getId());
                    customerSample.setCertificationStatus(calculateCertificationStatus(customerSample.getValidDeadline()));
                    if (!ObjectUtils.isEmpty(businessOrderSampleRelation)) {
                        customerSample.setOrderId(businessOrderSampleRelation.getOrderId());
                        customerSample.setSampleStatus(businessOrderSampleRelation.getSampleStatus());
                    }
                });
        for (CustomerSampleListResponse customerSampleListResponse : customerSamplePage.getRecords()) {
            if (!StringUtils.isEmpty(customerSampleListResponse.getSampleStatus())) {
                DictCodeUtils.convertDictCodeToName(customerSampleListResponse);
            }
        }
        return customerSamplePage;
    }

    /**
     * 新增样品表，同时新增样品委托书关联状态表
     */
    @Override
    @Transactional
    public ReturnDTO addSample(CustomerSampleInfo customerSampleInfo) throws Exception {
        DictCodeUtils.validDictCode(customerSampleInfo);
        initSample(customerSampleInfo);
        int addFlag = this.baseMapper.insert(customerSampleInfo);
        if (addFlag > 0) {
            return ReturnUtil.success();
        }
        throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
    }

    @Override
    @Transactional
    public ReturnDTO addSampleList(List<CustomerSampleInfo> list) throws Exception {
        //用于存储验证后的错误信息
        Long maxNo = this.baseMapper.selectMaxSampleNo();
        for (CustomerSampleInfo item : list) {
            Set<ConstraintViolation<CustomerSampleInfo>> validate = Validation.buildDefaultValidatorFactory().getValidator().validate(item);
            if (!CollectionUtils.isEmpty(validate)) {
                return ReturnUtil.failed(validate.iterator().next().getMessage());
            }
            DictCodeUtils.validDictCode(item);
            //生成编号
            String sampleNo = NumberGeneratorUtil.getContactNo(SAMPLE_PREFIX, maxNo);
            item.setSampleNo(sampleNo);
            maxNo++;
        }
        super.saveBatch(list);
        return ReturnUtil.success();
    }

    /**
     * 更新样品表，同时更新样品委托书关联状态表
     */
    @Override
    @Transactional
    public ReturnDTO updateSample(CustomerSampleInfo customerSampleInfo) {
        AuthUser authUser = ShiroKit.getUser();
        customerSampleInfo.setUpdateUser(authUser.getId());
        initSample(customerSampleInfo);
        int updateFlag = this.baseMapper.updateById(customerSampleInfo);
        if (updateFlag > 0) {
            return ReturnUtil.success();
        }
        throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
    }

    @Override
    public CustomerSampleInfo sampleDetail(Long id) {
        CustomerSampleInfo customerSampleInfo = this.baseMapper.selectById(id);
        if (!ObjectUtils.isEmpty(customerSampleInfo)) {
            doPopulateCustomerSampleInfo(customerSampleInfo);
        }
        return customerSampleInfo;
    }

    /**
     * 只导出样品列表信息
     */
    @Override
    public void sampleExport(CustomerSampleListRequest request, HttpServletResponse response) {
        try {
            List<CustomerSampleListResponse> customerSampleList;
            List<BusinessOrderSampleRelation> businessOrderList = sampleRelationMapper.selectList(null);
            Map<Long, BusinessOrderSampleRelation> businessOrderMap = businessOrderList.stream()
                    .collect(Collectors.toMap(e -> e.getSampleId(), e -> e,
                            (value1, value2) -> value1));
            if (!CollectionUtils.isEmpty(request.getIds())) {
                customerSampleList = customerSampleListResponseMapper.selectBatchIds(request.getIds());
            } else {
                QueryWrapper<CustomerSampleListResponse> wrapper = listParamWrapper(request);
                customerSampleList = customerSampleListResponseMapper.selectList(wrapper);
            }
            customerSampleList.stream().filter(customerSample -> !ObjectUtils.isEmpty(customerSample.getOrderId()))
                    .forEach(
                            customerSample -> {
                                BusinessOrderSampleRelation businessOrderSampleRelation = businessOrderMap.get(customerSample.getId());
                                if (!ObjectUtils.isEmpty(businessOrderSampleRelation)) {
                                    customerSample.setOrderId(businessOrderSampleRelation.getOrderId());
                                    customerSample.setSampleStatus(businessOrderSampleRelation.getSampleStatus());
                                    customerSample.setCertificationStatus(calculateCertificationStatus(customerSample.getValidDeadline()));
                                }
                            }
                    );
            for (CustomerSampleListResponse customerSampleListResponse : customerSampleList) {
                DictCodeUtils.convertDictCodeToName(customerSampleListResponse);
            }
            iBaseExportService.exportExcel(response, CustomerSampleListResponse.class, customerSampleList, ExportEnum.SAMPLE_EXPORT.getSheetName());
        } catch (Exception e) {
            log.error("样品导出出现异常，异常信息为{}", e);
        }
    }

    @Override
    public ReturnDTO deleteSample(Long id) {
        int deleteFalg = this.baseMapper.deleteById(id);
        if (deleteFalg > 0) {
            return ReturnUtil.success();
        }
        throw new BusinessException(BusinessExceptionEnum.HANDLE_FAILED);
    }

    @Override
    public Page<MeasureRecordsResponse> measureRecordsById(CustomerSampleIdRequest customerSampleIdRequest) {
        Page<MeasureRecordsResponse> page = PageFactory.defaultPage();
        Page<MeasureRecordsResponse> measureRecordsResponsePage = this.baseMapper.measureRecordsById(page, customerSampleIdRequest);
        return measureRecordsResponsePage;
    }


    @Override
    public Page<CustomerSampleInfo> samplesByOderId(Page<CustomerSampleInfo> page, Long orderId, String sampleNo, String sampleName) {
        return this.baseMapper.samplesByOderId(page, orderId, sampleNo, sampleName);
    }

    @Override
    public  Page<MultiItemSampleListResponse> listPageByOrder(Page<MultiItemSampleListResponse> page, OrderSampleListRequest request)  throws Exception{
        page.setRecords(this.baseMapper.listPageByOrder(page, request));
        for (MultiItemSampleListResponse multiItemSampleResponse : page.getRecords()) {
            DictCodeUtils.convertDictCodeToName(multiItemSampleResponse);
        }
        return page;
    }

    @Override
    public Page<MultiItemSampleListResponse> listPageByInterchange(Page<MultiItemSampleListResponse> page, InterchangeSampleListRequest request)  throws Exception{
        page.setRecords(this.baseMapper.listPageByInterchange(page, request));
        for (MultiItemSampleListResponse multiItemSampleResponse : page.getRecords()) {
            DictCodeUtils.convertDictCodeToName(multiItemSampleResponse);
        }
        return page;
    }

    @Override
    public Page<MultiItemSampleListResponse> listPageBySubpackage(Page<MultiItemSampleListResponse> page, SubpackageSampleListRequest request)  throws Exception{
        page.setRecords(this.baseMapper.listPageBySubpackage(page, request));
        for (MultiItemSampleListResponse multiItemSampleResponse : page.getRecords()) {
            DictCodeUtils.convertDictCodeToName(multiItemSampleResponse);
        }
        return page;
    }

    @Override
    public Page<MultiItemSampleListResponse> listPageBySubpackageCertificate(Page<MultiItemSampleListResponse> page, InterchangeSampleListRequest request) throws Exception {
        page.setRecords(this.baseMapper.listPageBySubpackageCertificate(page, request));
        for (MultiItemSampleListResponse multiItemSampleResponse : page.getRecords()) {
            DictCodeUtils.convertDictCodeToName(multiItemSampleResponse);
        }
        return page;
    }

    private BusinessOrderSampleRelation getSampleStatusById(Long sampleId) {
        QueryWrapper<BusinessOrderSampleRelation> wrapper = new QueryWrapper<BusinessOrderSampleRelation>()
                .eq("sample_id", sampleId)
                .orderByDesc("create_time");
        List<BusinessOrderSampleRelation> orderSampleList = sampleRelationMapper.selectList(wrapper);
        Optional<BusinessOrderSampleRelation> orderSampleOptional = orderSampleList.stream().findFirst();
        return orderSampleOptional.isPresent() ? orderSampleOptional.get() : null;
    }

    /**
     * 初始化样品状态
     */
    private void initSample(CustomerSampleInfo customerSampleInfo) {
        Long maxNo = this.baseMapper.selectMaxSampleNo();
        String sampleNo = NumberGeneratorUtil.getContactNo(SAMPLE_PREFIX, maxNo);
        AuthUser authUser = ShiroKit.getUser();
        customerSampleInfo.setSampleNo(sampleNo);
        customerSampleInfo.setCreateUser(authUser.getId());
        customerSampleInfo.setSampleBelong("1");
        customerSampleInfo.setUpdateUser(authUser.getId());
    }

    private QueryWrapper<CustomerSampleListResponse> listParamWrapper(CustomerSampleListRequest request) {
        QueryWrapper<CustomerSampleListResponse> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(request.getSampleNo()), "sample_no", request.getSampleNo());
        queryWrapper.like(StringUtils.isNotBlank(request.getSampleName()), "sample_name", request.getSampleName());
        queryWrapper.like(StringUtils.isNotBlank(request.getSampleBelong()), "sample_belong", request.getSampleBelong());
        queryWrapper.like(StringUtils.isNotBlank(request.getSampleModel()), "sample_model", request.getSampleModel());
        queryWrapper.like(StringUtils.isNotBlank(request.getCustomerName()), "customer_name", request.getCustomerName());
        queryWrapper.like(StringUtils.isNotBlank(request.getCustomerNo()), "customer_no", request.getCustomerNo());
        if (!StringUtils.isEmpty(request.getOvertimeStatus())) {
            int expireTime=StringUtils.isEmpty(reminderNodeConfig.getSampleCertificate())?0:Integer.valueOf(reminderNodeConfig.getSampleCertificate());
            queryWrapper.apply("1".equals(request.getOvertimeStatus()),
                    "DATE_ADD(sysdate(),INTERVAL " + expireTime+ " DAY) > DATE_FORMAT(valid_deadline,'%Y-%m-%d')");
            queryWrapper.apply("0".equals(request.getOvertimeStatus()),
                    "DATE_ADD(sysdate(),INTERVAL " + expireTime + " DAY) <= DATE_FORMAT(valid_deadline,'%Y-%m-%d')");
        }
        queryWrapper.apply(StringUtils.isNotBlank(request.getStartTime()),
                "{0} <= DATE_FORMAT(measure_last_time,'%Y-%m-%d')", request.getStartTime());
        queryWrapper.apply(StringUtils.isNotBlank(request.getEndTime()),
                "{0} >= DATE_FORMAT(measure_last_time,'%Y-%m-%d')", request.getEndTime());
        queryWrapper.eq("is_del", 0);
        queryWrapper.orderByDesc("create_time");
        return queryWrapper;
    }

    /**
     * 通过证书到期时间进行到期状态的计算
     */
    private String calculateCertificationStatus(String validDeadline) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (StringUtils.isEmpty(validDeadline)) {
            return NORMAL;
        }
        if (validDeadline.compareTo(sdf.format(new Date())) < 0) {
            return ALREADY_EXPIRE;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(new Date());
        int expireTime=StringUtils.isEmpty(reminderNodeConfig.getSampleCertificate())?7:Integer.valueOf(reminderNodeConfig.getSampleCertificate());
        date.add(Calendar.DAY_OF_MONTH,expireTime);
        if (validDeadline.compareTo(sdf.format(date.getTime())) < 0) {
            return ALMOST_EXPIRE;
        }
        return NORMAL;
    }

    /**
     * 对样品列表的进行供应商联系方式的填充
     */
    private void doPopulateCustomerSampleInfo(CustomerSampleInfo customerSampleInfo) {
        CustomerInfo customerInfo = customerMapper.selectById(customerSampleInfo.getCustomerId());
        if (!ObjectUtils.isEmpty(customerInfo)) {
            customerSampleInfo.setPhone(customerInfo.getPhone());
            customerSampleInfo.setCustomerAddress(customerInfo.getAddressCountryName() + customerInfo.getAddressProvinceName() + customerInfo.getAddressCityName() + customerInfo.getFullAddress());
            customerSampleInfo.setPostalCode(customerInfo.getPostalCode());
        }
    }

}
