package com.xy.xyaicpzs.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xy.xyaicpzs.common.ErrorCode;
import com.xy.xyaicpzs.common.ResultUtils;
import com.xy.xyaicpzs.common.requset.GenerateVipCodesRequest;
import com.xy.xyaicpzs.common.requset.VipCodeQueryRequest;
import com.xy.xyaicpzs.common.response.ApiResponse;
import com.xy.xyaicpzs.domain.entity.User;
import com.xy.xyaicpzs.domain.entity.VipCode;
import com.xy.xyaicpzs.domain.vo.VipCodeVO;
import com.xy.xyaicpzs.exception.BusinessException;
import com.xy.xyaicpzs.service.OperationHistoryService;
import com.xy.xyaicpzs.service.UserService;
import com.xy.xyaicpzs.service.VipCodeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 会员码管理接口
 */
@Slf4j
@RestController
@RequestMapping("/vip-code")
@Tag(name = "会员码管理", description = "会员码管理相关接口")
public class VipCodeController {

    @Resource
    private VipCodeService vipCodeService;

    @Autowired
    private UserService userService;
    
    @Autowired
    private OperationHistoryService operationHistoryService;

    /**
     * 批量生成会员码
     *
     * @param request 生成会员码请求
     * @return 生成成功的数量
     */
    @PostMapping("/generate")
    @Operation(summary = "批量生成会员码", description = "管理员批量生成会员码")
    public ApiResponse<Integer> generateVipCodes(@RequestBody GenerateVipCodesRequest request,
                                                 HttpServletRequest httpServletRequest) {

        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)){
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }
        Long userId = loginUser.getId();
        String userName = loginUser.getUserName();

        if (request == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }
        if (request.getNumCodes() == null || request.getNumCodes() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "生成数量必须大于0");
        }
        if (request.getVipExpireTime() == null || request.getVipExpireTime() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数必须大于0");
        }
        if (request.getNumCodes() > 1000) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "单次生成数量不能超过1000");
        }
        
        try {
            int result = vipCodeService.generateVipCodes(request.getNumCodes(), request.getVipExpireTime(), userId, userName);
            
            // 记录操作历史 - 成功
            String resultMessage = String.format("%s成功生成%d个会员码，有效月数：%d", userName, result, request.getVipExpireTime());
            operationHistoryService.recordOperation(userId, "批量生成会员码", 0, "成功", resultMessage);
            
            return ResultUtils.success(result);
        } catch (IllegalArgumentException e) {
            log.error("生成会员码参数错误：{}", e.getMessage());
            
            // 记录操作历史 - 失败
            String resultMessage = String.format("%s生成会员码失败：%s，请求数量：%d，有效月数：%d", 
                                                userName, e.getMessage(), request.getNumCodes(), request.getVipExpireTime());
            operationHistoryService.recordOperation(userId, "批量生成会员码", 0, "失败", resultMessage);
            
            throw new BusinessException(ErrorCode.PARAMS_ERROR, e.getMessage());
        } catch (RuntimeException e) {
            log.error("生成会员码系统错误：{}", e.getMessage());
            
            // 记录操作历史 - 失败
            String resultMessage = String.format("%s生成会员码系统错误：%s，请求数量：%d，有效月数：%d", 
                                                userName, e.getMessage(), request.getNumCodes(), request.getVipExpireTime());
            operationHistoryService.recordOperation(userId, "批量生成会员码", 0, "失败", resultMessage);
            
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "生成会员码失败，请稍后重试");
        }
    }

    /**
     * 获取一个可用的会员码
     *
     * @param vipExpireTime 会员有效月数
     * @return 可用的会员码
     */
    @GetMapping("/available")
    @Operation(summary = "获取可用会员码", description = "根据有效月数获取一个可用的会员码")
    public ApiResponse<String> getAvailableVipCode(@RequestParam("vipExpireTime") Integer vipExpireTime,
                                                   HttpServletRequest httpServletRequest) {

        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)){
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }
        Long userId = loginUser.getId();
        String userName = loginUser.getUserName();

        if (vipExpireTime == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数不能为空");
        }
        if (vipExpireTime <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数必须大于0");
        }
        
        try {
            String code = vipCodeService.getAvailableVipCode(vipExpireTime, userId, userName);
            if (code == null) {
                // 记录操作历史 - 失败
                String resultMessage = String.format("%s获取可用会员码失败：没有找到可用的会员码，有效月数：%d", userName, vipExpireTime);
                operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "失败", resultMessage);
                
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有找到可用的会员码");
            }
            
            // 记录操作历史 - 成功
            String resultMessage = String.format("%s成功获取可用会员码：%s，有效月数：%d", userName, code, vipExpireTime);
            operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "成功", resultMessage);
            
            return ResultUtils.success(code);
        } catch (IllegalArgumentException e) {
            log.error("获取可用会员码参数错误：{}", e.getMessage());
            
            // 记录操作历史 - 失败
            String resultMessage = String.format("%s获取可用会员码参数错误：%s，有效月数：%d", userName, e.getMessage(), vipExpireTime);
            operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "失败", resultMessage);
            
            throw new BusinessException(ErrorCode.PARAMS_ERROR, e.getMessage());
        } catch (Exception e) {
            log.error("获取可用会员码系统错误：{}", e.getMessage());
            
            // 记录操作历史 - 失败
            String resultMessage = String.format("%s获取可用会员码系统错误：%s，有效月数：%d", userName, e.getMessage(), vipExpireTime);
            operationHistoryService.recordOperation(userId, "获取可用会员码", 0, "失败", resultMessage);
            
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取可用会员码失败，请生成后获取。");
        }
    }

    /**
     * 分页获取会员码列表
     *
     * @param vipCodeQueryRequest 会员码查询请求
     * @param httpServletRequest Http请求
     * @return 分页会员码列表
     */
    @GetMapping("/list/page")
    @Operation(summary = "分页获取会员码列表", description = "分页获取会员码列表，支持根据会员码、使用状态和时间筛选")
    public ApiResponse<Page<VipCodeVO>> listVipCodesByPage(VipCodeQueryRequest vipCodeQueryRequest,
                                                           HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)){
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }
        
        if (vipCodeQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }
        
        long current = vipCodeQueryRequest.getCurrent();
        long pageSize = vipCodeQueryRequest.getPageSize();
        
        // 构建查询条件
        QueryWrapper<VipCode> queryWrapper = new QueryWrapper<>();
        
        // 根据会员码模糊查询
        if (StringUtils.isNotBlank(vipCodeQueryRequest.getCode())) {
            queryWrapper.like("code", vipCodeQueryRequest.getCode());
        }
        
        // 根据使用状态筛选
        if (vipCodeQueryRequest.getIsUse() != null) {
            queryWrapper.eq("isUse", vipCodeQueryRequest.getIsUse());
        }
        
        // 根据会员有效月数筛选
        if (vipCodeQueryRequest.getVipExpireTime() != null) {
            queryWrapper.eq("vipExpireTime", vipCodeQueryRequest.getVipExpireTime());
        }
        
        // 根据创建人ID筛选
        if (vipCodeQueryRequest.getCreatedUserId() != null) {
            queryWrapper.eq("createdUserId", vipCodeQueryRequest.getCreatedUserId());
        }
        
        // 根据创建人名称模糊查询
        if (StringUtils.isNotBlank(vipCodeQueryRequest.getCreatedUserName())) {
            queryWrapper.like("createdUserName", vipCodeQueryRequest.getCreatedUserName());
        }
        
        // 根据使用人ID筛选
        if (vipCodeQueryRequest.getUsedUserId() != null) {
            queryWrapper.eq("usedUserId", vipCodeQueryRequest.getUsedUserId());
        }
        
        // 根据创建时间范围筛选
        if (vipCodeQueryRequest.getStartTime() != null && vipCodeQueryRequest.getEndTime() != null) {
            queryWrapper.between("createTime", vipCodeQueryRequest.getStartTime(), vipCodeQueryRequest.getEndTime());
        } else if (vipCodeQueryRequest.getStartTime() != null) {
            queryWrapper.ge("createTime", vipCodeQueryRequest.getStartTime());
        } else if (vipCodeQueryRequest.getEndTime() != null) {
            queryWrapper.le("createTime", vipCodeQueryRequest.getEndTime());
        }
        
        // 按会员编号升序排序（从小到大）
        queryWrapper.orderByAsc("vipNumber");
        
        // 执行分页查询
        Page<VipCode> vipCodePage = vipCodeService.page(new Page<>(current, pageSize), queryWrapper);
        
        // 转换为VO对象
        List<VipCodeVO> vipCodeVOList = vipCodePage.getRecords().stream().map(vipCode -> {
            VipCodeVO vipCodeVO = new VipCodeVO();
            BeanUtils.copyProperties(vipCode, vipCodeVO);
            return vipCodeVO;
        }).collect(Collectors.toList());
        
        // 创建VO分页对象，确保正确传递所有分页信息
        Page<VipCodeVO> vipCodeVOPage = new Page<>(vipCodePage.getCurrent(), vipCodePage.getSize(), vipCodePage.getTotal());
        vipCodeVOPage.setRecords(vipCodeVOList);
        // 手动设置pages值
        vipCodeVOPage.setPages(vipCodePage.getPages());
        
        return ResultUtils.success(vipCodeVOPage);
    }

    /**
     * 获取会员码统计数量
     *
     * @param httpServletRequest Http请求
     * @return 会员码统计数量
     */
    @GetMapping("/count")
    @Operation(summary = "获取会员码统计数量", description = "获取系统中会员码总数、可用会员码和已使用会员码的数量")
    public ApiResponse<Map<String, Long>> getVipCodeCount(HttpServletRequest httpServletRequest) {
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)){
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }
        
        try {
            // 构建查询条件 - 总数
            long totalCount = vipCodeService.count();
            
            // 构建查询条件 - 已使用的会员码
            QueryWrapper<VipCode> usedQueryWrapper = new QueryWrapper<>();
            usedQueryWrapper.eq("isUse", 1);
            long usedCount = vipCodeService.count(usedQueryWrapper);
            
            // 构建查询条件 - 可用的会员码
            QueryWrapper<VipCode> availableQueryWrapper = new QueryWrapper<>();
            availableQueryWrapper.eq("isUse", 0);
            long availableCount = vipCodeService.count(availableQueryWrapper);
            
            // 构造返回结果
            Map<String, Long> countMap = new HashMap<>();
            countMap.put("totalCount", totalCount);
            countMap.put("availableCount", availableCount);
            countMap.put("usedCount", usedCount);
            
            return ResultUtils.success(countMap);
        } catch (Exception e) {
            log.error("获取会员码统计数量失败：{}", e.getMessage());
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取会员码统计数量失败，请稍后重试");
        }
    }

    /**
     * 根据月份获取已使用的会员码（分页）
     *
     * @param vipExpireTime 会员有效月数
     * @param current 当前页码，默认为1
     * @param pageSize 每页大小，默认为10
     * @param httpServletRequest Http请求
     * @return 分页的已使用会员码列表
     */
    @GetMapping("/used/by-month")
    @Operation(summary = "根据月份获取已使用的会员码", description = "根据会员有效月数查询已使用的会员码，支持分页")
    public ApiResponse<Page<VipCodeVO>> getUsedVipCodesByMonth(
            @Parameter(description = "会员有效月数", required = true)
            @RequestParam("vipExpireTime") Integer vipExpireTime,
            @Parameter(description = "当前页码，默认为1", required = false)
            @RequestParam(value = "current", defaultValue = "1") Long current,
            @Parameter(description = "每页大小，默认为10", required = false)
            @RequestParam(value = "pageSize", defaultValue = "10") Long pageSize,
            HttpServletRequest httpServletRequest) {
        
        // 权限校验
        User loginUser = userService.getLoginUser(httpServletRequest);
        if (!userService.isAdmin(loginUser)){
            return ResultUtils.error(ErrorCode.NOT_LOGIN_ERROR, "无权限");
        }
        
        // 参数校验
        if (vipExpireTime == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数不能为空");
        }
        if (vipExpireTime <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "会员有效月数必须大于0");
        }
        if (current <= 0) {
            current = 1L;
        }
        if (pageSize <= 0) {
            pageSize = 10L;
        }
        
        try {
            // 构建查询条件：已使用且指定月份
            QueryWrapper<VipCode> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("isUse", 1)  // 已使用
                       .eq("vipExpireTime", vipExpireTime);  // 指定月份
            
            // 按使用时间倒序排序（最近使用的在前）
            queryWrapper.orderByDesc("updateTime");
            
            // 执行分页查询
            Page<VipCode> vipCodePage = vipCodeService.page(new Page<>(current, pageSize), queryWrapper);
            
            // 转换为VO对象
            List<VipCodeVO> vipCodeVOList = vipCodePage.getRecords().stream().map(vipCode -> {
                VipCodeVO vipCodeVO = new VipCodeVO();
                BeanUtils.copyProperties(vipCode, vipCodeVO);
                return vipCodeVO;
            }).collect(Collectors.toList());
            
            // 创建VO分页对象，确保正确传递所有分页信息
            Page<VipCodeVO> vipCodeVOPage = new Page<>(vipCodePage.getCurrent(), vipCodePage.getSize(), vipCodePage.getTotal());
            vipCodeVOPage.setRecords(vipCodeVOList);
            // 手动设置pages值
            vipCodeVOPage.setPages(vipCodePage.getPages());
            
            log.info("根据月份获取已使用的会员码完成，月份：{}，页码：{}，每页大小：{}，返回{}条记录", 
                    vipExpireTime, current, pageSize, vipCodeVOList.size());
            return ResultUtils.success(vipCodeVOPage);
            
        } catch (Exception e) {
            log.error("根据月份获取已使用的会员码失败：{}", e.getMessage(), e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取已使用的会员码失败：" + e.getMessage());
        }
    }
} 