package com.red.circle.other.app.command.team.query;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.red.circle.other.app.dto.clientobject.team.AnchorWorkStatisticsCO;
import com.red.circle.other.app.dto.cmd.team.DateTypeQryCmd;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamBillCycle;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamBillCycleService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;

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

import com.red.circle.other.inner.enums.team.TeamMemberTargetIndex;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import static com.red.circle.other.infra.database.mongo.service.team.TeamBillCycleUtils.getCalcBillBelong;

/**
 * 历史app内主播中心 数据统计.
 *
 * @author pengliang on 2023/01/15
 */
@Component
@RequiredArgsConstructor
public class TeamHistoryWorkCountQryExe {

  private final TeamMemberService teamMemberService;
  private final TeamBillCycleService teamBillCycleService;
  private final TeamMemberTargetService teamMemberTargetService;

  public List<AnchorWorkStatisticsCO> execute(DateTypeQryCmd cmd) {

    TeamMember teamMember = teamMemberService.getByMemberId(cmd.getMemberId());

    if (Objects.isNull(teamMember)) {
      return Lists.newArrayList();
    }

    List<TeamMemberTarget> teamMemberTargets = teamMemberTargetService.listMemberTarget(
        teamMember.getTeamId(), teamMember.getMemberId(), null);

    if (Objects.isNull(teamMemberTargets)) {
      return Lists.newArrayList();
    }

    if (cmd.isDaily()) {
      return toDaily(teamMemberTargets);
    }

    return toMonth(teamMemberTargets);
  }

    public AnchorWorkStatisticsCO executeNow(DateTypeQryCmd cmd) {

        TeamMember teamMember = teamMemberService.getByMemberId(cmd.getMemberId());

        if (Objects.isNull(teamMember)) {
            return null;
        }

        List<TeamMemberTarget> teamMemberTargets = teamMemberTargetService.listMemberMonthlyTarget(
                teamMember.getTeamId(), teamMember.getMemberId(), ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt());

        if (CollectionUtils.isEmpty(teamMemberTargets)) {
            return null;
        }

        List<TeamMemberTargetIndex> dailyTargets = Lists.newArrayList();
        teamMemberTargets.forEach(teamMemberTarget -> {
            dailyTargets.addAll(teamMemberTarget.getDailyTargets());
        });

        return dailyTargets.stream()
                .filter(Objects::nonNull)
                .filter(e -> Objects.equals(e.getDateNumber(), ZonedDateTimeAsiaRiyadhUtils.nowDateToInt()))
                .sorted(Comparator.comparing(TeamMemberTargetIndex::getUpdateTime).reversed())
                .map(dailyTarget -> new AnchorWorkStatisticsCO()
                        .setId(teamMemberTargets.get(0).getTimeId())
                        .setOwnTime(dailyTarget.getOwnOnlineTime())
                        .setOtherTime(dailyTarget.getOtherOnlineTime())
                        .setAcceptGiftValue(dailyTarget.getAcceptGiftValue())
                        .setTitle(Objects.toString(dailyTarget.getDateNumber()))
                        .setCreateTime(dailyTarget.getCreateTime()))
                .findFirst().orElse(null);

    }

  private List<AnchorWorkStatisticsCO> toMonth(List<TeamMemberTarget> teamMemberTargets) {

    Map<String, TeamBillCycle> teamBillCycleMap = teamBillCycleService.mapByBillIds(
        teamMemberTargets.stream().map(TeamMemberTarget::getTeamId)
            .collect(Collectors.toSet()),
        teamMemberTargets.stream().map(TeamMemberTarget::getBillBelong)
            .collect(Collectors.toSet())
    );

    return teamMemberTargets.stream()
        .map(target -> {

          TeamBillCycle teamBillCycle = teamBillCycleMap.get(
              target.getTeamId() + "_" + target.getBillBelong());

          if (Objects.isNull(teamBillCycle)) {
            return null;
          }

          if (CollectionUtils.isEmpty(target.getDailyTargets())) {
            return null;
          }

          return new AnchorWorkStatisticsCO()
              .setId(target.getTimeId())
              .setOwnTime(target.sumOwnOnlineTime())
              .setOtherTime(target.sumOtherOnlineTime())
              .setAcceptGiftValue(target.sumAcceptGiftValue())
              .setTitle(Objects.toString(teamBillCycle.getBillBelong()))
              .setCreateTime(target.getCreateTime());
        }).collect(Collectors.toList());
  }


  private List<AnchorWorkStatisticsCO> toDaily(List<TeamMemberTarget> teamMemberTargets) {
    return teamMemberTargets.stream()
        .map(target -> {
          if (CollectionUtils.isEmpty(target.getDailyTargets())) {
            return null;
          }
          return target.getDailyTargets().stream()
              .map(dailyTarget -> new AnchorWorkStatisticsCO()
                  .setId(target.getTimeId())
                  .setOwnTime(dailyTarget.getOwnOnlineTime())
                  .setOtherTime(dailyTarget.getOtherOnlineTime())
                  .setAcceptGiftValue(dailyTarget.getAcceptGiftValue())
                  .setTitle(Objects.toString(dailyTarget.getDateNumber()))
                  .setCreateTime(dailyTarget.getCreateTime()))
              .collect(Collectors.toList());
        }).filter(CollectionUtils::isNotEmpty).flatMap(Collection::stream)
        .collect(Collectors.toList());
  }

}
