package com.cool.store.service.closeup.impl;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.constants.CommonConstants;
import com.cool.store.context.CurrentUserHolder;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.dao.*;
import com.cool.store.dao.closeup.CloseUpApplyFormDAO;
import com.cool.store.dao.closeup.CloseUpAuditRecordDAO;
import com.cool.store.dao.closeup.CloseUpPlatformDAO;
import com.cool.store.dto.store.StoreMasterIssueDTO;
import com.cool.store.entity.*;
import com.cool.store.entity.closeup.CloseUpApplyFormDO;
import com.cool.store.entity.closeup.CloseUpAuditRecordDO;
import com.cool.store.entity.closeup.CloseUpPlatformDO;
import com.cool.store.enums.*;
import com.cool.store.enums.close.CloseStoreAuditStatusEnum;
import com.cool.store.enums.closeup.CloseUpStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mq.producer.SimpleMessageService;
import com.cool.store.request.closeup.*;
import com.cool.store.response.AuditInfoResponse;
import com.cool.store.service.UserAuthMappingService;
import com.cool.store.service.closeup.CloseUpService;
import com.cool.store.service.closeup.PlatformAutoStrategy;
import com.cool.store.service.sms.AliyunSmsService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.closeup.CloseUpApplyFormSimpleVO;
import com.cool.store.vo.closeup.CloseUpApplyFormVO;
import com.cool.store.vo.closeup.CloseUpPlatformVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

import static com.cool.store.service.close.impl.CloseStoreServiceImpl.getAuditInfoType;
import static com.cool.store.utils.GenerateNoUtil.generateMillsNoWithRandom;

/**
 * <p>
 * 歇业管理 服务实现类
 * </p>
 *
 * @author wangff
 * @since 2026/4/8
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CloseUpServiceImpl implements CloseUpService {
    private final CloseUpApplyFormDAO applyFormDAO;
    private final CloseUpAuditRecordDAO auditRecordDAO;
    private final CloseUpPlatformDAO platformDAO;
    private final UserAuthMappingService userAuthMappingService;
    private final RegionDao regionDao;
    private final StoreDao storeDao;
    private final SimpleMessageService simpleMessageService;
    private final PlatformAutoFactory platformAutoFactory;
    private final EnterpriseUserRoleDao enterpriseUserRoleDao;
    private final LineInfoDAO lineInfoDAO;
    private final EnterpriseUserDAO enterpriseUserDAO;
    private final AliyunSmsService aliyunSmsService;

    @Value("${mybatis.configuration.variables.enterpriseId}")
    private String enterpriseId;

    @Override
    @Transactional
    public Boolean closeUpApply(CloseUpApplyRequest request) {
        // 查询当前当前门店 校验门店状态
        StoreDO store = storeDao.getByStoreId(request.getStoreId());
        if (store == null){
            throw new ServiceException(ErrorCodeEnum.STORE_NOT_EXIST);
        }
        if (DateUtil.betweenDay(request.getPlanCloseDate(), request.getPlanOpenDate(), true) >= 7
                && StringUtils.isBlank(request.getUrls())) {
            throw new ServiceException(ErrorCodeEnum.ERROR_MESSAGE, "歇业时间大于7天，歇业检查清单不能为空");
        }
        // 校验是否存在时间交集的申请单（非审批拒绝状态）
        if (applyFormDAO.existsTimeOverlap(request.getStoreId(), request.getPlanCloseDate(), request.getPlanOpenDate())) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_EXIST_ONGOING_RECORD);
        }
        PartnerUserInfoVO user = PartnerUserHolder.getUser();
        CloseUpApplyFormDO formDO = BeanUtil.toBean(request, CloseUpApplyFormDO.class);
        formDO.setType(0);
        formDO.setApplyNo(generateMillsNoWithRandom());
        formDO.setStatus(CloseUpStatusEnum.APPROVAL.getStatus());
        formDO.setLineId(user.getLineId());
        applyFormDAO.insertOrUpdate(formDO);
        RegionDO regionDO = regionDao.getRegionByStoreId(request.getStoreId());
        if (Objects.isNull(regionDO)) {
            throw new ServiceException(ErrorCodeEnum.REGION_NOT_EXIST);
        }
        // 运营顾问审批
        List<String> auditUserIds = getAuditUserIds(regionDO.getId(), UserRoleEnum.SUPERVISION);
        auditRecordDAO.addRecord(formDO.getId(), formDO.getType(), String.valueOf(user.getLineId()), user.getUsername(), auditUserIds);
        return true;
    }

    @Override
    @Transactional
    public Boolean openApply(CloseUpOpenApplyRequest request) {
        CloseUpApplyFormDO sourceFormDO = applyFormDAO.getById(request.getSourceApplyId());
        if (Objects.isNull(sourceFormDO)) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_FORM_NOT_EXIST);
        }
        StoreDO store = storeDao.getByStoreId(sourceFormDO.getStoreId());
        if (store == null){
            throw new ServiceException(ErrorCodeEnum.STORE_NOT_EXIST);
        }
        if (CloseUpStatusEnum.unPass(sourceFormDO.getStatus())) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_CLOSED_AUDIT_NOT_PASS);
        }
        if (applyFormDAO.existOpenApply(request.getSourceApplyId())) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_EXIST_OPEN_APPLY);
        }
        CloseUpApplyFormDO openFormDO = CloseUpApplyFormDO.builder()
                .type(1)
                .applyNo(generateMillsNoWithRandom())
                .storeId(sourceFormDO.getStoreId())
                .lineId(sourceFormDO.getLineId())
                .status(CloseUpStatusEnum.APPROVAL.getStatus())
                .planCloseDate(sourceFormDO.getPlanCloseDate())
                .actualCloseDate(sourceFormDO.getActualCloseDate())
                .planOpenDate(sourceFormDO.getPlanOpenDate())
                .actualOpenDate(request.getActualOpenDate())
                .reason(request.getReason())
                .sourceApplyId(request.getSourceApplyId())
                .build();
        applyFormDAO.insertOrUpdate(openFormDO);
        // 修改源歇业申请单状态
        CloseUpApplyFormDO updateSourceForm = CloseUpApplyFormDO.builder()
                .id(sourceFormDO.getId())
                .status(CloseUpStatusEnum.APPLY_OPEN.getStatus())
                .build();
        applyFormDAO.updateByPrimaryKeySelective(updateSourceForm);
        PartnerUserInfoVO user = PartnerUserHolder.getUser();
        RegionDO regionDO = regionDao.getRegionByStoreId(sourceFormDO.getStoreId());
        if (Objects.isNull(regionDO)) {
            throw new ServiceException(ErrorCodeEnum.REGION_NOT_EXIST);
        }
        // 运营顾问审批
        List<String> auditUserIds = getAuditUserIds(regionDO.getId(), UserRoleEnum.SUPERVISION);
        auditRecordDAO.addRecord(openFormDO.getId(), openFormDO.getType(), String.valueOf(user.getLineId()), user.getUsername(), auditUserIds);
        return true;
    }

    @Override
    @Transactional
    public Boolean auditPass(CloseUpAuditRequest request) {
        CloseUpAuditRecordDO auditRecord = auditRecordDAO.getById(request.getAuditRecordId());
        if (Objects.isNull(auditRecord)) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_AUDIT_RECORD_NOT_EXIST);
        }
        CloseUpApplyFormDO formDO = applyFormDAO.getById(auditRecord.getApplyId());
        if (Objects.isNull(formDO)) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_FORM_NOT_EXIST);
        }
        if (!CloseUpStatusEnum.APPROVAL.getStatus().equals(formDO.getStatus())) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_APPROVED);
        }
        // 校验审批权限并修改审批单状态
        verifyAuthAndUpdateAuditStatus(auditRecord, CloseStoreAuditStatusEnum.PASS.getStatus(), request.getRemark());
        // 更新申请单状态
        Date actualCloseDate = Objects.nonNull(request.getActualCloseDate()) ? request.getActualCloseDate() : formDO.getPlanCloseDate();
        formDO.setActualCloseDate(actualCloseDate);
        CloseUpApplyFormDO updateFormDO = CloseUpApplyFormDO.builder()
                .id(formDO.getId())
                .status(CloseUpStatusEnum.PASS.getStatus())
                .actualCloseDate(formDO.getType().equals(0) ? actualCloseDate : null)
                .build();
        applyFormDAO.updateByPrimaryKeySelective(updateFormDO);
        if (formDO.getType().equals(0)) {
            closeExecute(formDO);
        } else if (formDO.getType().equals(1)) {
            openExecute(formDO);
        }
        return true;
    }

    private void openExecute(CloseUpApplyFormDO formDO) {
        // 根据营业时间判断直接修改主数据还是定时任务修改主数据
        if (formDO.getActualOpenDate().after(new Date())) {
            // 发送延时任务
            log.info("发送延时任务");
            simpleMessageService.send(String.valueOf(formDO.getId()), RocketMqTagEnum.CLOSE_UP_APPLY_STORE_UPDATE, formDO.getPlanOpenDate().getTime());
        } else {
            log.info("直接变更");
            storeStatusAndPlatformUpdate(formDO.getStoreId(), formDO.getId(), formDO.getType(), formDO.getSourceApplyId(), false);
        }
        // 修改源歇业申请单
        CloseUpApplyFormDO updateSourceForm = CloseUpApplyFormDO.builder()
                .id(formDO.getSourceApplyId())
                .actualOpenDate(formDO.getActualOpenDate())
                .status(CloseUpStatusEnum.APPLY_OPEN_PASS.getStatus())
                .build();
        applyFormDAO.updateByPrimaryKeySelective(updateSourceForm);
        // 初始化各外卖团购平台账号
        List<CloseUpPlatformDO> platformList = platformDAO.init(formDO.getId(), formDO.getType(), formDO.getActualOpenDate());
        // 根据平台类型自动开启
        autoPlatform(formDO.getType(), platformList);
    }

    /**
     * 歇业执行操作
     */
    private void closeExecute(CloseUpApplyFormDO formDO) {
        Date now = new Date();
        // 过去的单据不处理
        if (Objects.nonNull(formDO.getActualOpenDate()) && formDO.getActualOpenDate().before(now)
                || Objects.isNull(formDO.getActualOpenDate()) && formDO.getPlanOpenDate().before(now)) {
            return;
        }
        // 根据实际闭店时间判断直接修改主数据还是定时任务修改主数据
        if (formDO.getActualCloseDate().after(now)) {
            // 发送延时任务
            log.info("发送延时任务");
            simpleMessageService.send(String.valueOf(formDO.getId()), RocketMqTagEnum.CLOSE_UP_APPLY_STORE_UPDATE, formDO.getActualCloseDate().getTime());
        } else {
            log.info("直接变更");
            storeStatusAndPlatformUpdate(formDO.getStoreId(), formDO.getId(), formDO.getType(), formDO.getSourceApplyId(), false);
        }
        // 初始化各外卖团购平台账号
        List<CloseUpPlatformDO> platformList = platformDAO.init(formDO.getId(), formDO.getType(), formDO.getActualCloseDate());
        // 根据平台类型自动关闭
        autoPlatform(formDO.getType(), platformList);
    }

    @Override
    @Transactional
    public Boolean auditRejected(CloseUpAuditRequest request) {
        CloseUpAuditRecordDO auditRecord = auditRecordDAO.getById(request.getAuditRecordId());
        if (Objects.isNull(auditRecord)) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_AUDIT_RECORD_NOT_EXIST);
        }
        CloseUpApplyFormDO formDO = applyFormDAO.getById(auditRecord.getApplyId());
        if (Objects.isNull(formDO)) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_FORM_NOT_EXIST);
        }
        if (!CloseUpStatusEnum.APPROVAL.getStatus().equals(formDO.getStatus())) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_APPROVED);
        }
        // 校验审批权限并修改审批单状态
        verifyAuthAndUpdateAuditStatus(auditRecord, CloseStoreAuditStatusEnum.REJECTED.getStatus(), request.getRemark());
        // 修改申请单
        CloseUpApplyFormDO updateFormDO = CloseUpApplyFormDO.builder()
                .id(formDO.getId())
                .status(CloseUpStatusEnum.REJECTED.getStatus())
                .build();
        applyFormDAO.updateByPrimaryKeySelective(updateFormDO);
        // 营业申请修改源单据状态
        if (formDO.getType().equals(1)) {
            CloseUpApplyFormDO updateSourceFormDO = CloseUpApplyFormDO.builder()
                    .id(formDO.getSourceApplyId())
                    .status(CloseUpStatusEnum.APPLY_OPEN_REJECTED.getStatus())
                    .build();
            applyFormDAO.updateByPrimaryKeySelective(updateSourceFormDO);
        }
        return true;
    }

    @Override
    public PageInfo<CloseUpApplyFormSimpleVO> miniApplyFormList(CloseUpApplySimpleQueryRequest request) {
        PartnerUserInfoVO user = PartnerUserHolder.getUser();
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<CloseUpApplyFormDO> list = applyFormDAO.getList(user.getLineId(), 0, request.getStoreId());
        PageInfo<CloseUpApplyFormSimpleVO> page = BeanUtil.toPage(new PageInfo<>(list), CloseUpApplyFormSimpleVO.class);
        fillSimpleField(page.getList());
        return page;
    }

    @Override
    public CloseUpApplyFormVO getDetail(Long applyId) {
        CloseUpApplyFormDO formDO = applyFormDAO.getById(applyId);
        if (Objects.nonNull(formDO)) {
            CloseUpApplyFormVO vo = BeanUtil.toBean(formDO, CloseUpApplyFormVO.class);
            LineInfoDO lineInfo = lineInfoDAO.getLineInfo(formDO.getLineId());
            StoreDO storeDO = storeDao.getByStoreId(formDO.getStoreId());
            vo.setApplyName(lineInfo.getUsername());
            vo.setApplyMobile(lineInfo.getMobile());
            vo.setApplyRoleName("加盟商");
            vo.setStoreName(storeDO.getStoreName());
            vo.setStoreNum(storeDO.getStoreNum());
            vo.setJoinBrand(storeDO.getJoinBrand());
            // 查询审批记录
            if (CloseUpStatusEnum.REJECTED.getStatus().equals(formDO.getStatus())) {
                CloseUpAuditRecordDO auditRecord = auditRecordDAO.getLatestRecordByStatus(applyId, CloseStoreAuditStatusEnum.REJECTED.getStatus());
                if (Objects.nonNull(auditRecord)) {
                    vo.setRejectReason(auditRecord.getActionRemark());
                }
            } else if (CloseUpStatusEnum.APPLY_OPEN_REJECTED.getStatus().equals(formDO.getStatus())) {
                CloseUpApplyFormDO resumeForm = applyFormDAO.getBySourceApplyId(applyId);
                CloseUpAuditRecordDO auditRecord = auditRecordDAO.getLatestRecordByStatus(resumeForm.getId(), CloseStoreAuditStatusEnum.REJECTED.getStatus());
                if (Objects.nonNull(auditRecord)) {
                    vo.setRejectReason(auditRecord.getActionRemark());
                }
            } else {
                CloseUpAuditRecordDO auditRecord = auditRecordDAO.getOngoingRecordByApplyId(applyId);
                if (Objects.nonNull(auditRecord)) {
                    vo.setAuditId(auditRecord.getId());
                }
            }
            return vo;
        }
        return null;
    }

    @Override
    public PageInfo<CloseUpApplyFormSimpleVO> todoList(CloseUpTodoQueryRequest request) {
        LoginUserInfo user = CurrentUserHolder.getUser();
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<CloseUpAuditRecordDO> list = auditRecordDAO.getList(user.getUserId(), request.getType(), 0);
        PageInfo<CloseUpAuditRecordDO> page = new PageInfo<>(list);

        List<Long> applyIds = CollStreamUtil.toList(list, CloseUpAuditRecordDO::getApplyId);
        List<CloseUpApplyFormDO> forms = applyFormDAO.getByIds(applyIds);
        Map<Long, CloseUpApplyFormDO> formMap = CollStreamUtil.toMap(forms, CloseUpApplyFormDO::getId, v -> v);

        List<CloseUpApplyFormSimpleVO> resultList = CollStreamUtil.toList(list, v -> {
            CloseUpApplyFormDO formDO = formMap.get(v.getApplyId());
            CloseUpApplyFormSimpleVO vo = BeanUtil.toBean(formDO, CloseUpApplyFormSimpleVO.class);
            vo.setAuditId(v.getId());
            return vo;
        });
        fillSimpleField(resultList);
        return BeanUtil.toPage(page, resultList);
    }

    /**
     * 填充信息
     */
    private void fillSimpleField(List<CloseUpApplyFormSimpleVO> list) {
        Set<Long> lineIds = CollStreamUtil.toSet(list, CloseUpApplyFormSimpleVO::getLineId);
        Set<String> storeIds = CollStreamUtil.toSet(list, CloseUpApplyFormSimpleVO::getStoreId);
        List<LineInfoDO> lines = lineInfoDAO.getByLineIds(new ArrayList<>(lineIds));
        Map<Long, LineInfoDO> lineMap = CollStreamUtil.toMap(lines, LineInfoDO::getId, v -> v);
        Map<String, StoreDO> storeMap = storeDao.getStoreMapByStoreIds(new ArrayList<>(storeIds));
        Set<Long> sourceApplyIds = list.stream()
                .map(CloseUpApplyFormSimpleVO::getSourceApplyId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        List<CloseUpApplyFormDO> closeUpApplyList = applyFormDAO.getByIds(new ArrayList<>(sourceApplyIds));
        Map<Long, CloseUpApplyFormDO> sourceApplyMap = CollStreamUtil.toMap(closeUpApplyList, CloseUpApplyFormDO::getId, v -> v);

        for (CloseUpApplyFormSimpleVO vo : list) {
            LineInfoDO lineInfoDO = lineMap.get(vo.getLineId());
            if (Objects.nonNull(lineInfoDO)) {
                vo.setApplyMobile(lineInfoDO.getMobile());
                vo.setApplyName(lineInfoDO.getUsername());
                vo.setApplyRoleName("加盟商");
            }
            StoreDO storeDO = storeMap.get(vo.getStoreId());
            if (Objects.nonNull(storeDO)) {
                vo.setStoreName(storeDO.getStoreName());
                vo.setStoreNum(storeDO.getStoreNum());
                vo.setJoinBrand(storeDO.getJoinBrand());
            }
            CloseUpApplyFormDO sourceApplyForm = sourceApplyMap.get(vo.getSourceApplyId());
            if (Objects.nonNull(sourceApplyForm)) {
                vo.setCloseUpApplyNo(sourceApplyForm.getApplyNo());
            }
        }
    }

    @Override
    public PageInfo<CloseUpApplyFormSimpleVO> applyList(CloseUpQueryRequest request) {
        String userId = CurrentUserHolder.getUserId();
        Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(userId);
        if (!isAdmin) {
            List<UserAuthMappingDO> userAuthMappingDOS = userAuthMappingService.listUserAuthMappingByUserId(userId);
            if (CollectionUtils.isEmpty(userAuthMappingDOS)) {
                return new PageInfo<>();
            }
            request.setRegionIds(CollStreamUtil.toList(userAuthMappingDOS, UserAuthMappingDO::getMappingId));
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<CloseUpApplyFormDO> list = applyFormDAO.getList(request);
        PageInfo<CloseUpApplyFormSimpleVO> page = BeanUtil.toPage(new PageInfo<>(list), CloseUpApplyFormSimpleVO.class);
        fillSimpleField(page.getList());
        return page;
    }

    @Override
    public List<CloseUpPlatformVO> getPlatformListByApplyId(Long applyId) {
        List<CloseUpPlatformDO> list = platformDAO.getList(applyId, null, null);
        return BeanUtil.toList(list, CloseUpPlatformVO.class);
    }

    @Override
    public List<AuditInfoResponse> getAuditRecordList(Long applyId) {
        List<CloseUpAuditRecordDO> list = auditRecordDAO.getListByApplyId(applyId);
        Set<String> userIds = new HashSet<>();
        list.forEach(v -> {
            if (!CommonConstants.INDEX_ONE.equals(v.getRecordType())) {
                userIds.addAll(StringUtils.isNotBlank(v.getHandlerUserIds()) ? Arrays.asList(v.getHandlerUserIds().split(",")) : Collections.emptyList());
            }
        });
        Map<String, EnterpriseUserDO> userMap = enterpriseUserDAO.getUserMap(new ArrayList<>(userIds));
        List<AuditInfoResponse> result = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            CloseUpAuditRecordDO auditRecordDO = list.get(i);
            AuditInfoResponse auditInfo = AuditInfoResponse.builder()
                    .type(getAuditInfoType(auditRecordDO.getRecordType(), auditRecordDO.getAuditStatus()))
                    // 0加盟商发起 1运营顾问审批
                    .execute(CommonConstants.INDEX_ONE.equals(auditRecordDO.getRecordType()) ? 0 : 1)
                    .status(CommonConstants.INDEX_ZERO.equals(auditRecordDO.getAuditStatus()) ? 0 : 1)
                    .createTime(auditRecordDO.getCreateTime())
                    .remark(auditRecordDO.getActionRemark())
                    .actualUserId(auditRecordDO.getHandlerUserId())
                    .build();
            List<AuditInfoResponse.AuditUserInfoVO> auditUserList = Arrays.stream(auditRecordDO.getHandlerUserIds().split(","))
                    .filter(com.cool.store.utils.poi.StringUtils::isNotBlank)
                    .map(v -> {
                        String userName = null, avatar = null;
                        if (CommonConstants.INDEX_ZERO.equals(auditInfo.getExecute())) {
                            userName = auditRecordDO.getHandlerUserName();
                        } else {
                            EnterpriseUserDO user = userMap.get(v);
                            if (Objects.nonNull(user)) {
                                userName = user.getName();
                                avatar = user.getAvatar();
                            }
                        }
                        return new AuditInfoResponse.AuditUserInfoVO(v, userName, avatar);
                    })
                    .collect(Collectors.toList());
            auditInfo.setList(auditUserList);
            result.add(auditInfo);
        }
        return result;
    }

    @Override
    public PageInfo<CloseUpApplyFormSimpleVO> getPlatformTodoList(CloseUpTodoQueryRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<Long> applyIds = platformDAO.selectTodoApplyIds(request.getType(), request.getStoreKeyword());

        List<CloseUpApplyFormDO> list = applyFormDAO.getByIds(applyIds);
        List<CloseUpApplyFormSimpleVO> resultList = BeanUtil.toList(list, CloseUpApplyFormSimpleVO.class);
        PageInfo<CloseUpApplyFormSimpleVO> page = BeanUtil.toPage(new PageInfo<>(applyIds), resultList);
        fillSimpleField(page.getList());
        return page;
    }

    /**
     * 校验审批权限并修改审批单状态
     */
    private void verifyAuthAndUpdateAuditStatus(CloseUpAuditRecordDO auditRecord, Integer status, String remark) {
        if (!auditRecord.getAuditStatus().equals(0)) {
            throw new ServiceException(ErrorCodeEnum.CLOSE_UP_APPROVED);
        }
        LoginUserInfo user = CurrentUserHolder.getUser();
        Boolean isAdmin = enterpriseUserRoleDao.checkIsAdmin(user.getUserId());
        if (!isAdmin) {
            boolean match = Arrays.stream(auditRecord.getHandlerUserIds().split(","))
                    .filter(StringUtils::isNotBlank)
                    .anyMatch(v -> v.equals(user.getUserId()));
            if (!match) {
                throw new ServiceException(ErrorCodeEnum.CLOSE_UP_AUDIT_ACCESS_DENIED);
            }
        }
        // 更新审批单状态
        CloseUpAuditRecordDO updateAuditRecord = new CloseUpAuditRecordDO();
        updateAuditRecord.setId(auditRecord.getId());
        updateAuditRecord.setAuditStatus(status);
        updateAuditRecord.setHandlerUserId(user.getUserId());
        updateAuditRecord.setHandlerUserName(user.getName());
        updateAuditRecord.setActionRemark(remark);
        updateAuditRecord.setFinishTaskTime(new Date());
        auditRecordDAO.updateByPrimaryKeySelective(updateAuditRecord);
    }

    /**
     * 自动开启关闭各平台
     */
    private void autoPlatform(Integer applyType, List<CloseUpPlatformDO> list) {
        List<Long> updateIds = new ArrayList<>();
        for (CloseUpPlatformDO platformDO : list) {
            // 待处理且自动关闭
            if (platformDO.getStatus().equals(0) && platformDO.getType().equals(1) && (new Date()).after(platformDO.getTaskStartDate())) {
                PlatformAutoStrategy platformAuto = platformAutoFactory.getByCode(platformDO.getCode());
                if (Objects.isNull(platformAuto)) {
                    log.info("平台不存在实现类, code:{} name:{}", platformDO.getCode(), platformDO.getName());
                } else {
                    boolean update = false;
                    if (applyType.equals(0)) {
                        update = platformAuto.close();
                    } else if (applyType.equals(1)) {
                        update = platformAuto.open();
                    }
                    if (update) {
                        updateIds.add(platformDO.getId());
                    }
                }
            }
        }
        if (CollectionUtils.isNotEmpty(updateIds)) {
            platformDAO.updateStatusByIds(updateIds, 1);
        }
    }

    /**
     * 根据申请单修改主数据并处理各外卖团购平台开闭店
     */
    @Override
    public void storeStatusAndPlatformUpdate(Long formId) {
        CloseUpApplyFormDO formDO = applyFormDAO.getById(formId);
        if (Objects.nonNull(formDO)) {
            storeStatusAndPlatformUpdate(formDO.getStoreId(), formDO.getId(), formDO.getType(), formDO.getSourceApplyId(), true);
        }
    }

    @Override
    public Boolean handlePlatform(CloseUpPlatformHandleRequest request) {
        platformDAO.updateStatusByIds(Collections.singletonList(request.getId()), request.getStatus());
        return true;
    }

    /**
     * 修改主数据并处理各外卖团购平台开闭店
     */
    private void storeStatusAndPlatformUpdate(String storeId, Long applyId, Integer applyType, Long sourceApplyId, boolean autoPlatform) {
        StoreDO storeDO = storeDao.getByStoreId(storeId);
        if (Objects.isNull(storeDO)) {
            return;
        }
        // 主数据状态修改
        boolean storeUpdate = false;
        if (applyType.equals(0)) {
            if (StoreStatusEnum.OPEN.getValue().equals(storeDO.getStoreStatus())) {
                storeDao.closeUp(storeId, "close_up_special_reason");
                storeUpdate = true;
            } else {
                log.info("门店不处于在营状态，修改为暂停营业失败");
            }
        } else {
            if (StoreStatusEnum.CLOSE_UP.getValue().equals(storeDO.getStoreStatus())) {
                storeDao.closeUpToOpen(storeId);
                storeUpdate = true;
            } else {
                log.info("门店不处于暂停营业状态，修改为在营失败");
            }
            // 删除歇业申请的平台数据
            if (Objects.nonNull(sourceApplyId)) {
                platformDAO.deleteByApplyId(sourceApplyId);
            }
        }
        if (autoPlatform) {
            // 自动开关平台
            List<CloseUpPlatformDO> platformList = platformDAO.getList(applyId, 0, applyType);
            autoPlatform(applyType, platformList);
        }
        if (StringUtils.isNotBlank(storeDO.getTelephone())) {
            aliyunSmsService.sendNotice(storeDO.getTelephone(), applyType.equals(0) ? SmsNoticeTypeEnum.CLOSE_UP_CLOSE_NOTICE : SmsNoticeTypeEnum.CLOSE_UP_OPEN_NOTICE);
        }

        // 用mq通知主应用下发门店主数据
        if (storeUpdate) {
            try {
                StoreMasterIssueDTO storeMasterIssueDTO = new StoreMasterIssueDTO(enterpriseId, Collections.singletonList(storeId));
                simpleMessageService.send(JSONObject.toJSONString(storeMasterIssueDTO), RocketMqTagEnum.STORE_MASTER_ISSUE);
            } catch (Exception e) {
                log.error("mq通知主应用下发门店主数据失败");
            }
        }
    }

    /**
     * 获取拥有区域管辖权限的指定角色用户
     * @param regionId 区域id
     * @param userRoleEnum 角色枚举
     * @return 用户id列表
     */
    private List<String> getAuditUserIds(Long regionId, UserRoleEnum userRoleEnum) {
        List<EnterpriseUserDO> allUserByRoleEnumAndRegionId = userAuthMappingService.getAllUserByRoleEnumAndRegionId(userRoleEnum, regionId);
        return ListUtils.emptyIfNull(allUserByRoleEnumAndRegionId).stream().map(EnterpriseUserDO::getUserId).distinct().collect(Collectors.toList());
    }
}
