package com.red.circle.other.infra.database.mongo.service.team.team;

import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.dto.team.query.TeamMemberTargetQuery;
import com.red.circle.other.inner.enums.team.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 成员工作目标.
 *
 * @author pengliang on 2022/12/6
 */
public interface TeamMemberTargetService {

  /**
   * 创建成员工作数据.
   */
  void createMemberTarget(TeamMemberTarget param);

  /**
   * 每日工作数据.
   */
  void createDailyWorkTarget(Long userId, Integer billBelong);

  /**
   * 工作数据-不存在创建.
   */
  void createIfAbsent(TeamMemberTarget param);

  /**
   * 覆盖目标.
   */
  void updateTargetCover(Long userId, Integer billBelong, TeamMemberTargetIndex target);

  /**
   * 累计在线时长-自己房间.
   */
  void incrOwnOnlineTime(Long userId, Integer onlineTime);

  /**
   * 更新用户有效天.
   */
  void incrEffectiveDay(Long userId);

  /**
   * 累计在线时长-其他时间.
   */
  void incrOtherOnlineTime(Long userId, Integer onlineTime);

  /**
   * 累计接收礼物.
   */
  boolean incrAcceptGiftValue(Long userId, Long giftValue);

  boolean incrAcceptGiftValue(Long userId, Long giftValue, Integer dateNumber);

  /**
   * 累计减去接收礼物.
   */
  void decrAcceptGiftValue(Long userId, Integer dateNumber, Long giftValue);

  /**
   * 累计赠送礼物.
   */
  void incrGiveGiftValue(Long userId, Long giftValue);

  /**
   * 累计房间流水.
   */
  void incrRoomValue(Long userId, Long roomValue);

  /**
   * 判断成员是否存在目标记录.
   *
   * @return true 存在.
   */
  Boolean existsBillTarget(Long userId, Integer billBelong);

  /**
   * 获取团队账单人工作情况.
   */
  List<TeamMemberTarget> listByBillBelong(Long teamId, Integer billBelong);

  /**
   * 获取用户账单信息.
   */
  List<TeamMemberTarget> listMemberTarget(Long teamId, Long memberId, Integer billBelong);

  /**
   * 获取工作情况.
   */
  List<TeamMemberTarget> list(TeamMemberTargetQuery query);

  /**
   * 获取用户目标 >= billBelong 记录.
   */
  List<TeamMemberTarget> listByGeBillBelong(Long teamId, Long userId, Integer billBelong);

  /**
   * 获取一组成员账单数据.
   */
  Map<Long, TeamMemberTarget> mapMemberBillTarget(Long teamId, Set<Long> userIds,
      Integer billBelong);

  /**
   * 获取一组成员账单数据.
   */
  Map<Long, List<TeamMemberTarget>> mapMemberBillTarget(Set<Long> teamIds, Integer billBelong);

  /**
   * 移除用户目标.
   */
  void removeUserTarget(Integer billBelong, Long userId);

  /**
   * 修改本月，成员账单目标归属.
   */
  void updateThisMonthUserTargetAscription(Long userId, Long newTeamId);

  /**
   * 修改本月，将成员账单归类于历史账单.
   */
  void updateThisMonthUserTargetHistoryStatusByUserId(Long userId);

  /**
   * 修改本月，将成员账单归类于历史账单.
   */
  void updateThisMonthUserTargetHistoryStatusByTeamId(Long teamId);

  /**
   * 获取指定目标记录.
   */
  TeamMemberTarget getByTimeId(Long timeId);

  /**
   * 获取指定目标记录.
   */
  TeamMemberTarget getById(String id);

  /**
   * 获取指定用户账单目标.
   */
  TeamMemberTarget getUserByBillId(Long userId, Integer billBelong);

  /**
   * 标记道具已领取.
   */
  void updateTargetPropsReceivedTrue(String id);

  /**
   * 保存结算结果.
   */
  void saveSettlementResult(String id,
      TeamMemberTargetStatus status,
      TeamMemberTargetSettlementResult settlementResult);

  /**
   * 移除团队所有工作记录.
   */
  void removeBatchByTeamIds(List<Long> teamIds);

  /**
   * 获取最新进行中目标数量.
   */
  Long getLatestInProgressTarget(Long userId);

  /**
   * 统计本月团队总目标.
   */
  Long countThisMonthTeamMemberTarget(List<Long> teamIds);


    /**
     * 统计上个月团队总目标.
     */
  Long countLastMonthTeamMemberTarget(List<Long> teamIds);

  /**
   * 根据团队id修改本月成员目标状态.
   *
   * @param teamIds 团队ID
   * @param status  目标状态
   */
  void updateStatusByTeamIds(Set<Long> teamIds, TeamMemberTargetStatus status);

  /**
   * 检查并处理重复的成员月目标记录.
   */
  Set<String> repeatTargetHistory();

  /**
   * 统计某个团队在某个结算周期的工资总和.
   *
   * @param teamId 团队ID
   * @param billBelong 结算周期
   * @return 工资总和（美元）
   * @deprecated 使用 {@link #statisticsTeamSalaryByTeamIdAndBillBelong(Long, Integer)} 代替
   */
  @Deprecated
  BigDecimal sumTeamSalaryByTeamIdAndBillBelong(Long teamId, Integer billBelong);

  /**
   * 统计某个团队在某个结算周期的工资信息（包含用户列表和工资总和）.
   *
   * @param teamId 团队ID
   * @param billBelong 结算周期
   * @return 团队工资统计信息（包含用户ID列表和工资总和）
   */
  TeamSalaryStatisticsCO statisticsTeamSalaryByTeamIdAndBillBelong(
      Long teamId, Integer billBelong);

  /**
   * 按月查询团队成员目标（聚合半月数据）.
   * 用于前端按月展示，会自动聚合同一个月的多条记录
   * 
   * @param teamId 团队ID
   * @param monthlyBillBelong 月度账期（202511）
   * @return 该月所有成员目标列表（可能包含两个批次的数据）
   */
  List<TeamMemberTarget> listByMonthlyBillBelong(Long teamId, Integer monthlyBillBelong);

  /**
   * 按月查询单个成员目标（聚合半月数据）.
   * 用于查询指定用户的月度数据
   * 
   * @param teamId 团队ID
   * @param userId 用户ID
   * @param monthlyBillBelong 月度账期（202511）
   * @return 该月该成员的所有目标记录（通常1-2条）
   */
  List<TeamMemberTarget> listMemberMonthlyTarget(Long teamId, Long userId, Integer monthlyBillBelong);

  /**
   * 按月统计成员目标（聚合后返回月度汇总）.
   * 用于前端展示月度累计数据，会自动合并同一个月的多条记录
   * 
   * @param teamId 团队ID
   * @param userId 用户ID  
   * @param monthlyBillBelong 月度账期（202511）
   * @return 月度汇总后的成员目标（dailyTargets 包含整月数据，settlementResult 为累计值）
   */
  TeamMemberTarget aggregateMonthlyTarget(Long teamId, Long userId, Integer monthlyBillBelong);

    /**
     * 团队用户已结算的工资
     */
  BigDecimal listMemberSettledAndSumSalary(Long teamId, Long userId, TeamMemberRole role);

}
