package com.yaoai.admin.tenant;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import com.yaoai.admin.audit.annotation.AdminAudited;
import com.yaoai.admin.common.PageResult;
import com.yaoai.admin.tenant.dto.TenantBalanceOverview;
import com.yaoai.admin.tenant.dto.TenantDetail;
import com.yaoai.admin.tenant.dto.TenantImpersonateRequest;
import com.yaoai.admin.tenant.dto.TenantImpersonateResponse;
import com.yaoai.admin.tenant.dto.TenantListItem;
import com.yaoai.admin.tenant.dto.TenantPlanChangeRequest;
import com.yaoai.admin.tenant.dto.TenantQuotaUpdateRequest;
import com.yaoai.admin.tenant.dto.TenantRechargeRequest;
import com.yaoai.admin.tenant.dto.TenantSuspendRequest;
import com.yaoai.admin.tenant.dto.TenantUpdateRequest;
import com.yaoai.common.result.Result;
import com.yaoai.domain.entity.Project;
import com.yaoai.domain.entity.Tenant;
import com.yaoai.domain.entity.TenantQuota;
import com.yaoai.domain.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/admin-api/tenants")
@RequiredArgsConstructor
@SaCheckLogin(type = "admin")
public class TenantAdminController {

    private final TenantAdminService tenantAdminService;

    @GetMapping
    public Result<PageResult<TenantListItem>> list(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String plan,
            @RequestParam(required = false) Integer status,
            @RequestParam(defaultValue = "1") long page,
            @RequestParam(defaultValue = "20") long size) {
        return Result.ok(tenantAdminService.list(keyword, plan, status, page, size));
    }

    @GetMapping("/{id}")
    public Result<TenantDetail> detail(@PathVariable Long id) {
        return Result.ok(tenantAdminService.detail(id));
    }

    @PatchMapping("/{id}")
    @AdminAudited(action = "TENANT_UPDATE", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN", "OPERATOR"}, mode = SaMode.OR)
    public Result<Tenant> update(@PathVariable Long id, @RequestBody TenantUpdateRequest request) {
        return Result.ok(tenantAdminService.update(id, request));
    }

    @PutMapping("/{id}/plan")
    @AdminAudited(action = "TENANT_PLAN_CHANGE", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN", "OPERATOR"}, mode = SaMode.OR)
    public Result<Tenant> changePlan(@PathVariable Long id, @RequestBody TenantPlanChangeRequest request) {
        return Result.ok(tenantAdminService.changePlan(id, request));
    }

    @PostMapping("/{id}/suspend")
    @AdminAudited(action = "TENANT_SUSPEND", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN", "OPERATOR"}, mode = SaMode.OR)
    public Result<Tenant> suspend(@PathVariable Long id, @RequestBody TenantSuspendRequest request) {
        return Result.ok(tenantAdminService.suspend(id, request));
    }

    @PostMapping("/{id}/resume")
    @AdminAudited(action = "TENANT_RESUME", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN", "OPERATOR"}, mode = SaMode.OR)
    public Result<Tenant> resume(@PathVariable Long id) {
        return Result.ok(tenantAdminService.resume(id));
    }

    @GetMapping("/{id}/balance")
    public Result<TenantBalanceOverview> balance(@PathVariable Long id) {
        return Result.ok(tenantAdminService.balance(id));
    }

    @GetMapping("/{id}/members")
    public Result<List<User>> members(@PathVariable Long id) {
        return Result.ok(tenantAdminService.members(id));
    }

    @GetMapping("/{id}/projects")
    public Result<List<Project>> projects(@PathVariable Long id) {
        return Result.ok(tenantAdminService.projects(id));
    }

    @PostMapping("/{id}/recharge")
    @AdminAudited(action = "TENANT_RECHARGE", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN", "FINANCE"}, mode = SaMode.OR)
    public Result<TenantBalanceOverview> recharge(@PathVariable Long id, @RequestBody TenantRechargeRequest request) {
        return Result.ok(tenantAdminService.recharge(id, request));
    }

    @PutMapping("/{id}/quota")
    @AdminAudited(action = "TENANT_QUOTA_UPDATE", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN"})
    public Result<TenantQuota> updateQuota(@PathVariable Long id, @RequestBody TenantQuotaUpdateRequest request) {
        return Result.ok(tenantAdminService.updateQuota(id, request));
    }

    @PostMapping("/{id}/impersonate")
    @AdminAudited(action = "IMPERSONATE_START", resource = "TENANT", resourceIdParam = "id")
    @SaCheckRole(type = "admin", value = {"SUPER_ADMIN", "OPERATOR"}, mode = SaMode.OR)
    public Result<TenantImpersonateResponse> impersonate(
            @PathVariable Long id,
            @RequestBody(required = false) TenantImpersonateRequest request) {
        return Result.ok(tenantAdminService.impersonate(
                id,
                request == null ? new TenantImpersonateRequest() : request));
    }
}
