package com.haha.admin.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.haha.admin.annotation.RequirePermission;
import com.haha.common.annotation.Log;
import com.haha.common.enums.OperationType;
import com.haha.common.vo.PageResult;
import com.haha.common.vo.Result;
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 com.haha.service.InviteActivityService;
import cn.dev33.satoken.stp.StpUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 邀请活动管理端控制器
 * 提供邀请活动的CRUD管理、数据统计、邀请记录查询、奖励补发等功能
 */
@Slf4j
@RestController
@RequestMapping("/marketing/invite")
@RequiredArgsConstructor
public class InviteActivityAdminController {

    private final InviteActivityService inviteActivityService;

    // ==================== 活动管理 ====================

    /**
     * 创建邀请活动
     *
     * @param dto 创建请求DTO
     * @return 创建的活动对象
     */
    @RequirePermission("marketing:invite:create")
    @Log(module = "邀请活动", operation = OperationType.INSERT, summary = "创建邀请活动")
    @PostMapping("/activity")
    public Result<InviteActivity> createActivity(@RequestBody @Valid InviteActivityCreateDTO dto) {
        Long creatorId = StpUtil.getLoginIdAsLong();
        String creatorName = (String) StpUtil.getSession().get("name");
        log.info("[邀请活动] 创建邀请活动 - creatorId: {}, activityName: {}", creatorId, dto.getActivityName());
        InviteActivity activity = inviteActivityService.create(dto, creatorId, creatorName);
        return Result.success("创建成功", activity);
    }

    /**
     * 更新邀请活动
     *
     * @param id  活动ID
     * @param dto 更新请求DTO
     * @return 更新后的活动对象
     */
    @RequirePermission("marketing:invite:edit")
    @Log(module = "邀请活动", operation = OperationType.UPDATE, summary = "编辑邀请活动")
    @PutMapping("/activity/{id}")
    public Result<InviteActivity> updateActivity(@PathVariable Long id,
                                                  @RequestBody @Valid InviteActivityUpdateDTO dto) {
        dto.setId(id);
        log.info("[邀请活动] 更新邀请活动 - id: {}", id);
        InviteActivity activity = inviteActivityService.update(dto);
        return Result.success("更新成功", activity);
    }

    /**
     * 获取邀请活动详情
     *
     * @param id 活动ID
     * @return 活动详情
     */
    @RequirePermission("marketing:invite:read")
    @GetMapping("/activity/{id}")
    public Result<InviteActivity> getActivityDetail(@PathVariable Long id) {
        log.info("[邀请活动] 查询活动详情 - id: {}", id);
        InviteActivity activity = inviteActivityService.getDetail(id);
        return Result.success("查询成功", activity);
    }

    /**
     * 分页查询邀请活动列表
     *
     * @param queryDTO 查询条件（包含分页参数）
     * @return 分页结果
     */
    @RequirePermission("marketing:invite:read")
    @GetMapping("/activity/list")
    public Result<PageResult<InviteActivity>> getActivityList(InviteRecordQueryDTO queryDTO) {
        queryDTO.validate();
        log.info("[邀请活动] 分页查询活动列表 - page: {}, pageSize: {}", queryDTO.getPage(), queryDTO.getPageSize());
        IPage<InviteActivity> page = inviteActivityService.getPage(queryDTO);
        return Result.success("查询成功", PageResult.of(page));
    }

    /**
     * 发布邀请活动（草稿状态 -> 已发布）
     *
     * @param id 活动ID
     * @return 操作结果
     */
    @RequirePermission("marketing:invite:publish")
    @Log(module = "邀请活动", operation = OperationType.UPDATE, summary = "发布邀请活动")
    @PutMapping("/activity/{id}/publish")
    public Result<Void> publishActivity(@PathVariable Long id) {
        log.info("[邀请活动] 发布活动 - id: {}", id);
        boolean success = inviteActivityService.publish(id);
        if (!success) {
            return Result.error("发布失败，请检查活动状态");
        }
        return Result.success("发布成功", null);
    }

    /**
     * 暂停邀请活动
     *
     * @param id 活动ID
     * @return 操作结果
     */
    @RequirePermission("marketing:invite:edit")
    @Log(module = "邀请活动", operation = OperationType.UPDATE, summary = "暂停邀请活动")
    @PutMapping("/activity/{id}/pause")
    public Result<Void> pauseActivity(@PathVariable Long id) {
        log.info("[邀请活动] 暂停活动 - id: {}", id);
        boolean success = inviteActivityService.pause(id);
        if (!success) {
            return Result.error("暂停失败，请检查活动状态");
        }
        return Result.success("暂停成功", null);
    }

    /**
     * 恢复邀请活动
     *
     * @param id 活动ID
     * @return 操作结果
     */
    @RequirePermission("marketing:invite:edit")
    @Log(module = "邀请活动", operation = OperationType.UPDATE, summary = "恢复邀请活动")
    @PutMapping("/activity/{id}/resume")
    public Result<Void> resumeActivity(@PathVariable Long id) {
        log.info("[邀请活动] 恢复活动 - id: {}", id);
        boolean success = inviteActivityService.resume(id);
        if (!success) {
            return Result.error("恢复失败，请检查活动状态");
        }
        return Result.success("恢复成功", null);
    }

    /**
     * 删除邀请活动（逻辑删除）
     *
     * @param id 活动ID
     * @return 操作结果
     */
    @RequirePermission("marketing:invite:delete")
    @Log(module = "邀请活动", operation = OperationType.DELETE, summary = "删除邀请活动")
    @DeleteMapping("/activity/{id}")
    public Result<Void> deleteActivity(@PathVariable Long id) {
        log.info("[邀请活动] 删除活动 - id: {}", id);
        boolean success = inviteActivityService.deleteActivity(id);
        if (!success) {
            return Result.error("删除失败，请检查活动状态");
        }
        return Result.success("删除成功", null);
    }

    // ==================== 数据统计 ====================

    /**
     * 获取邀请活动统计数据
     *
     * @param activityId 活动ID
     * @return 统计数据Map
     */
    @RequirePermission("marketing:invite:read")
    @GetMapping("/statistics/{activityId}")
    public Result<Map<String, Object>> getStatistics(@PathVariable Long activityId) {
        log.info("[邀请活动] 查询活动统计 - activityId: {}", activityId);
        Map<String, Object> statistics = inviteActivityService.getActivityStatistics(activityId);
        return Result.success("查询成功", statistics);
    }

    // ==================== 邀请记录管理 ====================

    /**
     * 分页查询邀请记录列表
     *
     * @param queryDTO 查询条件（包含分页参数）
     * @return 分页结果
     */
    @RequirePermission("marketing:invite:read")
    @GetMapping("/records")
    public Result<PageResult<InviteRecord>> getRecords(InviteRecordQueryDTO queryDTO) {
        queryDTO.validate();
        log.info("[邀请活动] 分页查询邀请记录 - page: {}, pageSize: {}, activityId: {}, status: {}",
                queryDTO.getPage(), queryDTO.getPageSize(), queryDTO.getActivityId(), queryDTO.getStatus());
        IPage<InviteRecord> page = inviteActivityService.getInviteRecords(queryDTO);
        return Result.success("查询成功", PageResult.of(page));
    }

    /**
     * 导出邀请记录Excel
     *
     * @param queryDTO 查询条件
     * @param response HTTP响应
     */
    @RequirePermission("marketing:invite:export")
    @Log(module = "邀请活动", operation = OperationType.EXPORT, summary = "导出邀请记录")
    @GetMapping("/records/export")
    public void exportRecords(InviteRecordQueryDTO queryDTO, HttpServletResponse response) {
        log.info("[邀请活动] 导出邀请记录 - activityId: {}, status: {}", queryDTO.getActivityId(), queryDTO.getStatus());
        // TODO: 实现Excel导出逻辑
        // 1. 设置响应头：Content-Type=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
        // 2. 设置文件名：UTF-8编码的 attachment;filename*=UTF-8''xxx.xlsx
        // 3. 查询全量数据（不分页）
        // 4. 使用EasyExcel写入响应输出流
    }

    // ==================== 奖励管理 ====================

    /**
     * 手动补发失败的奖励
     * 管理员操作，用于处理发放失败的奖励记录
     *
     * @param rewardId 奖励记录ID
     * @return 操作结果
     */
    @RequirePermission("marketing:invite:edit")
    @Log(module = "邀请活动", operation = OperationType.UPDATE, summary = "手动补发邀请奖励")
    @PostMapping("/reward/manual-reissue")
    public Result<Void> manualReissueReward(@RequestParam Long rewardId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = (String) StpUtil.getSession().get("name");
        log.info("[邀请活动] 手动补发奖励 - rewardId: {}, operatorId: {}, operatorName: {}",
                rewardId, operatorId, operatorName);
        boolean success = inviteActivityService.manualReissueReward(rewardId, operatorId, operatorName);
        if (!success) {
            return Result.error("补发失败，请检查奖励记录状态");
        }
        return Result.success("补发成功", null);
    }
}
