package com.jeesharp.business.modules.member.controller;

import cn.hutool.core.util.StrUtil;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.jeesharp.business.modules.member.application.MemberApplicationService;
import com.jeesharp.business.modules.member.application.MemberPointsLogManageApplicationService;
import com.jeesharp.business.modules.member.dto.MemberSaveDTO;
import com.jeesharp.business.modules.member.entity.Member;
import com.jeesharp.business.modules.member.entity.MemberPointsLog;
import com.jeesharp.business.modules.member.vo.MemberExportVO;
import com.jeesharp.business.modules.member.vo.MemberImportVO;
import com.jeesharp.business.modules.member.vo.MemberInfoVO;
import com.jeesharp.business.modules.member.vo.MemberListVO;
import com.jeesharp.business.modules.member.vo.MemberPointsLogListVO;
import com.jeesharp.business.modules.member.vo.MemberPointsLogQueryVO;
import com.jeesharp.business.modules.member.vo.MemberQueryVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.office.excel.util.ExcelExportUtil;
import com.jeesharp.framework.office.excel.util.ExcelImportUtil;
import com.jeesharp.framework.pojo.AjaxResult;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import com.jeesharp.framework.pojo.vo.ImportRespVO;
import com.jeesharp.framework.web.controller.BaseController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 会员管理 Controller
 *
 * @author jeesharp
 * @version 2024-01-24
 */
@RestController
@RequestMapping(value = "${jeesharp.web.adminPath}/member/member/v1")
@Tag(name = "会员管理", description = "会员管理相关接口，包括会员的增删改查、积分管理等功能")
@AllArgsConstructor
public class MemberController extends BaseController {

    private final MemberApplicationService memberApplicationService;
    private final MemberPointsLogManageApplicationService memberPointsLogManageApplicationService;

    // ==================== 基础 CRUD ====================

    /**
     * 获取成长等级下拉选项
     */
    @ApiOperationSupport(order = 0)
    @Operation(summary = "0、获取成长等级选项", description = "消费成长档下拉，用于筛选与表单")
    @GetMapping(value = "levelOptions")
    public AjaxResult<List<Map<String, String>>> levelOptions() {
        return AjaxResult.okData(memberApplicationService.getGrowthLevelOptions());
    }

    /**
     * 获取付费等级下拉选项
     */
    @ApiOperationSupport(order = 1)
    @Operation(summary = "1、获取付费等级选项", description = "付费开通档下拉，用于筛选")
    @GetMapping(value = "vipLevelOptions")
    public AjaxResult<List<Map<String, String>>> vipLevelOptions() {
        return AjaxResult.okData(memberApplicationService.getVipLevelOptions());
    }

    @PreAuthorize("@ss.hasPermission('member:member:info')")
    @GetMapping(value = "info")
    public AjaxResult<MemberInfoVO> info(
            @Parameter(description = "会员ID", required = true)
            @RequestParam("id") String id) {
        return AjaxResult.okData(memberApplicationService.getMember(id));
    }

    /**
     * 获取会员列表（分页）
     */
    @ApiOperationSupport(order = 2)
    @Operation(summary = "2、获取会员列表", description = "分页查询会员列表，支持多条件筛选")
    @PreAuthorize("@ss.hasPermission('member:member:list')")
    @PostMapping(value = "list")
    public AjaxResult<PageRespVO<MemberListVO>> list(@RequestBody MemberQueryVO query) {
        Page<Member> page = new Page<>(query);
        return AjaxResult.okData(memberApplicationService.findPage(page, query));
    }

    /**
     * 保存会员
     */
    @ApiOperationSupport(order = 3)
    @Operation(summary = "3、保存会员", description = "新增或更新会员信息，ID为空时新增，否则更新")
    @PreAuthorize("@ss.hasPermission('member:member:save')")
    @PostMapping(value = "save")
    public AjaxResult<Void> save(@RequestBody @Valid MemberSaveDTO dto) {
        memberApplicationService.saveData(dto);
        return AjaxResult.ok("保存成功");
    }

    /**
     * 删除会员
     */
    @ApiOperationSupport(order = 4)
    @Operation(summary = "4、删除会员", description = "批量删除会员，多个ID用逗号分隔")
    @PreAuthorize("@ss.hasPermission('member:member:delete')")
    @GetMapping(value = "delete")
    public AjaxResult<Void> delete(
            @Parameter(description = "会员ID，多个用逗号分隔", required = true)
            @RequestParam("ids") String ids) {
        memberApplicationService.delete(ids);
        return AjaxResult.ok("删除成功");
    }

    // ==================== 导入导出 ====================

    /**
     * 导出会员数据
     */
    @ApiOperationSupport(order = 5)
    @Operation(summary = "5、导出会员数据", description = "根据查询条件导出会员数据到Excel")
    @PreAuthorize("@ss.hasPermission('member:member:export')")
    @PostMapping(value = "export")
    public void export(@RequestBody MemberQueryVO query, HttpServletResponse response) {
//        List<MemberExportVO> list = memberApplicationService.findExportList(query);
//        ExcelExportUtil.export(response, MemberExportVO.class, list, "会员数据");
    }

    /**
     * 导入会员数据
     */
    @ApiOperationSupport(order = 6)
    @Operation(summary = "6、导入会员数据", description = "从Excel导入会员数据")
    @PreAuthorize("@ss.hasPermission('member:member:import')")
    @PostMapping(value = "import")
    public AjaxResult<ImportRespVO> importData(@RequestParam("file") MultipartFile file) throws IOException {
        List<MemberImportVO> list = ExcelImportUtil.read(file, MemberImportVO.class);
        return AjaxResult.ok("导入成功", memberApplicationService.importData(list));
    }

    /**
     * 下载导入模板
     */
    @ApiOperationSupport(order = 7)
    @Operation(summary = "7、下载导入模板", description = "下载会员导入Excel模板")
    @GetMapping(value = "import/template")
    public void importTemplate(HttpServletResponse response) {
        ExcelExportUtil.export(response, MemberImportVO.class, new ArrayList<>(), "会员导入模板");
    }

    // ==================== 会员状态管理 ====================

    /**
     * 禁用会员
     */
    @ApiOperationSupport(order = 8)
    @Operation(summary = "8、禁用会员", description = "禁用指定会员账号")
    @PreAuthorize("@ss.hasPermission('member:member:disable')")
    @GetMapping(value = "disable")
    public AjaxResult<Void> disable(
            @Parameter(description = "会员ID", required = true)
            @RequestParam("id") String id) {
        memberApplicationService.disable(id);
        return AjaxResult.ok("禁用成功");
    }

    /**
     * 启用会员
     */
    @ApiOperationSupport(order = 9)
    @Operation(summary = "9、启用会员", description = "启用指定会员账号")
    @PreAuthorize("@ss.hasPermission('member:member:enable')")
    @GetMapping(value = "enable")
    public AjaxResult<Void> enable(
            @Parameter(description = "会员ID", required = true)
            @RequestParam("id") String id) {
        memberApplicationService.enable(id);
        return AjaxResult.ok("启用成功");
    }

    // ==================== 积分管理 ====================

    /**
     * 会员积分明细分页（管理端档案操作列，数据源为 app_member_points_log）
     */
    @ApiOperationSupport(order = 9)
    @Operation(summary = "9、会员积分明细", description = "按会员分页查询积分变动流水（app_member_points_log）")
    @PreAuthorize("@ss.hasPermission('member:member:list')")
    @PostMapping(value = "pointsDetail/list")
    public AjaxResult<PageRespVO<MemberPointsLogListVO>> pointsDetailList(
            @RequestBody MemberPointsLogQueryVO query) {
        if (StrUtil.isBlank(query.getMemberId())) {
            throw new BizErrorException("会员ID不能为空");
        }
        Page<MemberPointsLog> page = new Page<>(query);
        return AjaxResult.okData(memberPointsLogManageApplicationService.findPage(page, query));
    }

    /**
     * 增加积分
     */
    @ApiOperationSupport(order = 10)
    @Operation(summary = "10、增加积分", description = "为会员增加积分")
    @PreAuthorize("@ss.hasPermission('member:member:adjustPoints')")
    @PostMapping(value = "addPoints")
    public AjaxResult<Void> addPoints(
            @Parameter(description = "会员ID", required = true)
            @RequestParam("memberId") String memberId,
            @Parameter(description = "积分数量", required = true)
            @RequestParam("points") Integer points,
            @Parameter(description = "业务描述")
            @RequestParam(value = "bizDesc", required = false) String bizDesc) {
        memberApplicationService.addPoints(memberId, points, "MANUAL", null, bizDesc);
        return AjaxResult.ok("积分增加成功");
    }

    /**
     * 扣减积分
     */
    @ApiOperationSupport(order = 11)
    @Operation(summary = "11、扣减积分", description = "扣减会员积分")
    @PreAuthorize("@ss.hasPermission('member:member:adjustPoints')")
    @PostMapping(value = "deductPoints")
    public AjaxResult<Void> deductPoints(
            @Parameter(description = "会员ID", required = true)
            @RequestParam("memberId") String memberId,
            @Parameter(description = "积分数量", required = true)
            @RequestParam("points") Integer points,
            @Parameter(description = "业务描述")
            @RequestParam(value = "bizDesc", required = false) String bizDesc) {
        memberApplicationService.deductPoints(memberId, points, "MANUAL", null, bizDesc);
        return AjaxResult.ok("积分扣减成功");
    }

    // ==================== 成长值管理 ====================

    /**
     * 增加成长值
     */
    @ApiOperationSupport(order = 12)
    @Operation(summary = "12、增加成长值", description = "为会员增加成长值")
    @PreAuthorize("@ss.hasPermission('member:member:growth')")
    @PostMapping(value = "addGrowthValue")
    public AjaxResult<Void> addGrowthValue(
            @Parameter(description = "会员ID", required = true)
            @RequestParam("memberId") String memberId,
            @Parameter(description = "成长值", required = true)
            @RequestParam("growthValue") Integer growthValue,
            @Parameter(description = "业务描述")
            @RequestParam(value = "bizDesc", required = false) String bizDesc) {
        memberApplicationService.addGrowthValue(memberId, growthValue, "MANUAL", bizDesc);
        return AjaxResult.ok("成长值增加成功");
    }
}
