package com.mosquito.project.controller;

import com.mosquito.project.dto.ApiResponse;
import com.mosquito.project.permission.ApprovalFlowService;
import com.mosquito.project.permission.PermissionCheckService;
import com.mosquito.project.permission.RequirePermission;
import com.mosquito.project.service.RewardService;
import com.mosquito.project.web.PermissionInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

/**
 * 奖励管理控制器
 */
@RestController
@RequestMapping("/api/v1/rewards/admin")
public class RewardController {

    private final RewardService rewardService;
    private final PermissionCheckService permissionCheckService;
    private final ApprovalFlowService approvalFlowService;

    public RewardController(RewardService rewardService,
                           PermissionCheckService permissionCheckService,
                           ApprovalFlowService approvalFlowService) {
        this.rewardService = rewardService;
        this.permissionCheckService = permissionCheckService;
        this.approvalFlowService = approvalFlowService;
    }

    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        Object userIdObj = request.getAttribute("userId");
        if (userIdObj instanceof Long) {
            return (Long) userIdObj;
        } else if (userIdObj instanceof Integer) {
            return ((Integer) userIdObj).longValue();
        }
        return null;
    }

    /**
     * 获取奖励列表（带数据权限）
     */
    @GetMapping
    @RequirePermission("reward.index.view.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getRewards(
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer size,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String rewardType,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);
        Map<String, Object> data = rewardService.getRewards(page, size, status, rewardType, currentUserId);
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    /**
     * 获取单个奖励详情
     */
    @GetMapping("/{id}")
    @RequirePermission("reward.index.view.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getRewardById(@PathVariable Long id) {
        Map<String, Object> data = rewardService.getRewardById(id);
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    /**
     * 申请奖励
     */
    @PostMapping("/apply")
    @RequirePermission("reward.index.apply.ALL")
    public ResponseEntity<ApiResponse<Long>> applyReward(@RequestBody Map<String, Object> request) {
        Long id = rewardService.applyReward(request);
        return ResponseEntity.ok(ApiResponse.success(id, "奖励申请已提交"));
    }

    /**
     * 审批奖励
     */
    @PostMapping("/{id}/approve")
    @RequirePermission("reward.index.approve.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> approveReward(
            @PathVariable Long id,
            @RequestBody Map<String, Object> request,
            HttpServletRequest httpRequest) {

        // 从登录态获取操作者ID，禁止从请求体中获取以防止伪造
        Long currentUserId = getCurrentUserId(httpRequest);
        Map<String, Object> result = rewardService.approveReward(id, request, currentUserId);
        if (Boolean.TRUE.equals(result.get("success"))) {
            String message = (String) result.get("message");
            return ResponseEntity.ok(ApiResponse.success(result, message));
        }
        return ResponseEntity.ok(ApiResponse.error(400, (String) result.getOrDefault("message", "审批失败")));
    }

    /**
     * 拒绝奖励
     * 使用独立的 reward.index.reject.ALL 权限
     */
    @PostMapping("/{id}/reject")
    @RequirePermission("reward.index.reject.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> rejectReward(
            @PathVariable Long id,
            @RequestBody Map<String, Object> request,
            HttpServletRequest httpRequest) {

        // 从登录态获取操作者ID，禁止从请求体中获取以防止伪造
        Long currentUserId = getCurrentUserId(httpRequest);
        Map<String, Object> result = rewardService.rejectReward(id, request, currentUserId);
        if (Boolean.TRUE.equals(result.get("success"))) {
            String message = (String) result.get("message");
            return ResponseEntity.ok(ApiResponse.success(result, message));
        }
        return ResponseEntity.ok(ApiResponse.error(400, (String) result.getOrDefault("message", "拒绝失败")));
    }

    /**
     * 发放奖励
     */
    @PostMapping("/{id}/grant")
    @RequirePermission("reward.index.grant.ALL")
    public ResponseEntity<ApiResponse<Void>> grantReward(@PathVariable Long id) {
        boolean success = rewardService.grantReward(id);
        if (success) {
            return ResponseEntity.ok(ApiResponse.success(null, "奖励发放成功"));
        }
        return ResponseEntity.ok(ApiResponse.error(400, "奖励发放失败"));
    }

    /**
     * 批量发放奖励
     */
    @SuppressWarnings("unchecked")
    @PostMapping("/batch-grant")
    @RequirePermission("reward.index.batch.ALL")
    public ResponseEntity<ApiResponse<Integer>> batchGrantRewards(@RequestBody Map<String, Object> request) {
        List<Long> ids = (List<Long>) request.get("ids");
        int count = rewardService.batchGrantRewards(ids);
        return ResponseEntity.ok(ApiResponse.success(count, "批量发放成功"));
    }

    /**
     * 取消奖励
     */
    @PostMapping("/{id}/cancel")
    @RequirePermission("reward.index.cancel.ALL")
    public ResponseEntity<ApiResponse<Void>> cancelReward(
            @PathVariable Long id,
            @RequestBody Map<String, String> request) {

        String reason = request.get("reason");
        boolean success = rewardService.cancelReward(id, reason);
        if (success) {
            return ResponseEntity.ok(ApiResponse.success(null, "奖励已取消"));
        }
        return ResponseEntity.ok(ApiResponse.error(400, "取消失败"));
    }

    /**
     * 获取待审批奖励数量
     */
    @GetMapping("/pending-count")
    @RequirePermission("reward.index.view.ALL")
    public ResponseEntity<ApiResponse<Long>> getPendingCount() {
        long count = rewardService.getPendingCount();
        return ResponseEntity.ok(ApiResponse.success(count));
    }

    /**
     * 奖励对账
     */
    @GetMapping("/reconcile")
    @RequirePermission("reward.index.reconcile.ALL")
    public ResponseEntity<ApiResponse<Map<String, Object>>> reconcile(
            @RequestParam String startDate,
            @RequestParam String endDate) {

        Map<String, Object> result = rewardService.reconcile(startDate, endDate);
        return ResponseEntity.ok(ApiResponse.success(result));
    }

    /**
     * 导出奖励列表（后端流式导出）
     * PRD要求: 敏感数据导出需要审批门禁（24小时有效期）
     */
    @GetMapping("/export")
    @RequirePermission("reward.index.export.ALL")
    public ResponseEntity<byte[]> exportRewards(
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String rewardType,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            HttpServletRequest request) {

        Long currentUserId = getCurrentUserId(request);

        // 检查是否有已批准的敏感导出审批记录
        boolean hasApprovedExport = false;
        if (approvalFlowService != null && currentUserId != null) {
            try {
                hasApprovedExport = approvalFlowService.hasApprovedExport(currentUserId);
            } catch (Exception e) {
                // 审批服务异常，拒绝导出
                return ResponseEntity.status(HttpStatus.CONFLICT).build();
            }
        }

        if (!hasApprovedExport) {
            // 无审批记录或审批未通过，拒绝导出
            return ResponseEntity.status(HttpStatus.CONFLICT).build();
        }

        byte[] csvData = rewardService.exportRewards(status, rewardType, startDate, endDate, currentUserId);

        return ResponseEntity.ok()
                .header("Content-Type", "text/csv;charset=UTF-8")
                .header("Content-Disposition", "attachment; filename=rewards_export.csv")
                .body(csvData);
    }
}
