package com.yaoai.api.controller;

import com.yaoai.api.dto.billing.BalanceDTO;
import com.yaoai.api.dto.billing.BillingRecordDTO;
import com.yaoai.billing.service.BillingCostService;
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.Project;
import com.yaoai.domain.mapper.ProjectMapper;
import com.yaoai.security.context.TenantContext;
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;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Tag(name = "用量统计")
@RestController
@RequestMapping("/usage")
@RequiredArgsConstructor
public class UsageController {

    private final BillingService billingService;
    private final BillingCostService billingCostService;
    private final ProjectMapper projectMapper;

    @Operation(summary = "查询积分余额")
    @GetMapping("/balance")
    public ApiResponse<BalanceDTO> getBalance() {
        Long tenantId = TenantContext.get();
        return ApiResponse.success(BalanceDTO.from(billingService.getBalance(tenantId)));
    }

    @Operation(summary = "查询计费价目（operation -> credits）")
    @GetMapping("/costs")
    public ApiResponse<Map<String, BigDecimal>> getCosts() {
        return ApiResponse.success(billingCostService.getCosts());
    }

    @Operation(summary = "购买积分资源包（演示：免支付直接到账）")
    @PostMapping("/purchase")
    public ApiResponse<BalanceDTO> purchase(@RequestBody Map<String, Object> body) {
        Long tenantId = TenantContext.get();
        String packageId = body.getOrDefault("packageId", "").toString();
        BigDecimal credits = switch (packageId) {
            case "starter"    -> BigDecimal.valueOf(1_000);
            case "basic"      -> BigDecimal.valueOf(5_000);
            case "pro"        -> BigDecimal.valueOf(20_000);
            case "enterprise" -> BigDecimal.valueOf(100_000);
            default -> throw new BizException(ErrorCode.INVALID_PARAM, "未知资源包: " + packageId);
        };
        billingService.recharge(tenantId, credits, "PURCHASE-" + packageId.toUpperCase());
        return ApiResponse.success(BalanceDTO.from(billingService.getBalance(tenantId)));
    }

    @Operation(summary = "查询消耗明细（分页）")
    @GetMapping("/records")
    public ApiResponse<Map<String, Object>> getRecords(
            @RequestParam(defaultValue = "20") int limit,
            @RequestParam(defaultValue = "0") long offset) {
        Long tenantId = TenantContext.get();
        List<BillingRecordDTO> list = billingService.getRecords(tenantId, limit, offset)
                .stream().map(BillingRecordDTO::from).toList();
        Map<Long, Project> projects = loadProjects(tenantId, list);
        list.forEach(record -> {
            Project project = projects.get(record.getProjectId());
            if (project != null) {
                record.setProjectName(project.getName());
            }
        });
        long total = billingService.countRecords(tenantId);
        return ApiResponse.success(Map.of("total", total, "items", list));
    }

    private Map<Long, Project> loadProjects(Long tenantId, List<BillingRecordDTO> records) {
        Set<Long> ids = records.stream()
                .map(BillingRecordDTO::getProjectId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        if (ids.isEmpty()) {
            return Map.of();
        }
        return projectMapper.selectBatchIds(ids).stream()
                .filter(project -> tenantId.equals(project.getTenantId()))
                .collect(Collectors.toMap(Project::getId, Function.identity()));
    }
}
