package com.haha.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.haha.entity.InviteActivity;
import com.haha.entity.InviteRecord;
import com.haha.entity.dto.InviteActivityCreateDTO;
import com.haha.entity.dto.InviteActivityUpdateDTO;
import com.haha.entity.dto.InviteRecordQueryDTO;

import java.util.List;
import java.util.Map;

/**
 * 邀请活动服务接口
 * 提供邀请活动的完整生命周期管理，包括活动CRUD、邀请码生成、邀请关系绑定、
 * 邀请激活、奖励发放、防刷检查等功能
 */
public interface InviteActivityService extends IService<InviteActivity> {

    // ==================== CRUD 操作 ====================

    /**
     * 分页查询邀请记录列表
     *
     * @param queryDTO 查询条件（包含分页参数）
     * @return 分页结果
     */
    IPage<InviteActivity> getPage(InviteRecordQueryDTO queryDTO);

    /**
     * 获取邀请活动详情
     *
     * @param id 活动ID
     * @return 活动详情
     */
    InviteActivity getDetail(Long id);

    /**
     * 创建邀请活动
     *
     * @param dto         创建请求DTO
     * @param creatorId   创建人ID
     * @param creatorName 创建人姓名
     * @return 创建的活动对象
     */
    InviteActivity create(InviteActivityCreateDTO dto, Long creatorId, String creatorName);

    /**
     * 更新邀请活动
     *
     * @param dto 更新请求DTO
     * @return 更新后的活动对象
     */
    InviteActivity update(InviteActivityUpdateDTO dto);

    /**
     * 发布活动（草稿状态 -> 已发布/进行中）
     *
     * @param id 活动ID
     * @return 是否成功
     */
    boolean publish(Long id);

    /**
     * 暂停活动
     *
     * @param id 活动ID
     * @return 是否成功
     */
    boolean pause(Long id);

    /**
     * 恢复活动
     *
     * @param id 活动ID
     * @return 是否成功
     */
    boolean resume(Long id);

    /**
     * 删除活动（逻辑删除）
     *
     * @param id 活动ID
     * @return 是否成功
     */
    boolean deleteActivity(Long id);

    // ==================== 邀请码相关 ====================

    /**
     * 生成邀请码
     * 格式：前缀 + 用户ID编码 + 活动ID编码 + 时间戳 + 4位随机数
     * 使用Base62编码压缩长度，保证唯一性
     *
     * @param userId    邀请人用户ID
     * @param activityId 活动ID
     * @return 生成的邀请码
     */
    String generateInviteCode(Long userId, Long activityId);

    /**
     * 获取当前进行中的邀请活动
     *
     * @return 进行中的活动，如果没有返回null
     */
    InviteActivity getOngoingActivity();

    /**
     * 获取所有进行中的邀请活动列表（定时任务使用）
     *
     * @return 进行中的活动列表
     */
    List<InviteActivity> getOngoingActivities();

    // ==================== 邀请关系绑定 ====================

    /**
     * 绑定邀请关系
     * 当被邀请人通过邀请码注册时调用此方法建立邀请关系
     *
     * @param activityId     活动ID
     * @param inviterUserId  邀请人用户ID
     * @param inviteeUserId  被邀请人用户ID
     * @param inviteCode     邀请码
     * @param sourceChannel  来源渠道（如：微信分享、二维码扫描等）
     * @param deviceInfo     设备信息
     * @param ipAddress      IP地址
     * @return 是否绑定成功
     */
    boolean bindInviteRelation(Long activityId, Long inviterUserId, Long inviteeUserId,
                               String inviteCode, String sourceChannel, String deviceInfo, String ipAddress);

    /**
     * 绑定邀请关系（自动根据邀请码查询活动ID和邀请人）
     *
     * @param inviteeUserId 被邀请人用户ID
     * @param inviteCode    邀请码
     * @param sourceChannel 来源渠道
     * @param deviceInfo    设备信息
     * @return 是否绑定成功，邀请码无效时返回false
     */
    boolean bindInviteRelation(Long inviteeUserId, String inviteCode, String sourceChannel, String deviceInfo);

    // ==================== 邀请激活 ====================

    /**
     * 激活邀请记录
     * 当被邀请人完成首单时调用此方法，将邀请记录从"待激活"变为"已激活"
     *
     * @param inviteeUserId 被邀请人用户ID
     * @param orderId       订单ID
     * @return 是否激活成功
     */
    boolean activateInviteRecord(Long inviteeUserId, Long orderId);

    // ==================== 奖励发放 ====================

    /**
     * 发放奖励
     * 根据邀请记录发放优惠券奖励给邀请人
     *
     * @param recordId 邀请记录ID
     * @return 是否发放成功
     */
    boolean distributeReward(Long recordId);

    /**
     * 向被邀请人发放新人优惠券
     * 当新用户通过邀请链接注册并绑定关系时，立即向被邀请人发放优惠券
     *
     * @param recordId 邀请记录ID
     * @return 是否发放成功
     */
    boolean distributeInviteeCoupon(Long recordId);

    // ==================== 统计查询 ====================

    /**
     * 分页查询邀请记录列表（管理端）
     *
     * @param queryDTO 查询条件（包含分页参数）
     * @return 分页结果
     */
    IPage<InviteRecord> getInviteRecords(InviteRecordQueryDTO queryDTO);

    /**
     * 获取活动统计数据
     *
     * @param activityId 活动ID
     * @return 统计数据Map（包含总邀请数、有效邀请数、今日邀请数等）
     */
    Map<String, Object> getActivityStatistics(Long activityId);

    /**
     * 获取当前用户的邀请统计
     *
     * @param userId     用户ID
     * @param activityId 活动ID
     * @return 用户邀请统计数据
     */
    Map<String, Object> getMyInviteStatistics(Long userId, Long activityId);

    /**
     * 获取当前用户的邀请统计（自动获取当前活动）
     *
     * @param userId 用户ID
     * @return 用户邀请统计数据，无进行中活动时返回空Map
     */
    Map<String, Object> getMyInviteStatistics(Long userId);

    /**
     * 获取当前用户的邀请码信息（含活动信息和邀请链接）
     *
     * @param userId 用户ID
     * @return 包含 inviteCode、inviteLink、activityInfo 的Map，无活动时返回 null
     */
    Map<String, Object> getInviteCodeInfo(Long userId);

    /**
     * 获取当前用户的邀请海报信息
     *
     * @param userId 用户ID
     * @return 包含 inviteCode、posterUrl 的Map，无活动时返回 null
     */
    Map<String, Object> generatePosterInfo(Long userId);

    /**
     * 分页查询当前用户的邀请记录列表
     *
     * @param userId     用户ID
     * @param activityId 活动ID
     * @param page       页码
     * @param pageSize   每页条数
     * @return 分页结果
     */
    IPage<InviteRecord> getMyInviteRecords(Long userId, Long activityId, Integer page, Integer pageSize);

    /**
     * 分页查询当前用户的邀请记录列表（自动获取当前活动）
     *
     * @param userId   用户ID
     * @param page     页码
     * @param pageSize 每页条数
     * @return 分页结果，无进行中活动时为空分页
     */
    IPage<InviteRecord> getMyInviteRecords(Long userId, Integer page, Integer pageSize);

    // ==================== 防刷检查 ====================

    /**
     * 防刷检查
     * 检查用户是否超过邀请限制，防止恶意刷邀请
     *
     * @param inviterUserId 邀请人用户ID
     * @param activityId    活动ID
     * @param ipAddress     IP地址
     * @param deviceInfo    设备信息
     * @return true-通过检查可以继续邀请；false-未通过检查，存在刷邀请嫌疑
     */
    boolean checkAntiFraud(Long inviterUserId, Long activityId, String ipAddress, String deviceInfo);

    // ==================== 手动补发奖励 ====================

    /**
     * 自动更新活动状态（定时任务调用）
     * 检查活动的开始/结束时间，自动将活动状态更新为"进行中"或"已结束"
     *
     * @return 更新结果：[0]=应开始数量, [1]=应结束数量
     */
    int[] autoUpdateActivityStatus();

    /**
     * 重试发放失败的奖励（定时任务调用）
     *
     * @param maxRetryCount 最大重试次数
     * @param batchSize      每批处理数量
     * @return [0]=成功数, [1]=失败数
     */
    int[] retryFailedRewards(int maxRetryCount, int batchSize);

    /**
     * 获取即将结束的活动列表（定时任务调用）
     *
     * @param daysAhead 提前天数
     * @return 即将结束的活动列表
     */
    List<InviteActivity> getEndingSoonActivities(int daysAhead);

    /**
     * 手动补发失败的奖励
     * 管理员操作，用于处理发放失败的奖励记录
     *
     * @param rewardId     奖励记录ID
     * @param operatorId   操作人ID
     * @param operatorName 操作人姓名
     * @return 是否补发成功
     */
    boolean manualReissueReward(Long rewardId, Long operatorId, String operatorName);

    /**
     * 根据邀请码查询邀请记录
     *
     * @param inviteCode 邀请码
     * @return 邀请记录，如果不存在返回null
     */
    InviteRecord getInviteRecordByCode(String inviteCode);
}
