package com.cool.store.service.impl;

import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.*;
import com.cool.store.dto.partner.PartnerOpenNewShopPageDTO;
import com.cool.store.entity.HyOpenAreaInfoDO;
import com.cool.store.entity.LineInfoDO;
import com.cool.store.entity.OpenNewShopRecordDO;
import com.cool.store.entity.SigningBaseInfoDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.IntentAgreementMapper;
import com.cool.store.request.AddShopRequest;
import com.cool.store.request.AuditOpenNewShopRequest;
import com.cool.store.request.PartnerOpenNewShopPageRequest;
import com.cool.store.request.SubmitOpenNewShopRequest;
import com.cool.store.service.LabelService;
import com.cool.store.service.OpenNewShopService;
import com.cool.store.service.ShopService;
import com.cool.store.vo.IsSubmitOpenNewShopVO;
import com.cool.store.vo.PartnerOpenNewShopDetailVO;
import com.cool.store.vo.PartnerOpenNewShopPageVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zhangchenbiao
 * @FileName: OpenNewShopServiceImpl
 * @Description:
 * @date 2024-05-09 15:12
 */
@Service
public class OpenNewShopServiceImpl implements OpenNewShopService {

    @Resource
    private HyOpenAreaInfoDAO hyOpenAreaInfoDAO;
    @Resource
    private OpenNewShopRecordDAO openNewShopRecordDAO;
    @Resource
    private IntentAgreementMapper intentAgreementMapper;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;
    @Resource
    private HyPartnerUserChannelDAO hyPartnerUserChannelDAO;
    @Resource
    private LabelService labelService;
    @Resource
    private ShopService shopService;
    @Resource
    private ShopStageInfoDAO shopStageInfoDAO;
    @Resource
    private LineInfoDAO lineInfoDAO;


    @Override
    public PageInfo<PartnerOpenNewShopPageVO> getPartnerOpenNewShopPage(PartnerOpenNewShopPageRequest request) {
        if(Objects.nonNull(request.getWantShopAreaId())){
            HyOpenAreaInfoDO areaInfo = hyOpenAreaInfoDAO.selectById(request.getWantShopAreaId());
            if(Objects.nonNull(areaInfo)){
                request.setAreaPath(areaInfo.getAreaPath());
            }
        }
        Page<PartnerOpenNewShopPageDTO> page = openNewShopRecordDAO.getPartnerOpenNewShopPage(request);
        List<PartnerOpenNewShopPageVO> resultList = Lists.newArrayList();
        if(Objects.nonNull(page) && CollectionUtils.isNotEmpty(page.getResult())){
            List<PartnerOpenNewShopPageDTO> result = page.getResult();
            List<Long> lineIds = result.stream().filter(o -> Objects.nonNull(o.getLineId())).map(PartnerOpenNewShopPageDTO::getLineId).distinct().collect(Collectors.toList());
            List<Long> wantShopAreaIds = result.stream().filter(o -> Objects.nonNull(o.getWantShopAreaId())).map(PartnerOpenNewShopPageDTO::getWantShopAreaId).distinct().collect(Collectors.toList());
            List<String> developmentManagerUserIds = result.stream().filter(o -> Objects.nonNull(o.getDevelopmentManager())).map(PartnerOpenNewShopPageDTO::getDevelopmentManager).distinct().collect(Collectors.toList());
            List<Integer> lineSourceIds = result.stream().filter(o -> Objects.nonNull(o.getLineSource())).map(PartnerOpenNewShopPageDTO::getLineSource).distinct().collect(Collectors.toList());
            List<String> userPortraitList  = result.stream().filter(x -> StringUtils.isNotEmpty(x.getUserPortrait() )).map(PartnerOpenNewShopPageDTO::getUserPortrait).collect(Collectors.toList());
            List<SigningBaseInfoDO> signingBaseInfoDOS = intentAgreementMapper.selectByLineIds(lineIds);
            Map<Long, String>  wantShopAreaMap = hyOpenAreaInfoDAO.selectNameMapByIds(wantShopAreaIds);
            Map<String, String> userNameMap = enterpriseUserDAO.getUserNameMap(developmentManagerUserIds);
            Map<Integer, String> channelMap = hyPartnerUserChannelDAO.getChannelMapByIds(lineSourceIds);
            Map<Long, String> userPortraitMap = labelService.getUserPortraitMap(userPortraitList);
            Map<Long, Date> dateMap = signingBaseInfoDOS.stream().collect(Collectors.toMap(SigningBaseInfoDO::getLineId, SigningBaseInfoDO::getCreateTime));
            resultList = PartnerOpenNewShopPageVO.convertList(result, dateMap, wantShopAreaMap, userNameMap, channelMap, userPortraitMap);
        }
        PageInfo resultPage = new PageInfo(page);
        resultPage.setList(resultList);
        return resultPage;
    }

    @Override
    public PartnerOpenNewShopDetailVO getOpenNewShopRecordDetail(Long recordId) {
        OpenNewShopRecordDO openNewShopRecord = openNewShopRecordDAO.getOpenNewShopRecordById(recordId);
        if(Objects.isNull(openNewShopRecord)){
            throw new ServiceException(ErrorCodeEnum.OPEN_NEW_SHOP_RECORD_NOT_EXIST);
        }
        return PartnerOpenNewShopDetailVO.convert(openNewShopRecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer auditOpenNewShop(AuditOpenNewShopRequest request) {
        OpenNewShopRecordDO openNewShopRecord = openNewShopRecordDAO.getOpenNewShopRecordById(request.getRecordId());
        if(Objects.isNull(openNewShopRecord) || openNewShopRecord.getDeleted()){
            throw new ServiceException(ErrorCodeEnum.OPEN_NEW_SHOP_RECORD_NOT_EXIST);
        }
        if(CommonConstants.ZERO != openNewShopRecord.getAuditResult()){
            throw new ServiceException(ErrorCodeEnum.OPEN_NEW_SHOP_RECORD_AUDITED);
        }
        if(request.getAuditResult() == CommonConstants.ONE){
            shopService.addShop(new AddShopRequest(openNewShopRecord.getLineId(), request.getShopNameList()));
        }
        OpenNewShopRecordDO update = new OpenNewShopRecordDO();
        update.setId(request.getRecordId());
        update.setAuditResult(request.getAuditResult());
        return openNewShopRecordDAO.updateOpenNewShopRecord(update);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long submitOpenNewShop(SubmitOpenNewShopRequest request) {
        List<OpenNewShopRecordDO> recordList = openNewShopRecordDAO.getOpenNewShopRecordList(request.getLineId());
        if(CollectionUtils.isNotEmpty(recordList)){
            List<OpenNewShopRecordDO> waitAuditRecordList = recordList.stream().filter(o -> CommonConstants.ZERO == o.getAuditResult()).collect(Collectors.toList());
            //过滤待审核的
            if(CollectionUtils.isNotEmpty(waitAuditRecordList)){
                throw new ServiceException(ErrorCodeEnum.OPEN_NEW_SHOP_RECORD_WAIT_AUDIT);
            }
            List<Long> deleteIds = recordList.stream().map(OpenNewShopRecordDO::getId).collect(Collectors.toList());
            openNewShopRecordDAO.deleteOpenNewShopRecord(deleteIds);
        }
        return openNewShopRecordDAO.insertOpenNewShopRecord(request.convertDO());
    }

    @Override
    public IsSubmitOpenNewShopVO isSubmitOpenNewShop(Long lineId) {
        LineInfoDO lineInfo = lineInfoDAO.getLineInfo(lineId);
        if(Objects.isNull(lineInfo)){
            return new IsSubmitOpenNewShopVO(Boolean.FALSE, null);
        }
        if(lineInfo.getJoinStatus() != 2){
            return new IsSubmitOpenNewShopVO(Boolean.FALSE, null);
        }
        //首先获取有没有待审核的记录
        OpenNewShopRecordDO openNewShopRecord = openNewShopRecordDAO.getWaitAuditOpenNewShopRecord(lineId);
        if(Objects.nonNull(openNewShopRecord)){
            return new IsSubmitOpenNewShopVO(Boolean.FALSE, openNewShopRecord.getAuditResult());
        }
        //没有待审核的记录 去获取店铺是否都已经在验收中
        Integer notOpenShopCount = shopStageInfoDAO.getNotOpenShopCountByLineId(lineId);
        return new IsSubmitOpenNewShopVO(notOpenShopCount <= CommonConstants.ZERO, null);
    }
}