package com.fs.statis.impl;

import com.fs.common.utils.StringUtils;
import com.fs.company.cache.ICompanyDeptCacheService;
import com.fs.company.cache.ICompanyUserCacheService;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyUserMapper;
import com.fs.qw.domain.QwUser;
import com.fs.qw.mapper.QwUserMapper;
import com.fs.statis.IFsStatisQwWatchService;
import com.fs.statis.domain.FsStatisQwTempParam;
import com.fs.statis.domain.FsStatisQwWatch;
import com.fs.statis.dto.FsStatisQwWatchWriteDataDTO;
import com.fs.statis.dto.StatsWatchLogPageListDTO;
import com.fs.statis.mapper.FsStatisQwTempParamMapper;
import com.fs.statis.mapper.FsStatisQwWatchMapper;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FsStatisQwWatchServiceImpl implements IFsStatisQwWatchService {
    @Autowired
    private FsStatisQwWatchMapper fsStatisQwWatchMapper;

    @Autowired
    private CompanyUserMapper companyUserMapper;

    @Autowired
    private QwUserMapper qwUserMapper;

    @Autowired
    private ICompanyDeptCacheService companyDeptCacheService;

    @Autowired
    private ICompanyUserCacheService companyUserCacheService;

    @Autowired
    private FsStatisQwTempParamMapper fsStatisQwTempParamMapper;
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public synchronized void writeData(String date) {

        FsStatisQwWatchWriteDataDTO paramByDate = getParamByDate(date);


        List<CompanyUser> companyUserList = this.companyUserMapper.selectAllCompanyUserList();
        Map<Long, List<Long>> qwUserIdMap = queryQwListMap();


        List<FsStatisQwTempParam> paramList = new ArrayList<>();
        for (CompanyUser companyUser : companyUserList) {
            if(companyUser.getCompanyId() == null) {
                log.info("销售{} 对应公司id {} 为空！",companyUser.getUserId(),companyUser.getCompanyId());
                continue;
            }
            // 找到销售关联的 企微账号
            List<Long> qwUserIdList = qwUserIdMap.get(companyUser.getUserId());
            if(CollectionUtils.isEmpty(qwUserIdList)){
                log.info("当前销售 {} 没有关联企微账号！",companyUser.getUserId());
                continue;
            }

            for (Long qwUserId : qwUserIdList) {
                FsStatisQwTempParam param = new FsStatisQwTempParam();
                param.setDeptId(companyUser.getDeptId());
                param.setCompanyUserId(companyUser.getUserId());
                param.setQwUserId(qwUserId);
                param.setThisDate(paramByDate.getDate());
                param.setCompanyId(companyUser.getCompanyId());
                paramList.add(param);
            }
        }
        fsStatisQwTempParamMapper.clear();

        fsStatisQwTempParamMapper.insertList(paramList);

        fsStatisQwWatchMapper.generateData(paramByDate);

        fsStatisQwTempParamMapper.clear();
    }

    @Override
    public List<FsStatisQwWatch> queryList(StatsWatchLogPageListDTO param) {
        if(StringUtils.isNull(param.getStartDate()) && StringUtils.isNull(param.getEndDate())) {
            return Collections.emptyList();
        }

        List<FsStatisQwWatch> list = fsStatisQwWatchMapper.queryList(param);

        for (FsStatisQwWatch item : list) {
            if(item.getDeptId() != null) {
                String deptNameById = companyDeptCacheService.getDeptNameById(item.getDeptId());
                if(StringUtils.isNotBlank(deptNameById)) {
                    item.setDeptName(deptNameById);
                }
            }

            if(item.getCompanyUserId() != null) {
                String companyUserName = companyUserCacheService.selectCompanyUserNameUserById(item.getCompanyUserId());
                if(StringUtils.isNotBlank(companyUserName)) {
                    item.setCompanyUserName(companyUserName);
                }
            }
        }
        return list;
    }

    @Override
    public List<FsStatisQwWatch> exportQueryList(StatsWatchLogPageListDTO param) {
        if(StringUtils.isNull(param.getStartDate()) && StringUtils.isNull(param.getEndDate())) {
            return Collections.emptyList();
        }

        List<FsStatisQwWatch> list = fsStatisQwWatchMapper.exportList(param);

        return list;
    }

    private FsStatisQwWatchWriteDataDTO getParamByDate(String dateStr){
        LocalDate targetDate;

        if (dateStr != null && !dateStr.isEmpty()) {
            try {
                targetDate = LocalDate.parse(dateStr, DATE_FORMATTER);
            } catch (DateTimeParseException e) {
                log.info("提供的日期字符串格式无效: {} . 期望格式: yyyy-MM-dd" ,dateStr);
                throw e;
            }
        } else {
            targetDate = LocalDate.now().minusDays(1);
        }

        LocalDateTime startTime = targetDate.atStartOfDay();

        LocalDateTime endTime = targetDate.plusDays(1).atStartOfDay();

        FsStatisQwWatchWriteDataDTO params = new FsStatisQwWatchWriteDataDTO();
        params.setDate(targetDate);
        params.setStartTime(startTime.format(DATE_TIME_FORMATTER));
        params.setEndTime(endTime.format(DATE_TIME_FORMATTER));
        return params;
    }


    private Map<Long,List<Long>> queryQwListMap(){
        List<QwUser> qwUsers = qwUserMapper.selectQwUserAllList();
        if(CollectionUtils.isEmpty(qwUsers)){
            return Maps.newHashMap();
        }

        return qwUsers.stream()
                .filter(Objects::nonNull)
                .filter(user -> user.getCompanyUserId() != null && user.getQwUserId() != null)
                .collect(Collectors.groupingBy(
                        QwUser::getCompanyUserId,
                        Collectors.mapping(QwUser::getId, Collectors.toList())
                ));
    }
}
