package com.gree.mall.manager.logic.quality;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.quality.QualityFeedbackBean;
import com.gree.mall.manager.bean.quality.QualityFeedbackCountBean;
import com.gree.mall.manager.bean.quality.QualityFeedbackVO;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.base.BaseEnum;
import com.gree.mall.manager.enums.quality.ExamineQualityFeedbackStatusEnum;
import com.gree.mall.manager.enums.quality.QualityFeedbackTypeEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.QualityFeedback;
import com.gree.mall.manager.plus.entity.QualityFeedbackItem;
import com.gree.mall.manager.plus.service.AdminWebsitService;
import com.gree.mall.manager.plus.service.QualityFeedbackItemService;
import com.gree.mall.manager.plus.service.QualityFeedbackService;
import com.gree.mall.manager.utils.CompressDownUtil;
import com.gree.mall.manager.utils.oss.OSSUtil;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class QualityFeedbackLogic {

    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final QualityFeedbackService qualityFeedbackService;
    private final QualityFeedbackItemService qualityFeedbackItemService;
    private final AdminWebsitService adminWebsitService;
    private final OSSUtil ossUtil;

    private static final String DOWN_PATH = "classpath:tmp/quality/";

    private final String FILE_SUFFIX = ".zip";

    public IPage<QualityFeedbackVO> list(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.supplyParam(zfireParamBean, QualityFeedbackVO.class, adminUser);

        return commonMapper.qualityFeedbackPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
    }

    public QualityFeedbackBean detail(String id) {
        QualityFeedbackBean bean = new QualityFeedbackBean();
        QualityFeedback qualityFeedback = qualityFeedbackService.getById(id);
        BeanUtils.copyProperties(qualityFeedback, bean);

        final List<QualityFeedbackItem> items = qualityFeedbackItemService.lambdaQuery()
                .eq(QualityFeedbackItem::getQualityFeedbckId, id)
                .list();
        bean.setItems(items);

        return bean;
    }

    public QualityFeedbackCountBean count() {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        QualityFeedbackCountBean bean = new QualityFeedbackCountBean();
        Integer saveCount = qualityFeedbackService.lambdaQuery()
                .eq(QualityFeedback::getStatus, ExamineQualityFeedbackStatusEnum.SAVE.getKey())
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), QualityFeedback::getWebsitId, adminUser.getAdminWebsitIds())
                .count();
        Integer waitCount = qualityFeedbackService.lambdaQuery()
                .eq(QualityFeedback::getStatus, ExamineQualityFeedbackStatusEnum.WAIT.getKey())
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), QualityFeedback::getWebsitId, adminUser.getAdminWebsitIds())
                .count();
        Integer rejectCount = qualityFeedbackService.lambdaQuery()
                .eq(QualityFeedback::getStatus, ExamineQualityFeedbackStatusEnum.REJECT.getKey())
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), QualityFeedback::getWebsitId, adminUser.getAdminWebsitIds())
                .count();
        bean.setSaveCount(saveCount);
        bean.setWaitCount(waitCount);
        bean.setRejectCount(rejectCount);
        return bean;
    }

    public void add(QualityFeedbackBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        this.checkRequireParams(bean);
        bean.setCompanyWechatId(adminUser.getCompanyWechatId());
        bean.setCompanyWechatName(adminUser.getCompanyName());
        bean.setStatus(ExamineQualityFeedbackStatusEnum.SAVE.getKey());
        bean.setIsUpload(false);
        bean.insert();
        for (QualityFeedbackItem item : bean.getItems()) {
            item.setQualityFeedbckId(bean.getId());
        }
        qualityFeedbackItemService.saveBatch(bean.getItems());
    }

    private void checkRequireParams(QualityFeedbackBean bean) {
        if (StringUtils.isBlank(bean.getWebsitId()) || StringUtils.isBlank(bean.getWebsitName())) {
            throw new RemoteServiceException("反馈网点不能为空");
        }
        if (StringUtils.isBlank(bean.getTitle())) {
            throw new RemoteServiceException("反馈主题不能为空");
        }
        if (StringUtils.isBlank(bean.getOrderNo())) {
            throw new RemoteServiceException("云售后4.0工单号不能为空");
        }
        if (StringUtils.isBlank(bean.getWorkerName())) {
            throw new RemoteServiceException("工程师名称不能为空");
        }
        if (StringUtils.isBlank(bean.getWorkerMobie())) {
            throw new RemoteServiceException("工程师电话不能为空");
        }
        if (StringUtils.isBlank(bean.getCustomerName())) {
            throw new RemoteServiceException("客户名称不能为空");
        }
        if (StringUtils.isBlank(bean.getCustomerMobile())) {
            throw new RemoteServiceException("客户电话不能为空");
        }
        if (StringUtils.isBlank(bean.getProvince())) {
            throw new RemoteServiceException("省份不能为空");
        }
        if (StringUtils.isBlank(bean.getCity())) {
            throw new RemoteServiceException("城市不能为空");
        }
        if (StringUtils.isBlank(bean.getArea())) {
            throw new RemoteServiceException("县区不能为空");
        }
        if (StringUtils.isBlank(bean.getStreet())) {
            throw new RemoteServiceException("街道不能为空");
        }
        if (StringUtils.isBlank(bean.getAddress())) {
            throw new RemoteServiceException("详细地址不能为空");
        }
        bean.setJoinAddress(bean.getProvince() + bean.getCity() + bean.getArea() + bean.getStreet() + bean.getAddress());
        if (StringUtils.isBlank(bean.getMainId()) || StringUtils.isBlank(bean.getMainName())) {
            throw new RemoteServiceException("产品大类不能为空");
        }
        if (StringUtils.isBlank(bean.getSmallId()) || StringUtils.isBlank(bean.getSmallName())) {
            throw new RemoteServiceException("产品小类不能为空");
        }
        if (StringUtils.isBlank(bean.getSeriesName())) {
            throw new RemoteServiceException("系列名称不能为空");
        }
        if (StringUtils.isBlank(bean.getInsideProductName())) {
            throw new RemoteServiceException("内机型号不能为空");
        }
        if (StringUtils.isBlank(bean.getInsideCode())) {
            throw new RemoteServiceException("内机条码不能为空");
        }
        Integer count = qualityFeedbackService.lambdaQuery()
                .eq(QualityFeedback::getInsideCode, bean.getInsideCode())
                .ne(StringUtils.isNotBlank(bean.getId()), QualityFeedback::getId, bean.getId())
                .count();
        if (count > 0) {
            throw new RemoteServiceException("内机条码在系统里已存在");
        }
        if ("空调,空气能热水器".contains(bean.getMainName()) && StringUtils.isBlank(bean.getOutCode())) {
            throw new RemoteServiceException("外机条码不能为空");
        }
        if ("空调,空气能热水器".contains(bean.getMainName()) && StringUtils.isBlank(bean.getOutProductName())) {
            throw new RemoteServiceException("外机型号不能为空");
        }
        if (StringUtils.isNotBlank(bean.getOutCode())) {
            count = qualityFeedbackService.lambdaQuery()
                    .eq(QualityFeedback::getOutCode, bean.getOutCode())
                    .ne(StringUtils.isNotBlank(bean.getId()), QualityFeedback::getId, bean.getId())
                    .count();
            if (count > 0) {
                throw new RemoteServiceException("外机条码在系统里已存在");
            }
        }
        if (Objects.isNull(bean.getNum())) {
            throw new RemoteServiceException("发生数量不能为空");
        }
        if (Objects.isNull(bean.getUseDate())) {
            throw new RemoteServiceException("安装或使用日期不能为空");
        }
        if (Objects.isNull(bean.getRepairDate())) {
            throw new RemoteServiceException("报修或发生日期不能为空");
        }
        if (Objects.isNull(bean.getIsPartSend())) {
            throw new RemoteServiceException("有无配件寄回不能为空");
        }
        if (StringUtils.isBlank(bean.getBugPartCode())) {
            throw new RemoteServiceException("故障代码不能为空");
        }
        if (Objects.isNull(bean.getIsNeedPlan())) {
            throw new RemoteServiceException("是否需要处理方案不能为空");
        }
        if (Objects.isNull(bean.getSupplyDate())) {
            throw new RemoteServiceException("要求提供日期不能为空");
        }
        if (StringUtils.isBlank(bean.getBugRemark())) {
            throw new RemoteServiceException("故障描述不能为空");
        }
        if (StringUtils.isBlank(bean.getWebsitAnalyse())) {
            throw new RemoteServiceException("网点人析不能为空");
        }
        if (StringUtils.isBlank(bean.getWebsitHandleMethod())) {
            throw new RemoteServiceException("网点处理方法不能为空");
        }
        if (CollectionUtil.isEmpty(bean.getItems())) {
            throw new RemoteServiceException("明细不能为空");
        }
        final Map<String, QualityFeedbackItem> itemMap = bean.getItems().stream()
                .collect(Collectors.toMap(QualityFeedbackItem::getType, Function.identity(), (key1, key2) -> key2));
        if (!itemMap.containsKey(QualityFeedbackTypeEnum.INSIDE_CODE.getKey())) {
            throw new RemoteServiceException("上传图片内机条码图不能为空");
        }
        if ("空调,空气能热水器".contains(bean.getMainName())
                && !itemMap.containsKey(QualityFeedbackTypeEnum.INSIDE_CODE.getKey())) {
            throw new RemoteServiceException("上传图片外机条码图不能为空");
        }
    }

    public void update(QualityFeedbackBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        QualityFeedback old = qualityFeedbackService.getById(bean.getId());

        if (old.getStatus().equals(ExamineQualityFeedbackStatusEnum.WAIT.getKey())
                || old.getStatus().equals(ExamineQualityFeedbackStatusEnum.OK.getKey())
                || old.getStatus().equals(ExamineQualityFeedbackStatusEnum.FAIL.getKey())) {
            throw new RemoteServiceException("单据状态非“保存”或“驳回可修改”不能修改");
        }

        if (bean.getStatus().equals(ExamineQualityFeedbackStatusEnum.WAIT.getKey())) {
            bean.setSubmitBy(adminUser.getNickName())
                    .setSubmitTime(DateUtil.date());
        }
        bean.updateById();
        qualityFeedbackService.lambdaUpdate()
                .set(QualityFeedback::getConfirmBy, null)
                .set(QualityFeedback::getConfirmTime, null)
                .eq(QualityFeedback::getId, bean.getId())
                .update();
        qualityFeedbackItemService.lambdaUpdate()
                .eq(QualityFeedbackItem::getQualityFeedbckId, bean.getId())
                .remove();
        for (QualityFeedbackItem item : bean.getItems()) {
            item.setQualityFeedbckId(bean.getId());
        }
        qualityFeedbackItemService.saveBatch(bean.getItems());
    }

    public void confirm(String id, String remark, ExamineQualityFeedbackStatusEnum status) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (!adminUser.getType().equals(1)) {
            throw new RemoteServiceException("非中心账号，审核失败");
        }
        if (status.getKey().equals(ExamineQualityFeedbackStatusEnum.SAVE.getKey())
                || status.getKey().equals(ExamineQualityFeedbackStatusEnum.WAIT.getKey()) ) {
            throw new RemoteServiceException("审核异常");
        }
        qualityFeedbackService.lambdaUpdate()
                .set(QualityFeedback::getConfirmBy, adminUser.getNickName())
                .set(QualityFeedback::getConfirmTime, DateUtil.date())
                .set(QualityFeedback::getRemark, remark)
                .set(QualityFeedback::getStatus, status.getKey())
                .eq(QualityFeedback::getId, id)
                .eq(QualityFeedback::getStatus, ExamineQualityFeedbackStatusEnum.WAIT.getKey())
                .update();
    }

    public void updateUpload(List<String> ids) {
        qualityFeedbackService.lambdaUpdate()
                .set(QualityFeedback::getIsUpload, true)
                .in(QualityFeedback::getId, ids)
                .ne(QualityFeedback::getStatus, ExamineQualityFeedbackStatusEnum.SAVE.getKey())
                .update();
    }

    public void downZipFile(String id, HttpServletResponse response) throws Exception {
        QualityFeedback qualityFeedback = qualityFeedbackService.getById(id);

        List<QualityFeedbackItem> dataList = qualityFeedbackItemService.lambdaQuery()
                .eq(QualityFeedbackItem::getQualityFeedbckId, id)
                .list();
        List<Map<String, String>> list = new ArrayList<>();
        for (QualityFeedbackItem data : dataList) {
            String filePath = data.getUrl().substring(data.getUrl().lastIndexOf("key=") + 4);
            String suffix = data.getUrl().substring(data.getUrl().lastIndexOf("."));
            Map<String, String> map = new HashMap<>();
            map.put("path", filePath);
            map.put("fileName", BaseEnum.keyToValueOpt(QualityFeedbackTypeEnum.class, data.getType()).orElse(IdWorker.getIdStr()) + suffix);
            list.add(map);
        }
        String downloadName = qualityFeedback.getTitle() + FILE_SUFFIX;
        CompressDownUtil.setDownloadResponse(response, downloadName);
        CompressDownUtil.compressZipByName(list, response.getOutputStream(),ossUtil,commonLogic);
    }
}
