package com.cool.store.service.impl;

import cn.hutool.core.bean.BeanUtil;
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.entity.*;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.MessageEnum;
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.LineInfoMapper;
import com.cool.store.request.AssignSurveyorsRequest;
import com.cool.store.request.DecorationMeasureRequest;
import com.cool.store.request.SubmitMeasurementRequest;
import com.cool.store.response.MeasureResponse;
import com.cool.store.service.DecorationMeasureService;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.vo.DecorationMeasureVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@RequiredArgsConstructor
public class DecorationMeasureServiceImpl implements DecorationMeasureService {

    @Resource
    private DecorationDesignInfoDAO decorationDesignInfoDAO;
    @Resource
    private EnterpriseUserRoleDao enterpriseUserRoleDao;
    private final DecorationMeasureDAO decorationMeasureDAO;
    private final EnterpriseUserDAO enterpriseUserDAO;
    private final RedisUtilPool redisUtilPool;
    private final ShopStageInfoDAO shopStageInfoDAO;
    private final ShopInfoDAO shopInfoDAO;
    private final CommonService commonService;
    @Resource
    private LineInfoMapper lineInfoMapper;

    @Override
    public DecorationMeasureVO getDecorationMeasureByShopId(Long shopId) {
        DecorationMeasureDO measureDO = decorationMeasureDAO.getByShopId(shopId);
        if (measureDO == null) {
            return new DecorationMeasureVO();
        }

        DecorationMeasureVO measureVO = BeanUtil.toBean(measureDO, DecorationMeasureVO.class);

        // 收集需要查询的用户ID
        Set<String> userIds = new HashSet<>();
        Optional.ofNullable(measureVO.getMeasureUserId()).ifPresent(userIds::add);
        Optional.ofNullable(measureVO.getDesignUserId()).ifPresent(userIds::add);

        // 只有当有用户ID需要查询时才进行查询
        if (!userIds.isEmpty()) {
            Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIds));
            measureVO.setMeasureUserName(userNameMap.getOrDefault(measureVO.getMeasureUserId(), null));
            measureVO.setDesignUserName(userNameMap.getOrDefault(measureVO.getDesignUserId(), null));
        }

        return measureVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitDecorationMeasure(DecorationMeasureRequest request) {
        // 重复提交校验（3秒内不能重复提交）
        String lockKey = "submitDecorationMeasure:" + request.getShopId();
        String lockValue = UUID.randomUUID().toString();
        boolean acquired = redisUtilPool.setNxExpire(lockKey, lockValue, CommonConstants.THREE * CommonConstants.ONE_SECONDS);
        if (!acquired) {
            throw new ServiceException(ErrorCodeEnum.DUPLICATE_SUBMISSION);
        }
        ShopStageInfoDO subStage = shopStageInfoDAO.getShopSubStageInfo(request.getShopId(), ShopSubStageEnum.SHOP_STAGE_8_6);
        // 获取当前登录用户
        LoginUserInfo user = CurrentUserHolder.getUser();
        DecorationMeasureDO saveDO = request.buildDecorationMeasureDO();
        DecorationMeasureDO measureDO = decorationMeasureDAO.getByShopId(request.getShopId());
        if (Objects.nonNull(measureDO)) {
            // 更新已有数据
            BeanUtil.copyProperties(saveDO, measureDO, "id");
            measureDO.setSubmitTime(new Date());
            decorationMeasureDAO.updateByPrimaryKeySelective(measureDO, user.getUserId());
            Integer currentStatus = subStage.getShopSubStageStatus();

            // 处理状态861->862
            if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_861.getShopSubStageStatus().equals(currentStatus)) {
                shopStageInfoDAO.batchUpdateShopStageStatus(request.getShopId(), Arrays.asList(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_862, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_90));
                // 给测量员发送企业微信消息
                sendMeasureUserMessage(request.getShopId(), request.getMeasureUserId());
                //企微通知设计组长
                sendHeadDesign(request);
                return Boolean.TRUE;
            }
            // 处理状态862->863
            if (ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_862.getShopSubStageStatus().equals(currentStatus)) {
                shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_863);
                return Boolean.TRUE;
            }
        } else {
            decorationMeasureDAO.insertSelective(saveDO, user.getUserId());
            // 更新设计状态和测量状态
            shopStageInfoDAO.batchUpdateShopStageStatus(request.getShopId(),
                    Arrays.asList(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_862, ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_90));
            //通知测量员
            sendMeasureUserMessage(request.getShopId(), request.getMeasureUserId());
            //企微通知设计组长
            sendHeadDesign(request);
        }
        return Boolean.TRUE;
    }

    private void sendHeadDesign(DecorationMeasureRequest request) {
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(request.getShopId());
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfo.getLineId());
        HashMap<String, String> map = new HashMap<>(4);
        map.put("partnerUsername", lineInfo.getUsername());
        map.put("partnerMobile", lineInfo.getMobile());
        map.put("storeName", shopInfo.getShopName());
        commonService.sendQWMessage(Collections.singletonList(request.getDesignUserId()),
                MessageEnum.MESSAGE_58,
                map
        );
    }

    /**
     * 发送测量消息给测量员
     */
    private void sendMeasureUserMessage(Long shopId, String userId) {
        // 获取商店信息
        ShopInfoDO shopInfo = shopInfoDAO.getShopInfo(shopId);
        LineInfoDO lineInfo = lineInfoMapper.getByLineId(shopInfo.getLineId());
        if (shopInfo == null) {
            throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
        }
        HashMap<String, String> map = new HashMap<>(4);
        map.put("partnerUsername", lineInfo.getUsername());
        map.put("partnerMobile", lineInfo.getMobile());
        map.put("storeName", shopInfo.getShopName());
        commonService.sendQWMessage(
                Collections.singletonList(userId),
                MessageEnum.MESSAGE_56,
                map
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDecorationMeasure(DecorationMeasureRequest request) {
        // 参数校验
        if (request == null || request.getShopId() == null) {
            throw new ServiceException(ErrorCodeEnum.PARAMS_REQUIRED);
        }
        // 获取当前登录用户
        LoginUserInfo user = CurrentUserHolder.getUser();
        DecorationMeasureDO saveDO = request.buildDecorationMeasureDO();
        DecorationMeasureDO measureDO = decorationMeasureDAO.getByShopId(request.getShopId());

        if (Objects.nonNull(measureDO)) {
            // 更新已有数据
            BeanUtil.copyProperties(saveDO, measureDO, "id");
            decorationMeasureDAO.updateByPrimaryKeySelective(measureDO, user.getUserId());
        } else {
            // 插入新数据
            decorationMeasureDAO.insertSelective(saveDO, user.getUserId());
        }

        return Boolean.TRUE;
    }

    @Override
    public Boolean assignSurveyors(AssignSurveyorsRequest request) {

        ShopInfoDO shopInfoDO = shopInfoDAO.getShopInfo(request.getShopId());
        if (shopInfoDO == null){
            throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
        }
        if (StringUtils.isEmpty(shopInfoDO.getHqtShopId())){
            throw new ServiceException(ErrorCodeEnum.HQT_SHOP_ID_NOT_EXIST);
        }
        ShopStageInfoDO shopStageInfo = shopStageInfoDAO.getShopSubStageInfo(shopInfoDO.getId(), ShopSubStageEnum.SHOP_STAGE_8_6);
        if (shopStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_00.getShopSubStageStatus())) {
            throw new ServiceException(ErrorCodeEnum.SHOP_STAGE_NOT_OPERATE);
        }
        DecorationMeasureDO measureDAOByShopId = decorationMeasureDAO.getByShopId(shopInfoDO.getId());
        if (measureDAOByShopId == null) {
            measureDAOByShopId = new DecorationMeasureDO();
            measureDAOByShopId.setDeleted(false);
            measureDAOByShopId.setShopId(shopInfoDO.getId());
            measureDAOByShopId.setCreateTime(new Date());
        }
        measureDAOByShopId.setShopId(shopInfoDO.getId());
        measureDAOByShopId.setMeasurementSheetId(request.getMeasurementSheetId());
        measureDAOByShopId.setMeasureUserName(request.getMeasureUserName());
        measureDAOByShopId.setDesignLeaderName(request.getDesignLeaderName());
        measureDAOByShopId.setUpdateTime(new Date());
        if (measureDAOByShopId.getId() == null) {
            decorationMeasureDAO.insertSelective(measureDAOByShopId);
            shopStageInfoDAO.updateShopStageInfo(shopInfoDO.getId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_862);
        } else {
            decorationMeasureDAO.updateByPrimaryKeySelective(measureDAOByShopId);
        }
        DecorationDesignInfoDO designInfoDO = decorationDesignInfoDAO.getByShopId(shopInfoDO.getId());
        if (designInfoDO == null) {
            designInfoDO = new DecorationDesignInfoDO();
            designInfoDO.setShopId(shopInfoDO.getId());
            designInfoDO.setCreateTime(new Date());
        }
        designInfoDO.setDesignLeaderName(request.getDesignLeaderName());
        designInfoDO.setDesignSubmitTime(new Date());
        designInfoDO.setUpdateTime(new Date());
        if (designInfoDO.getId() == null) {
            decorationDesignInfoDAO.insertSelective(designInfoDO);
            shopStageInfoDAO.updateShopStageInfo(shopInfoDO.getId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_90);
        } else {
            decorationDesignInfoDAO.updateByPrimaryKeySelective(designInfoDO);
        }
        return true;
    }

    @Override
    public Boolean submitMeasurementDiagram(SubmitMeasurementRequest request) {

        ShopInfoDO shopInfoDO = shopInfoDAO.getShopInfo(request.getShopId());
        if (shopInfoDO == null){
            throw new ServiceException(ErrorCodeEnum.SHOP_NOT_EXIST);
        }
        if (StringUtils.isEmpty(shopInfoDO.getHqtShopId())){
            throw new ServiceException(ErrorCodeEnum.HQT_SHOP_ID_NOT_EXIST);
        }
        DecorationMeasureDO measureDAOByShopId = decorationMeasureDAO.getByShopId(shopInfoDO.getId());
        if (measureDAOByShopId == null) {
            throw new ServiceException(ErrorCodeEnum.SHOP_STAGE_NOT_OPERATE);
        }
        measureDAOByShopId.setMeasureDate(request.getMeasureDate());
        measureDAOByShopId.setDiagramDate(request.getDiagramDate());
        measureDAOByShopId.setMeasureUrl(String.join(",", request.getMeasureUrl()));
        decorationMeasureDAO.updateByPrimaryKeySelective(measureDAOByShopId);
        ShopStageInfoDO shopStageInfo = shopStageInfoDAO.getShopSubStageInfo(shopInfoDO.getId(), ShopSubStageEnum.SHOP_STAGE_8_6);
        if (shopStageInfo.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_862.getShopSubStageStatus())) {
            shopStageInfoDAO.updateShopStageInfo(shopInfoDO.getId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_863);
        }
        return true;
    }

    @Override
    public MeasureResponse getMeasureData(Long shopId) {
        MeasureResponse response = new MeasureResponse();
        DecorationMeasureDO measureDAOByShopId = decorationMeasureDAO.getByShopId(shopId);
        if (measureDAOByShopId == null) {
            return response;
        }
        response.setMeasureUrl(measureDAOByShopId.getMeasureUrl());
        if (StringUtils.isBlank(measureDAOByShopId.getMeasureUserName())
                && StringUtils.isNotBlank(measureDAOByShopId.getMeasureUserId())) {
            response.setMeasureUserName(enterpriseUserDAO.getUserName(measureDAOByShopId.getMeasureUserId()));
            response.setMeasureUserId(measureDAOByShopId.getMeasureUserId());
        } else {
            response.setMeasureUserName(measureDAOByShopId.getMeasureUserName());
        }
        if (StringUtils.isBlank(measureDAOByShopId.getDesignLeaderName())
                && StringUtils.isNotBlank(measureDAOByShopId.getDesignUserId())) {
            response.setDesignLeaderName(enterpriseUserDAO.getUserName(measureDAOByShopId.getDesignUserId()));
            response.setDesignUserId(measureDAOByShopId.getDesignUserId());
        } else {
            response.setDesignLeaderName(measureDAOByShopId.getDesignLeaderName());
        }
        response.setMeasureDate(measureDAOByShopId.getMeasureDate());
        response.setDiagramDate(measureDAOByShopId.getDiagramDate());
        response.setMeasurementSheetId(measureDAOByShopId.getMeasurementSheetId());
        response.setSubmitTime(measureDAOByShopId.getUpdateTime());
        return response;
    }
}
