package com.cool.store.service.impl;

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.dao.*;
import com.cool.store.dto.Preparation.PreparationDTO;
import com.cool.store.dto.openPreparation.OpenPlanShopInfoDTO;
import com.cool.store.dto.openPreparation.PlanLineDTO;
import com.cool.store.dto.openPreparation.UserNameDTO;
import com.cool.store.entity.*;
import com.cool.store.enums.AuditStatusEnum;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.UserRoleEnum;
import com.cool.store.enums.point.ShopSubStageEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.UserAuthMappingMapper;
import com.cool.store.request.OpeningOperationPlanRequest;
import com.cool.store.request.PlanListRequest;
import com.cool.store.service.*;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.vo.OpeningOperationPlanListVO;
import com.cool.store.vo.OpeningOperationPlanVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: WangShuo
 * @Date: 2024/04/22/下午3:15
 * @Version 1.0
 * @注释:
 */
@Service
@Slf4j
public class OpeningOperationPlanImpl implements OpeningOperationPlanService {

    @Resource
    private OpeningOperationPlanDAO openingOperationPlanDAO;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    private ShopStageInfoDAO shopStageInfoDAO;
    @Resource
    private PreparationService preparationService;
    @Resource
    private RegionService regionService;
    @Resource
    private ShopInfoDAO shopInfoDAO;
    @Resource
    private CoolStoreStartFlowService coolStoreStartFlowService;
    @Resource
    private LineInfoDAO lineInfoDAO;
    @Resource
    private ShopService shopService;

    @Resource
    UserAuthMappingService userAuthMappingService;
    @Resource
    SysRoleService sysRoleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long savePlan(OpeningOperationPlanRequest request, LoginUserInfo userInfo) {
        log.info("addNewPlan request:{}", JSONObject.toJSONString(request));
        if (request.getActivityTheme().length() > CommonConstants.MAX_LENGTH_ONE_HUNDRED) {
            log.error("addNewPlan ActivityTheme  length error");
            throw new ServiceException(ErrorCodeEnum.ACTIVITY_THEME_LENGTH_FALSE);
        }
        if (request.getSurveyResult().length() > CommonConstants.MAX_LENGTH_ONE_HUNDRED) {
            log.error("addNewPlan  SurveyResult length error");
            throw new ServiceException(ErrorCodeEnum.SURVEYRESULT_LENGTH_FALSE);
        }
        String userId = userInfo.getUserId();
        OpeningOperationPlanDO selectByShopId = openingOperationPlanDAO.selectByShopId(request.getShopId());
        Long planId;
        OpeningOperationPlanDO openingOperationPlanDO = request.toOpeningOperationPlanDO();
        openingOperationPlanDO.setResultType(AuditStatusEnum.TODO.getCode());
        if (!Objects.isNull(selectByShopId)) {
            //提交修改
            openingOperationPlanDO.setSubmissionTime(new Date());
            openingOperationPlanDO.setSubmittedUserId(userId);
            openingOperationPlanDO.setId(selectByShopId.getId());
            openingOperationPlanDO.setUpdateTime(new Date());
            openingOperationPlanDO.setUpdateUserId(userId);
            planId = openingOperationPlanDAO.updateSelective(openingOperationPlanDO);
        } else {
            //新增
            openingOperationPlanDO.setSubmissionTime(new Date());
            openingOperationPlanDO.setSubmittedUserId(userId);
            openingOperationPlanDO.setCreateTime(new Date());
            openingOperationPlanDO.setCreateUserId(userId);
            planId = openingOperationPlanDAO.insertSelective(openingOperationPlanDO);
        }
        shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_141);
        return planId;

    }

    @Override
    public OpeningOperationPlanVO getPlanByShopId(Long shopId) {
        log.info("getPlanBy shopId:{}", shopId);
        if (Objects.isNull(shopId)) {
            log.error(" getPlanByShopId shopId is null");
            throw new ServiceException(ErrorCodeEnum.SHOP_ID_IS_NULL);
        }
        OpeningOperationPlanVO openingOperationPlanVO = new OpeningOperationPlanVO();
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        OpeningOperationPlanDO openingOperationPlanDO = openingOperationPlanDAO.selectByShopId(shopId);
        EnterpriseUserDO userInfoById = enterpriseUserDAO.getUserInfoById(shopInfo.getSupervisorUserId());
        List<EnterpriseUserDO> allUserByRoleEnumAndRegionId = userAuthMappingService.getAllUserByRoleEnumAndRegionId(UserRoleEnum.OPERATIONS_MANAGER, shopInfo.getRegionId());
        List<String> collect = new ArrayList<>();
        if (CollectionUtils.isEmpty(allUserByRoleEnumAndRegionId)){
            collect = null;
        }else {
            collect = allUserByRoleEnumAndRegionId.stream()
                    .filter(user -> user.getName() != null)
                    .map(user -> user.getName())
                    .collect(Collectors.toList());
        }

        if (Objects.nonNull(openingOperationPlanDO)) {
            openingOperationPlanVO = new OpeningOperationPlanVO(openingOperationPlanDO);
            openingOperationPlanVO.setSubmiter(Objects.isNull(userInfoById) ? null : userInfoById.getName());
            openingOperationPlanVO.setApprover(CollectionUtils.isEmpty(collect) ? null : collect.stream().collect(Collectors.joining(",")));
            String preparationUserIds = openingOperationPlanDO.getPreparationUserIds();
            List<String> stream = Arrays.stream(preparationUserIds.split(CommonConstants.COMMA)).collect(Collectors.toList());
            List<UserNameDTO> nameByUserId = enterpriseUserDAO.getNameByUserId(stream);
            String userName = enterpriseUserDAO.getUserName(openingOperationPlanDO.getSubmittedUserId());
            openingOperationPlanVO.setSubmittedUserName(userName);
            openingOperationPlanVO.setPreparationUsers(nameByUserId);
            openingOperationPlanVO.setShopName(shopInfo.getShopName());
            return openingOperationPlanVO;
        }
        openingOperationPlanVO.setSubmiter(Objects.isNull(userInfoById) ? null : userInfoById.getName());
        openingOperationPlanVO.setApprover(CollectionUtils.isEmpty(collect) ? null : collect.stream().collect(Collectors.joining(",")));
        return openingOperationPlanVO;
    }

    @Override
    public PageInfo<OpeningOperationPlanListVO> getPlanListPage(PlanListRequest request) {
        log.info("getPlanListPage request:{}", JSONObject.toJSONString(request));
        if (!sysRoleService.checkIsAdmin(request.getCurUserId())) {
            request.setAuthRegionIds(userAuthMappingService.getAuthRegionIdAndSubRegionIdByUserId(request.getCurUserId()));
        }
        PageHelper.startPage(request.getPageNumber(), request.getPageSize());
        //不指定时间为3个月数据 去shop_info表查询店铺名字，店铺code，开店负责人id，督导id，区域id，open_plan,提交时间，审核状态
        List<OpenPlanShopInfoDTO> openPlanShopInfoDTOS = openingOperationPlanDAO.getOpenPlanShopListByCondition(request);
        //lineinfo 加盟商name，手机号，招商经理name,
        if (CollectionUtils.isEmpty(openPlanShopInfoDTOS)) {
            log.error("查询运营方案列表没有数据");
            return new PageInfo<>();
        }
        List<Long> lines = openPlanShopInfoDTOS.stream().filter(o -> o.getLineId() != null).map(OpenPlanShopInfoDTO::getLineId).collect(Collectors.toList());
        List<PlanLineDTO> lineInfos = lineInfoDAO.getLines(lines);
        List<Long> shopIds = openPlanShopInfoDTOS.stream().filter(o -> o.getShopId() != null).map(OpenPlanShopInfoDTO::getShopId).collect(Collectors.toList());
        Map<Long, PlanLineDTO> lineInfoMap = lineInfos.stream().collect(Collectors.toMap(PlanLineDTO::getLineId, dto -> dto));
        for (OpenPlanShopInfoDTO openPlanShopInfoDTO : openPlanShopInfoDTOS) {
            openPlanShopInfoDTO.setPartnerName(lineInfoMap.getOrDefault(openPlanShopInfoDTO.getLineId(), new PlanLineDTO()).getUsername());
            openPlanShopInfoDTO.setMobile(lineInfoMap.getOrDefault(openPlanShopInfoDTO.getLineId(), new PlanLineDTO()).getMobile());
            openPlanShopInfoDTO.setInvestmentManagerId(lineInfoMap.getOrDefault(openPlanShopInfoDTO.getLineId(), new PlanLineDTO()).getInvestmentManagerId());
        }
        PageInfo pageInfo = new PageInfo<>(openPlanShopInfoDTOS);
        //开店负责人id，督导id,招商经理id //
        Set<String> userIdset = openPlanShopInfoDTOS.stream()
                .filter(dto -> dto.getShopManagerUserId() != null)
                .map(OpenPlanShopInfoDTO::getShopManagerUserId)
                .collect(Collectors.toSet());
        userIdset.addAll(openPlanShopInfoDTOS.stream()
                .filter(dto -> dto.getSupervisorUserId() != null)
                .map(OpenPlanShopInfoDTO::getSupervisorUserId)
                .collect(Collectors.toSet()));
        userIdset.addAll(openPlanShopInfoDTOS.stream()
                .filter(dto -> dto.getInvestmentManagerId() != null)
                .map(OpenPlanShopInfoDTO::getInvestmentManagerId)
                .collect(Collectors.toSet()));
        List<String> userIdList = new ArrayList<>(userIdset);
        Map<String, String> vonameMap = enterpriseUserDAO.getUserNameMap(userIdList);
        log.info("getPlanListPage vonameMap:{}", JSONObject.toJSONString(vonameMap));
        //region
        List<Long> regionIds = openPlanShopInfoDTOS.stream()
                .filter(dto -> dto.getRegionId() != null).map(OpenPlanShopInfoDTO::getRegionId).collect(Collectors.toList());
        Map<Long, String> regionNameMap = regionService.getBelongWarRegionNameMap(regionIds);
        //阶段状态
        List<ShopStageInfoDO> subStageList = shopStageInfoDAO.getSubStageList(shopIds, ShopSubStageEnum.SHOP_STAGE_14.getShopSubStage());
        Map<Long, ShopStageInfoDO> subStageMap = subStageList.stream().collect(Collectors.toMap(ShopStageInfoDO::getShopId, dto -> dto));
        List<OpeningOperationPlanListVO> openingOperationPlanListVOList = new ArrayList<>();
        openPlanShopInfoDTOS.forEach(x -> {
            OpeningOperationPlanListVO openingOperationPlanListVO = new OpeningOperationPlanListVO();
            openingOperationPlanListVO.setShopId(x.getShopId());
            openingOperationPlanListVO.setShopName(x.getShopName());
            openingOperationPlanListVO.setStoreNum(x.getStoreNum());
            openingOperationPlanListVO.setStoreCode(x.getShopCode());
            openingOperationPlanListVO.setPartnerName(x.getPartnerName());
            openingOperationPlanListVO.setMobile(x.getMobile());
            openingOperationPlanListVO.setRegion(regionNameMap.get(x.getRegionId()));
            openingOperationPlanListVO.setInvestmentManagerName
                    (vonameMap.get(x.getInvestmentManagerId()));
            openingOperationPlanListVO.setShopManagerName
                    (vonameMap.get(x.getShopManagerUserId()));
            openingOperationPlanListVO.setSupervisorName(
                    vonameMap.get(x.getSupervisorUserId()));
            openingOperationPlanListVO.setSubmissionTime(x.getSubmissionTime());
            openingOperationPlanListVO.setResultType(x.getResultType());
            openingOperationPlanListVO.setSubStageStatus(subStageMap.getOrDefault(x.getShopId(),new ShopStageInfoDO()).getShopSubStageStatus());
            openingOperationPlanListVOList.add(openingOperationPlanListVO);
        });
        pageInfo.setList(openingOperationPlanListVOList);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean flush(Long shopId) {
        return Boolean.TRUE;

    }

    @Override
    public Boolean getStatus(Long shopId) {
        try {
            ShopInfoDO shopInfo = shopService.getShopInfo(shopId);
            String shopNum = shopInfo.getStoreNum();
            Boolean firstOrder = coolStoreStartFlowService.getFirstOrder(shopNum);
            return firstOrder;
        } catch (Exception e) {
            log.error("获取鲜丰订货金异常或更新状态失败");
            throw new ServiceException(ErrorCodeEnum.XFSG_SERVICE_ERROR);
        }

    }


}
