package com.microservices.zone.member.controller;

import com.microservices.common.core.domain.R;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.domain.GenericsAjaxResult;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.common.security.annotation.RequiresPermissions;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.zone.member.domain.points.ZonePointsAccount;
import com.microservices.zone.member.domain.vo.*;
import com.microservices.zone.member.service.IZonePointsAccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 专区积分账户Controller
 *
 * @author otto
 */
@RestController
@RequestMapping("/points/account")
@Api(tags = "专区积分账户接口")
public class ZonePointsAccountController extends BaseController {
    @Autowired
    private IZonePointsAccountService zonePointsAccountService;

    /**
     * 查询专区积分账户列表
     */
    @RequiresPermissions("zone:points:account:list")
    @GetMapping("/list")
    @ApiOperation("查询专区积分账户列表")
    public GenericsTableDataInfo<ZonePointsAccount> list(ZonePointsAccountSearchVo searchVo) {
        startPage();
        List<ZonePointsAccount> list = zonePointsAccountService.selectZonePointsAccountList(searchVo.toZonePointsAccount());
        return getGenericsDataTable(list);
    }

    /**
     * 获取专区积分账户详细信息
     */
    @RequiresPermissions("zone:points:account:query")
    @GetMapping(value = "/{id}")
    @ApiOperation(value = "获取专区积分账户详细信息")
    public GenericsAjaxResult<ZonePointsAccount> getInfo(@PathVariable("id") Long id) {
        return genericsSuccess(zonePointsAccountService.selectZonePointsAccountById(id));
    }

    /**
     * 新增专区积分账户
     */
    @RequiresPermissions("zone:points:account:add")
    @Log(title = "专区积分账户", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation(value = "新增专区积分账户")
    public AjaxResult add(@RequestBody ZonePointsAccountInputVo inputVo) {
        return toAjax(zonePointsAccountService.insertZonePointsAccount(inputVo));
    }

    /**
     * 修改专区积分账户
     */
    @RequiresPermissions("zone:points:account:edit")
    @Log(title = "专区积分账户", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation(value = "修改专区积分账户")
    public AjaxResult edit(@RequestBody ZonePointsAccountUpdateVo updateVo) {
        return toAjax(zonePointsAccountService.updateZonePointsAccount(updateVo));
    }

    /**
     * 删除专区积分账户
     */
    @RequiresPermissions("zone:points:account:remove")
    @Log(title = "专区积分账户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation(value = "删除专区积分账户")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(zonePointsAccountService.deleteZonePointsAccountByIds(ids));
    }

    /**
     * 根据用户ID和专区ID查询积分账户
     */
    @RequiresPermissions("zone:points:account:query")
    @GetMapping("/user/{userId}/zone/{zoneId}")
    @ApiOperation(value = "根据用户ID和专区ID查询积分账户")
    public GenericsAjaxResult<ZonePointsAccount> getByUserIdAndZoneId(@PathVariable("userId") Long userId,
                                                                        @PathVariable("zoneId") Long zoneId) {
        return genericsSuccess(zonePointsAccountService.selectZonePointsAccountByUserIdAndZoneId(userId, zoneId));
    }

        /**
     * 根据会员ID查询积分账户列表
     */
    @RequiresPermissions("zone:points:account:query")
    @GetMapping("/member/{memberId}")
    @ApiOperation(value = "根据会员ID查询积分账户列表")
    public GenericsAjaxResult<List<ZonePointsAccount>> getByMemberId(@PathVariable("memberId") Long memberId) {
        return genericsSuccess(zonePointsAccountService.selectZonePointsAccountByMemberId(memberId));
    }

    /**
     * 获取当前登录用户的积分账户总览信息
     */
    @GetMapping("/overview/{zoneId}")
    @ApiOperation(value = "获取当前登录用户的积分账户总览信息")
    public GenericsAjaxResult<ZonePointsOverviewVo> getCurrentUserPointsOverview(@PathVariable("zoneId") Long zoneId) {
        return genericsSuccess(zonePointsAccountService.getCurrentUserPointsOverview(zoneId));
    }

    /**
     * 电子证书积分扣减（前台用户操作，业务层已做会员身份+积分专区+幂等+积分校验）
     */
    @PostMapping("/certificate/redeem")
    @ApiOperation(value = "电子证书积分扣减")
    public AjaxResult redeemCertificate(@RequestBody ZonePointsTransactionInputVo inputVo) {
        zonePointsAccountService.deductPointsForCertificate(inputVo);
        return success();
    }

    /**
     * 文章置顶积分扣减（前台用户操作，业务层已做会员身份+积分专区+积分校验）
     * 用户使用当前登录用户
     */
    @PostMapping("/article/top")
    @ApiOperation(value = "文章置顶积分扣减")
    public AjaxResult topArticle(@RequestBody ZonePointsArticleTopInputVo inputVo) {
        zonePointsAccountService.deductPointsForArticleTop(inputVo.getZoneId(), inputVo.getId(), inputVo.getName());
        return success();
    }

    /**
     * 获取当前登录用户的置顶文章信息
     */
    @GetMapping("/article/top/{zoneId}")
    @ApiOperation(value = "获取当前登录用户的置顶文章信息")
    public GenericsAjaxResult<ZonePointsTopDocVo> getCurrentUserPointsTopDoc(@PathVariable("zoneId") Long zoneId) {
        return genericsSuccess(zonePointsAccountService.getCurrentUserPointsTopDoc(zoneId));
    }

    /**
     * 获取当前登录用户的置顶项目信息
     */
    @GetMapping("/project/top/{zoneId}")
    @ApiOperation(value = "获取当前登录用户的置顶项目信息")
    public GenericsAjaxResult<ZonePointsTopProjectVo> getZonePointsTopProject(@PathVariable("zoneId") Long zoneId) {
        return genericsSuccess(zonePointsAccountService.getZonePointsTopProject(zoneId));
    }

    /**
     * 项目置顶积分扣减（前台用户操作，业务层已做会员身份+积分专区+积分校验）
     * 用户使用当前登录用户
     */
    @PostMapping("/project/top")
    @ApiOperation(value = "项目置顶积分扣减")
    public AjaxResult topProject(@RequestBody ZonePointsProjectTopInputVo inputVo) {
        zonePointsAccountService.deductPointsForProjectTop(inputVo.getZoneId(), inputVo.getId(), inputVo.getName());
        return success();
    }

    /**
     * 线下活动积分冻结（前台用户操作，业务层已做会员身份+积分专区+幂等+积分校验）
     */
    @PostMapping("/offlineActivity/freeze")
    @ApiOperation(value = "线下活动积分冻结")
    public AjaxResult freezePointsForOfflineActivity(@RequestBody ZonePointsApplyInputVo inputVo) {
        zonePointsAccountService.freezePointsForOfflineActivity(inputVo);
        return success();
    }

    /**
     * 专家答疑积分冻结（前台用户操作，业务层已做会员身份+积分专区+幂等+积分校验）
     */
    @PostMapping("/expert/qa/freeze")
    @ApiOperation(value = "专家答疑积分冻结")
    public AjaxResult freezePointsForExpertQa(@RequestBody ZonePointsApplyInputVo inputVo) {
        zonePointsAccountService.freezePointsForExpertQa(inputVo);
        return success();
    }

    /**
     * 驳回积分申请（管理员操作）
     * 查询对应申请记录（pending状态），更新状态为fail，
     * 同时更新pointsEvent的subject括号内容为"已退回"、replyContent为驳回原因，
     * 并触发积分解冻操作
     */
    @RequiresPermissions("zone:points:account:reject")
    @Log(title = "驳回积分申请", businessType = BusinessType.UPDATE)
    @PostMapping("/apply/reject")
    @ApiOperation(value = "驳回积分申请")
    public AjaxResult rejectPointsApply(@RequestBody ZonePointsApplyInputVo inputVo) {
        zonePointsAccountService.rejectPointsApply(inputVo);
        return success();
    }

    /**
     * 通过积分申请（管理员操作）
     * 查询对应申请记录（pending状态），更新状态为success，
     * 同时更新pointsEvent的subject去除原括号内容，
     * 并从冻结积分中正式扣减积分（含总积分扣减）
     */
    @RequiresPermissions("zone:points:account:approve")
    @Log(title = "通过积分申请", businessType = BusinessType.UPDATE)
    @PostMapping("/apply/approve")
    @ApiOperation(value = "通过积分申请")
    public AjaxResult approvePointsApply(@RequestBody ZonePointsApplyInputVo inputVo) {
        zonePointsAccountService.approvePointsApply(inputVo);
        return success();
    }
}