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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.workorder.PgAppraiseApplyBean;
import com.gree.mall.manager.bean.workorder.PgAppraiseApplyCountBean;
import com.gree.mall.manager.bean.workorder.PgAppraiseApplyVO;
import com.gree.mall.manager.bean.workorder.PgAppraiseCategoryVO;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.ExamineStatusEnum;
import com.gree.mall.manager.enums.workorder.*;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.utils.excel.ExcelUtils;
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 org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AppraiseRelaLogic {
    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final PgAppraiseConfigService pgAppraiseConfigService;
    private final PgAppraiseCategoryService pgAppraiseCategoryService;
    private final PgAppraiseApplyService pgAppraiseApplyService;
    private final PgAppraiseApplyItemService pgAppraiseApplyItemService;
    private final PgOrderBaseService pgOrderBaseService;
    private final OrderBaseLogic orderBaseLogic;

    public List<PgAppraiseConfig> configList() {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        return pgAppraiseConfigService.lambdaQuery()
                .eq(PgAppraiseConfig::getCompanyWechatId, adminUser.getCompanyWechatId())
                .list();
    }

    public void configSave(List<PgAppraiseConfig> config) {
        for (PgAppraiseConfig appraiseConfig : config) {
            appraiseConfig.updateById();
        }
    }

    public IPage<PgAppraiseCategoryVO> categoryList(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.supplyParam(zfireParamBean, PgAppraiseCategoryVO.class, adminUser);
        return commonMapper.appraiseCategoryList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
    }

    public PgAppraiseCategory categoryDetail(String id) {
        return pgAppraiseCategoryService.getById(id);
    }

    @Transactional
    public void categorySave(PgAppraiseCategory category) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        boolean isAdd = StringUtils.isBlank(category.getId());

        category.setCompanyWechatId(adminUser.getCompanyWechatId())
                .setCompanyWechatName(adminUser.getCompanyName());

        if (!isAdd) {
            final PgAppraiseCategory old = pgAppraiseCategoryService.getById(category.getId());
            category.setCompanyWechatId(old.getCompanyWechatId())
                    .setCompanyWechatName(old.getCompanyWechatName());
        }

        String preStr = "大类";
        if (StringUtils.isNotBlank(category.getParentId()) && !category.getParentId().equals("0")) {
            preStr = "小类";
        }

        if (StringUtils.isBlank(category.getName())) {
            throw new RemoteServiceException(preStr + "名称不能为空");
        }

        final Integer count = pgAppraiseCategoryService.lambdaQuery()
                .eq(PgAppraiseCategory::getCompanyWechatId, category.getCompanyWechatId())
                .eq(PgAppraiseCategory::getName, category.getName())
                .ne(!isAdd, PgAppraiseCategory::getId, category.getId())
                .count();
        if (count > 0) {
            throw new RemoteServiceException("名称重复存在");
        }

        if (isAdd) {
            category.insert();
        } else {
            category.updateById();
        }
    }

    @Transactional
    public void categoryDel(List<String> ids) {
        pgAppraiseCategoryService.lambdaUpdate()
                .in(PgAppraiseCategory::getId, ids)
                .remove();
        pgAppraiseCategoryService.lambdaUpdate()
                .in(PgAppraiseCategory::getParentId, ids)
                .remove();
    }

    @Transactional
    public void categoryImportData(MultipartFile file) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        String companyWechatId = adminUser.getAdminCompanyWechat().getCompanyWechatId();
        String companyName = adminUser.getAdminCompanyWechat().getCompanyName();

        List<Object> objects = ExcelUtils.importExcel(file);
        Map<String, Set<String>> importMap = new HashMap<>();

        for (int i = 0; i < objects.size(); i++) {
            List<Object> row = (List<Object>) objects.get(i);
            row = CommonUtils.initList2(row, 2);

            if (Objects.isNull(row.get(0))) {
                throw new RemoteServiceException("第" + (i + 1) + "行, 大类名称不能为空");
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("第" + (i + 1) + "行, 小类名称不能为空");
            }

            String parentName = (String) row.get(0);
            String subName = (String) row.get(1);

            if (importMap.containsKey(StrUtil.trim(parentName))) {
                importMap.get(StrUtil.trim(parentName)).add(StrUtil.trim(subName));
            } else {
                importMap.put(StrUtil.trim(parentName), new HashSet<String>() {{ this.add(StrUtil.trim(subName)); }});
            }
        }

        final List<PgAppraiseCategory> categoryList = pgAppraiseCategoryService.lambdaQuery()
                .eq(PgAppraiseCategory::getCompanyWechatId, companyWechatId)
                .eq(PgAppraiseCategory::getParentId, "0")
                .list();

        final Map<String, String> parentMap = categoryList.stream()
                .collect(Collectors.toMap(PgAppraiseCategory::getName, PgAppraiseCategory::getId));

        for (Map.Entry<String, Set<String>> entry : importMap.entrySet()) {
            if (!parentMap.containsKey(entry.getKey())) {
                continue;
            }
            final String parentId = parentMap.get(entry.getKey());
            for (String name : entry.getValue()) {
                PgAppraiseCategory category = new PgAppraiseCategory();
                category.setCompanyWechatId(companyWechatId)
                        .setCompanyWechatName(companyName)
                        .setParentId(parentId)
                        .setName(name);
                this.categorySave(category);
            }
        }
    }

    public IPage<PgAppraiseApplyVO> applyList(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.supplyParam(zfireParamBean, PgAppraiseApplyVO.class, adminUser);
        final IPage<PgAppraiseApplyVO> page = commonMapper.appraiseApplyList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            final PgAppraiseConfig config = pgAppraiseConfigService.lambdaQuery()
                    .eq(PgAppraiseConfig::getCompanyWechatId, page.getRecords().get(0).getCompanyWechatId())
                    .eq(PgAppraiseConfig::getType, AppraiseConfigTypeEnum.SECOND_A.getKey())
                    .one();
            for (PgAppraiseApplyVO record : page.getRecords()) {
                if (adminUser.getType() == 0) {
                    // 网点账户置空最高驳回人信息
                    record.setCloseBy(null);
                    record.setCloseTime(null);
                    record.setRejectBy(null);
                    record.setRejectTime(null);
                }
//                if (record.getIsSecond().getKey().equals(IsEnum.Y.getKey())
//                        && Objects.nonNull(record.getSecondCreateTime())
//                        && record.getStatus().getKey().equals(AppraiseApplyStatusEnum.WAIT.getKey())) {
//                    // 检查二次申诉是否显示按钮
//                    final int val = Integer.parseInt(config.getVal());
//                    DateTime endTime = DateUtil.offsetHour(record.getSecondCreateTime(), val);
//
//                    if (DateUtil.date().after(endTime)) {
//                        record.setShowSecondBtn("0");
//                    }
//                }
            }
        }

        return page;
    }


    public PgAppraiseApplyBean applyDetail(String id) {
        final PgAppraiseApply apply = pgAppraiseApplyService.getById(id);
        PgAppraiseApplyBean bean = new PgAppraiseApplyBean();
        BeanUtils.copyProperties(apply, bean);
        final List<PgAppraiseApplyItem> items = pgAppraiseApplyItemService.lambdaQuery()
                .eq(PgAppraiseApplyItem::getPgAppraiseApplyId, id)
                .list();
        bean.setItems(items);
        return bean;
    }

    @Transactional
    public void applySubmit(PgAppraiseApplyBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        boolean isAdd = StringUtils.isBlank(bean.getId());

        if (!isAdd) {
            // 有id查询是否有记录
            final PgAppraiseApply oldApply = pgAppraiseApplyService.getById(bean.getId());
            if (Objects.isNull(oldApply)) {
                // 没有记录置空新建
                bean.setId(null);
                isAdd = true;
            }
        }

        if (StringUtils.isBlank(bean.getOrderBaseId())) {
            throw new RemoteServiceException("工单编号不能为空");
        }
        if (StringUtils.isBlank(bean.getReason())) {
            throw new RemoteServiceException("申诉理由不能为空");
        }

        if (isAdd) {
            // 新增时判断是否已申诉过
            Integer count = pgAppraiseApplyService.lambdaQuery()
                    .eq(PgAppraiseApply::getIsSecond, false)
                    .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                    .count();
            if (count > 0) {
                throw new RemoteServiceException("已申诉, 提交失败");
            }
        }

        final PgOrderBase orderBase = pgOrderBaseService.getById(bean.getOrderBaseId());

        if (adminUser.getType() == 0 && !adminUser.getAdminWebsitIds().contains(orderBase.getWebsitId())) {
            throw new RemoteServiceException("填入的“工单编号”不存在");
        }

        if (!(orderBase.getOrderStatus().equals(OrderBaseStatusEnum.YWG.getKey())
                || orderBase.getOrderStatus().equals(OrderBaseStatusEnum.GCSZX.getKey())
                || orderBase.getOrderStatus().equals(OrderBaseStatusEnum.WDWG.getKey())
                || orderBase.getOrderStatus().equals(OrderBaseStatusEnum.YJS.getKey()))) {
            throw new RemoteServiceException("工单状态非“已完工”，不能提交申诉");
        }

//        if (orderBase.getAppraiseStatus().equals(AppraiseStatusEnum.A.getKey())
//                || orderBase.getAppraiseStatus().equals(AppraiseStatusEnum.D.getKey())) {
//            throw new RemoteServiceException("工单评价为“好评”，不需要申诉");
//        }

        final PgAppraiseApply beforeApply = pgAppraiseApplyService.lambdaQuery()
                .eq(PgAppraiseApply::getIsSecond, false)
                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                .orderByDesc(PgAppraiseApply::getCreateTime)
                .last("limit 1")
                .one();

        final Integer applyCount = pgAppraiseApplyService.lambdaQuery()
                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                .count();

        // 查询有没有驳回不可申诉人
        final Integer superEndCount = pgAppraiseApplyService.lambdaQuery()
                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                .isNotNull(PgAppraiseApply::getCloseTime)
                .count();

        if (superEndCount > 0) {
            throw new RemoteServiceException("不可再申诉");
        }

        // 查询有没有驳回可重诉人
        final Integer superCount = pgAppraiseApplyService.lambdaQuery()
                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                .isNotNull(PgAppraiseApply::getRejectTime)
                .count();

        // 有驳回可重诉人忽略申诉配置
        if (superCount == 0) {
            Date overTime = Objects.nonNull(orderBase.getOverTime()) ? orderBase.getOverTime() : orderBase.getWebsitOverTime();
            DateTime endTime;
            // 1、完工时间超过配置时间的，不可再提交；
            // 申诉配置
            final PgAppraiseConfig config = pgAppraiseConfigService.lambdaQuery()
                    .eq(PgAppraiseConfig::getCompanyWechatId, orderBase.getCompanyWechatId())
                    .eq(PgAppraiseConfig::getType, applyCount <= 1 ? AppraiseConfigTypeEnum.FIRST_A.getKey() : AppraiseConfigTypeEnum.SECOND_A.getKey())
                    .one();

            if (config.getType().equals(AppraiseConfigTypeEnum.SECOND_A.getKey())) {
                // 获取首次申诉审核时间
                overTime = beforeApply.getInfoConfirmTime();
            }

            final int val = Integer.parseInt(config.getVal());
            endTime = DateUtil.offsetHour(overTime, val);

            String str = applyCount <= 1 ? "首次" : "二次";
            if (DateUtil.date().after(endTime)) {
                throw new RemoteServiceException("已超" + str + "申诉时间, 提交失败");
            }
        }
        bean.setIsSecond(applyCount > 1);


        //2、该工单已有中差评申诉数据的，不可再提交；（已申诉、待审核状态的，均不可再创建申诉）
        Integer waitCount = pgAppraiseApplyService.lambdaQuery()
                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                .in(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.WAIT.getKey(), AppraiseApplyStatusEnum.WAIT_CENTER.getKey())
                .ne(!isAdd, PgAppraiseApply::getId, bean.getId())
                .count();
        if (waitCount > 0) {
            throw new RemoteServiceException("已有中差评申诉记录, 提交失败");
        }

//        waitCount = pgAppraiseApplyService.lambdaQuery()
//                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
//                .eq(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.OK.getKey())
//                .ne(!isAdd, PgAppraiseApply::getId, bean.getId())
//                .count();
//        if (waitCount > 0) {
//            throw new RemoteServiceException("已有中差评申诉“审核通过”记录, 提交失败");
//        }

        bean.setAppraiseStatus(orderBase.getAppraiseStatus());
        bean.setAppraiseSource(orderBase.getAppraiseSource());
        bean.setAddress(orderBase.getAddress());
        bean.setStatus(AppraiseApplyStatusEnum.WAIT_CENTER.getKey());
        bean.setApplyTime(DateUtil.date());
        bean.setApplyBy(adminUser.getNickName());
        bean.setCompanyWechatId(orderBase.getCompanyWechatId());
        bean.setCompanyWechatName(orderBase.getCompanyWechatName());
        bean.setOverTime(orderBase.getWebsitOverTime());

        if (Objects.isNull(bean.getOverTime())) {
            // 网点报完工时间为空取师傅报完工时间
            bean.setOverTime(orderBase.getOverTime());
        }
        if (isAdd) {
            bean.insert();
            orderBaseLogic.dow(orderBase.getId());
        } else {
            bean.updateById();
        }

        if (!isAdd) {
            // 非新增清空明细
            pgAppraiseApplyItemService.lambdaUpdate()
                    .eq(PgAppraiseApplyItem::getPgAppraiseApplyId, bean.getId())
                    .remove();
        }

        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            List<PgAppraiseApplyItem> itemList = bean.getItems().stream().peek(v -> v.setPgAppraiseApplyId(bean.getId())).collect(Collectors.toList());
            pgAppraiseApplyItemService.saveBatch(itemList);
        }
    }

    @Transactional
    public void applyConfirm(PgAppraiseApplyBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        PgAppraiseApply apply = pgAppraiseApplyService.getById(bean.getId());
        PgOrderBase orderBase = pgOrderBaseService.getById(apply.getOrderBaseId());

        if (!apply.getStatus().equals(AppraiseApplyStatusEnum.WAIT_CENTER.getKey())) {
            throw new RemoteServiceException("申诉状态已发生改变");
        }

        // 查询有没有驳回可重诉人
        final Integer superCount = pgAppraiseApplyService.lambdaQuery()
                .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                .isNotNull(PgAppraiseApply::getRejectTime)
                .count();

        if (superCount == 0) {
            // 首次审核时间不能超时, 二次审核时间不能超时，从网点提交首次申诉时间开始计算
            Date applyTime = apply.getApplyTime();
            final PgAppraiseConfig config = pgAppraiseConfigService.lambdaQuery()
                    .eq(PgAppraiseConfig::getCompanyWechatId, apply.getCompanyWechatId())
                    .eq(PgAppraiseConfig::getType, !apply.getIsSecond() ? AppraiseConfigTypeEnum.FIRST_C.getKey() : AppraiseConfigTypeEnum.SECOND_C.getKey())
                    .one();
            final int val = Integer.parseInt(config.getVal());
            Date endTime = DateUtil.offsetHour(applyTime, val);

            String str = !apply.getIsSecond() ? "首次" : "二次";
            if (DateUtil.date().after(endTime)) {
                throw new RemoteServiceException("已超" + str + "审核时间, 审核失败");
            }
        }

        if (StringUtils.isBlank(bean.getParentCategoryId())) {
            throw new RemoteServiceException("请选择问题大类");
        }
        if (StringUtils.isBlank(bean.getCategoryId())) {
            throw new RemoteServiceException("请选择问题小类");
        }
        if (StringUtils.isBlank(bean.getExamineRemark())) {
            throw new RemoteServiceException("请填写审核备注");
        }
        if (Objects.isNull(bean.getIsWebsitCall())) {
            throw new RemoteServiceException("请选择网点是否指引用户接听400回访电话");
        }
        if (Objects.isNull(bean.getWebsitResult())) {
            throw new RemoteServiceException("请选择判定网点");
        }
        if (Objects.isNull(bean.getWorkerResult())) {
            throw new RemoteServiceException("请选择判定服务人员");
        }

        final PgAppraiseCategory parentCategory = pgAppraiseCategoryService.getById(bean.getParentCategoryId());
        final PgAppraiseCategory category = pgAppraiseCategoryService.getById(bean.getCategoryId());

        apply.setParentCategoryId(bean.getParentCategoryId())
                .setParentCategoryName(parentCategory.getName())
                .setCategoryId(bean.getCategoryId())
                .setCategoryName(category.getName())
                .setExamineRemark(bean.getExamineRemark())
                .setExamineResult(bean.getExamineResult())
                .setIsWebsitCall(bean.getIsWebsitCall())
                .setWebsitResult(bean.getWebsitResult())
                .setWorkerResult(bean.getWorkerResult())
                .setInfoConfirmTime(apply.getIsSecond() ? null : DateUtil.date())
                .setSettleConfirmTime(apply.getIsSecond() ? DateUtil.date() : null)
                .setConfirmBy(adminUser.getNickName())
                .setStatus(ExamineStatusEnum.OK.getKey());


        if (apply.getWebsitResult().equals(AppraiseOnusEnum.NOT.getKey())) {
            // 首次申诉：判定网点【无责】的，则申诉成功，审核结果为【好评】，不触发二次可申诉
            // 二次申诉：判定网点【无责】的，则申诉成功，审核结果为【好评】
            apply.setExamineResult(AppraiseStatusEnum.A.getKey());
        } else if (apply.getWebsitResult().equals(AppraiseOnusEnum.HALF.getKey())) {
            // 首次申诉：判定网点为【半责】的，审核结果为【剔除】，不触发起二次可申诉
            // 二次申诉：判定网点【半责】的，审核结果为【剔除】
            apply.setExamineResult(AppraiseStatusEnum.T.getKey());
        } else if (apply.getWebsitResult().equals(AppraiseOnusEnum.ALL.getKey())) {
            // 首次申诉：判定网点【全责】的，审核结果为【驳回】，触发二次可申诉
            // 二次申诉：判定网点【全责】的，审核结果为【驳回】，维护原评价
            apply.setExamineResult(orderBase.getAppraiseStatus());
            final Integer supCount = pgAppraiseApplyService.lambdaQuery()
                    .eq(PgAppraiseApply::getIsSecond, false)
                    .eq(PgAppraiseApply::getOrderBaseId, bean.getOrderBaseId())
                    .isNotNull(PgAppraiseApply::getRejectTime)
                    .count();
            if (!apply.getIsSecond() && supCount == 0) {
                PgAppraiseApply copy = new PgAppraiseApply();
                this.copyApply(copy, apply);
                copy.setIsSecond(true);
                copy.setSecondCreateTime(DateUtil.dateSecond());
                copy.insert();
            }
        }

        apply.updateById();
        pgOrderBaseService.lambdaUpdate()
                .set(PgOrderBase::getAppraiseApplyResult, apply.getExamineResult())
                .eq(PgOrderBase::getId, orderBase.getId())
                .update();
    }

    public void applyReject(String id) {
        pgAppraiseApplyService.lambdaUpdate()
                .set(PgAppraiseApply::getApplyBy, null)
                .set(PgAppraiseApply::getApplyTime, null)
                .set(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.WAIT.getKey())
                .eq(PgAppraiseApply::getId, id)
                .eq(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.WAIT_CENTER.getKey())
                .update();
    }

    @Transactional
    public void batchUpdateReset(List<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new RemoteServiceException("请选择记录");
        }
        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<PgAppraiseApply> applyList = pgAppraiseApplyService.lambdaQuery()
                .in(PgAppraiseApply::getId, ids)
                .list();

        Integer count = pgAppraiseApplyService.lambdaQuery()
                .in(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.WAIT.getKey(), AppraiseApplyStatusEnum.WAIT_CENTER.getKey())
                .in(PgAppraiseApply::getId, ids)
                .count();

        if (count > 0) {
            throw new RemoteServiceException("有“待申诉”或“待中心审核”申诉记录，不能操作“驳回可再申诉”");
        }

        count = pgAppraiseApplyService.lambdaQuery()
                .isNotNull(PgAppraiseApply::getCloseTime)
                .in(PgAppraiseApply::getId, ids)
                .count();

        if (count > 0) {
            throw new RemoteServiceException("有“驳回不可再申诉信息”申诉记录，不能操作“驳回可再申诉”");
        }

        final List<String> orderIds = applyList.stream().map(PgAppraiseApply::getOrderBaseId).distinct().collect(Collectors.toList());

        count = pgAppraiseApplyService.lambdaQuery()
                .isNotNull(PgAppraiseApply::getCloseTime)
                .in(PgAppraiseApply::getOrderBaseId, orderIds)
                .count();

        if (count > 0) {
            throw new RemoteServiceException("有“驳回不可再申诉信息”申诉记录，不能操作“驳回可再申诉”");
        }

        for (PgAppraiseApply apply : applyList) {
            if (Objects.nonNull(apply.getRejectTime())) {
                throw new RemoteServiceException(apply.getOrderBaseId() + "工单编号的申诉记录有“驳回可重申诉信息”，不能操作“驳回可再申诉”");
            }
            if (Objects.nonNull(apply.getCloseTime())) {
                throw new RemoteServiceException(apply.getOrderBaseId() + "工单编号的申诉记录有“驳回不可再申诉信息”，不能操作“驳回可再申诉”");
            }
            if (!(apply.getStatus().equals(AppraiseApplyStatusEnum.OK.getKey())
                    || apply.getStatus().equals(AppraiseApplyStatusEnum.OVER.getKey())
                    || apply.getStatus().equals(AppraiseApplyStatusEnum.OVER_APPLY.getKey()))) {
                throw new RemoteServiceException(apply.getOrderBaseId() + "工单编号的申诉记录非“审核通过”或“超时未审核”或“超时未申诉”，不能操作“驳回可再申诉”");
            }
        }

        final List<String> normIds = applyList.stream().map(PgAppraiseApply::getId).collect(Collectors.toList());

        pgAppraiseApplyService.lambdaUpdate()
                .set(PgAppraiseApply::getRejectBy, adminUser.getNickName())
                .set(PgAppraiseApply::getRejectTime, DateUtil.date())
                .in(PgAppraiseApply::getId, normIds)
                .update();

        List<PgAppraiseApply> copyList = pgAppraiseApplyService.lambdaQuery()
                .in(PgAppraiseApply::getId, ids)
                .list();
        List<PgAppraiseApply> newList = new ArrayList<>();
        for (PgAppraiseApply apply : copyList) {
            PgAppraiseApply copy = new PgAppraiseApply();
            this.copyApply(copy, apply);
            copy.setIsSecond(true);
            newList.add(copy);
        }

        pgAppraiseApplyService.saveBatch(newList);
        pgOrderBaseService.lambdaUpdate()
                .set(PgOrderBase::getAppraiseApplyResult, null)
                .eq(PgOrderBase::getId, applyList.stream()
                        .map(PgAppraiseApply::getOrderBaseId)
                        .distinct()
                        .collect(Collectors.toList()))
                .update();
    }

    private void copyApply(PgAppraiseApply copy, PgAppraiseApply apply) {
        copy.setOrderBaseId(apply.getOrderBaseId())
                .setOrderType(apply.getOrderType())
                .setOrderSmallType(apply.getOrderSmallType())
                .setOrderSmallTypeText(apply.getOrderSmallTypeText())
                .setCompanyWechatId(apply.getCompanyWechatId())
                .setCompanyWechatName(apply.getCompanyWechatName())
                .setStatus(AppraiseApplyStatusEnum.WAIT.getKey())
                .setWorkerId(apply.getWorkerId())
                .setWorkerNumber(apply.getWorkerNumber())
                .setWorkerName(apply.getWorkerName())
                .setWorkerMobile(apply.getWorkerMobile())
                .setWorkerIdcard(apply.getWorkerIdcard())
                .setWebsitId(apply.getWebsitId())
                .setWebsitName(apply.getWebsitName())
                .setOverTime(apply.getOverTime())
                .setAppraiseStatus(apply.getAppraiseStatus())
                .setAppraiseContent(apply.getAppraiseContent())
                .setAppraiseSource(apply.getAppraiseSource())
                .setReason(apply.getReason())
                .setUserName(apply.getUserName())
                .setUserMobile(apply.getUserMobile())
                .setAddress(apply.getAddress());
    }

    public void batchUpdateEnd(List<String> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new RemoteServiceException("请选择记录");
        }
        AdminUserCom adminUser = commonLogic.getAdminUser();

        final List<PgAppraiseApply> applyList = pgAppraiseApplyService.lambdaQuery()
                .in(PgAppraiseApply::getId, ids)
                .in(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.OK.getKey(), AppraiseApplyStatusEnum.OVER.getKey(), AppraiseApplyStatusEnum.OVER_APPLY.getKey())
                .orderByAsc(PgAppraiseApply::getApplyTime)
                .list();

        if (CollectionUtil.isEmpty(applyList)) {
            throw new RemoteServiceException("未找到申诉记录为“审核通过”或“超时未审核”或“超时未申诉”，不能操作“驳回不可再申诉”");
        }

        final List<String> orderIds = applyList.stream().map(PgAppraiseApply::getOrderBaseId).collect(Collectors.toList());
        final Map<String, PgAppraiseApply> applyMap = applyList.stream().collect(Collectors.toMap(PgAppraiseApply::getOrderBaseId, Function.identity(), (key1, key2) -> key2));
        for (PgAppraiseApply apply : applyList) {
            if (!(apply.getStatus().equals(AppraiseApplyStatusEnum.OK.getKey())
                    || apply.getStatus().equals(AppraiseApplyStatusEnum.OVER.getKey())
                    || apply.getStatus().equals(AppraiseApplyStatusEnum.OVER_APPLY.getKey()))) {
                throw new RemoteServiceException(apply.getOrderBaseId() + "工单编号的申诉记录非“审核通过”或“超时未审核”或“超时未申诉”，不能操作“驳回不可再申诉”");
            }
            apply.setExamineResult(apply.getAppraiseStatus());
        }
        pgAppraiseApplyService.saveOrUpdateBatch(applyList);

        for (String orderId : orderIds) {
            final PgAppraiseApply apply = applyMap.get(orderId);
            if (Objects.nonNull(apply)) {
                pgOrderBaseService.lambdaUpdate()
                        .set(PgOrderBase::getAppraiseApplyResult, apply.getAppraiseStatus())
                        .eq(PgOrderBase::getId, orderId)
                        .update();
            }
        }


        pgAppraiseApplyService.lambdaUpdate()
                .set(PgAppraiseApply::getCloseBy, adminUser.getNickName())
                .set(PgAppraiseApply::getCloseTime, DateUtil.date())
                .in(PgAppraiseApply::getId, ids)
                .eq(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.OK.getKey())
                .update();
    }


    public PgAppraiseApplyCountBean applyCount() {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        PgAppraiseApplyCountBean bean = new PgAppraiseApplyCountBean();

        final Integer count = pgAppraiseApplyService.lambdaQuery()
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), PgAppraiseApply::getWebsitId, adminUser.getAdminWebsitIds())
                .eq(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.WAIT.getKey())
                .count();
        final Integer centerCount = pgAppraiseApplyService.lambdaQuery()
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminWebsitIds()), PgAppraiseApply::getWebsitId, adminUser.getAdminWebsitIds())
                .eq(PgAppraiseApply::getStatus, AppraiseApplyStatusEnum.WAIT_CENTER.getKey())
                .count();
        bean.setWaitCount(count);
        bean.setCenterCount(centerCount);
        return bean;
    }
}
