package com.yaoai.api.controller.admin;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yaoai.api.dto.billing.BalanceDTO;
import com.yaoai.billing.service.BillingService;
import com.yaoai.common.exception.BizException;
import com.yaoai.common.exception.ErrorCode;
import com.yaoai.common.response.ApiResponse;
import com.yaoai.domain.entity.Tenant;
import com.yaoai.domain.entity.User;
import com.yaoai.domain.mapper.BillingRecordMapper;
import com.yaoai.domain.mapper.TenantMapper;
import com.yaoai.domain.mapper.UserMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Tag(name = "运营后台")
@RestController
@RequestMapping("/admin")
@RequiredArgsConstructor
public class AdminController {

    private final TenantMapper tenantMapper;
    private final UserMapper userMapper;
    private final BillingService billingService;
    private final BillingRecordMapper billingRecordMapper;

    // ---- Auth guard (inline, avoids AOP complexity) ----

    private void requireAdmin() {
        Long userId = StpUtil.getLoginIdAsLong();
        User user = userMapper.selectById(userId);
        if (user == null || !"admin".equals(user.getRole())) {
            throw new BizException(ErrorCode.FORBIDDEN, "需要管理员权限");
        }
    }

    // ---- Stats ----

    @Operation(summary = "系统概览统计")
    @GetMapping("/stats")
    public ApiResponse<Map<String, Object>> stats() {
        requireAdmin();
        long tenantCount = tenantMapper.selectCount(Wrappers.emptyWrapper());
        long userCount = userMapper.selectCount(
                Wrappers.<User>lambdaQuery().isNull(User::getDeletedAt));
        long billingCount = billingRecordMapper.selectCount(Wrappers.emptyWrapper());
        return ApiResponse.success(Map.of(
                "tenantCount", tenantCount,
                "userCount", userCount,
                "billingRecordCount", billingCount
        ));
    }

    // ---- Tenants ----

    @Operation(summary = "租户列表")
    @GetMapping("/tenants")
    public ApiResponse<List<Tenant>> listTenants(
            @RequestParam(defaultValue = "50") int limit,
            @RequestParam(defaultValue = "0") long offset) {
        requireAdmin();
        List<Tenant> tenants = tenantMapper.selectList(
                Wrappers.<Tenant>lambdaQuery()
                        .orderByDesc(Tenant::getId)
                        .last("LIMIT " + limit + " OFFSET " + offset));
        return ApiResponse.success(tenants);
    }

    @Operation(summary = "查询租户余额")
    @GetMapping("/tenants/{tenantId}/balance")
    public ApiResponse<BalanceDTO> getTenantBalance(@PathVariable Long tenantId) {
        requireAdmin();
        return ApiResponse.success(BalanceDTO.from(billingService.getBalance(tenantId)));
    }

    @Operation(summary = "给租户充值积分")
    @PostMapping("/tenants/{tenantId}/recharge")
    public ApiResponse<BalanceDTO> rechargeTenant(@PathVariable Long tenantId,
                                                   @RequestBody Map<String, Object> body) {
        requireAdmin();
        Object amountRaw = body.get("amount");
        if (amountRaw == null) throw new BizException(ErrorCode.INVALID_PARAM, "amount 必填");
        BigDecimal amount = new BigDecimal(amountRaw.toString());
        String refId = body.getOrDefault("refId", "ADMIN").toString();
        billingService.recharge(tenantId, amount, refId);
        return ApiResponse.success(BalanceDTO.from(billingService.getBalance(tenantId)));
    }

    // ---- Users ----

    @Operation(summary = "用户列表")
    @GetMapping("/users")
    public ApiResponse<Map<String, Object>> listUsers(
            @RequestParam(defaultValue = "50") int limit,
            @RequestParam(defaultValue = "0") long offset) {
        requireAdmin();
        List<User> users = userMapper.selectList(
                Wrappers.<User>lambdaQuery()
                        .isNull(User::getDeletedAt)
                        .orderByDesc(User::getId)
                        .last("LIMIT " + limit + " OFFSET " + offset));
        long total = userMapper.selectCount(Wrappers.<User>lambdaQuery().isNull(User::getDeletedAt));
        // strip password hash
        users.forEach(u -> u.setPasswordHash(null));
        return ApiResponse.success(Map.of("total", total, "items", users));
    }

    // ---- Billing records ----

    @Operation(summary = "全平台计费记录")
    @GetMapping("/billing")
    public ApiResponse<Map<String, Object>> listBilling(
            @RequestParam(defaultValue = "50") int limit,
            @RequestParam(defaultValue = "0") long offset) {
        requireAdmin();
        var records = billingRecordMapper.selectList(
                Wrappers.lambdaQuery(com.yaoai.domain.entity.BillingRecord.class)
                        .orderByDesc(com.yaoai.domain.entity.BillingRecord::getCreatedAt)
                        .last("LIMIT " + limit + " OFFSET " + offset));
        long total = billingRecordMapper.selectCount(Wrappers.emptyWrapper());
        return ApiResponse.success(Map.of("total", total, "items", records));
    }
}
