import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { ZodResponse } from 'nestjs-zod';
import { Permission } from '@pac/types';
import { RequirePermission } from '../../common/decorators/permissions.decorator';
import {
  TenantScope,
  TenantScopeContext,
} from '../../common/decorators/tenant-scope.decorator';
import {
  HostDetailDto,
  HostStatsDto,
  HostSummaryDto,
  RemovePushSecretResponseDto,
  RotateCallbackSecretResponseDto,
  RotatePushSecretResponseDto,
  RotateSecretResponseDto,
  UpdateHostRequestDto,
} from './dto/admin.dto';
import { HostsService } from './hosts.service';

/**
 * Host Self Admin — 宿主自己的 admin 用户管理"自己这个 host"的配置页。
 *
 * 跟 HostsAdminController(/admin/hosts/:id)区别:
 *   - 本控制器**自动 scope 到调用者的 hostId**(从 token 里的 hostId 取)
 *   - 不接受 :id 参数 — 宿主 admin 永远只能看 / 改自己的 host
 *   - 所有端点都需 PLATFORM_MANAGE 权限(仅 ADMIN 角色)
 *
 * 这层端点专为前端"宿主 admin 配置页"设计。PAC 团队自己用 CLI(pnpm pac:host)更直接。
 */
@ApiTags('admin')
@ApiBearerAuth('accessToken')
@Controller('admin/host/self')
@RequirePermission(Permission.PLATFORM_MANAGE)
export class HostSelfAdminController {
  constructor(private readonly hosts: HostsService) {}

  @Get()
  @ZodResponse({ status: 200, type: HostDetailDto })
  @ApiOperation({ summary: '当前宿主配置详情(含 pullConfig / push secret meta / 运行状态)' })
  getSelf(@TenantScope() scope: TenantScopeContext) {
    return this.hosts.getDetail(scope.hostId);
  }

  @Get('stats')
  @ZodResponse({ status: 200, type: HostStatsDto })
  @ApiOperation({ summary: '当前宿主运行状态(只刷新指标,不刷新整页用)' })
  getStats(@TenantScope() scope: TenantScopeContext) {
    return this.hosts.getStats(scope.hostId);
  }

  @Patch()
  @ZodResponse({ status: 200, type: HostSummaryDto })
  @ApiOperation({
    summary: '更新当前宿主配置(pullConfig / actionUrls / active)',
    description: '凭据轮换走 rotate 端点;不能改 name / appId',
  })
  update(@TenantScope() scope: TenantScopeContext, @Body() dto: UpdateHostRequestDto) {
    return this.hosts.update(scope.hostId, dto);
  }

  // ─── Secret rotation ───

  @Post('rotate-app-secret')
  @ZodResponse({ status: 200, type: RotateSecretResponseDto })
  @ApiOperation({
    summary: '轮换 appSecret(旧立即失效)',
    description: '返回的 plaintext 仅本次显示,请立即保存。',
  })
  rotateAppSecret(@TenantScope() scope: TenantScopeContext) {
    return this.hosts.rotateAppSecret(scope.hostId);
  }

  @Post('push-secrets')
  @ZodResponse({ status: 200, type: RotatePushSecretResponseDto })
  @ApiOperation({
    summary: '添加新 push secret(数组前插,旧 key 进 grace period)',
    description: '返回的 plaintext 仅本次显示,请立即保存。',
  })
  addPushSecret(@TenantScope() scope: TenantScopeContext) {
    return this.hosts.rotatePushSecret(scope.hostId);
  }

  @Delete('push-secrets/:suffix')
  @ZodResponse({ status: 200, type: RemovePushSecretResponseDto })
  @ApiOperation({
    summary: '按 suffix 删除某条 push secret(不能删唯一一条)',
  })
  removePushSecret(
    @TenantScope() scope: TenantScopeContext,
    @Param('suffix') suffix: string,
  ) {
    return this.hosts.removePushSecretBySuffix(scope.hostId, suffix);
  }

  // ─── 回执密钥(执行结果回调,方向:PAC → 宿主)───

  @Post('callback-secrets')
  @ZodResponse({ status: 200, type: RotateCallbackSecretResponseDto })
  @ApiOperation({
    summary: '添加新 callback secret(数组前插,旧 key 进 grace period)',
    description: '返回的 plaintext 仅本次显示,请立即保存。回执地址(callbackUrl)走 PATCH 设置。',
  })
  addCallbackSecret(@TenantScope() scope: TenantScopeContext) {
    return this.hosts.rotateCallbackSecret(scope.hostId);
  }

  @Delete('callback-secrets/:suffix')
  @ZodResponse({ status: 200, type: RemovePushSecretResponseDto })
  @ApiOperation({
    summary: '按 suffix 删除某条 callback secret(不能删唯一一条)',
  })
  removeCallbackSecret(
    @TenantScope() scope: TenantScopeContext,
    @Param('suffix') suffix: string,
  ) {
    return this.hosts.removeCallbackSecretBySuffix(scope.hostId, suffix);
  }
}
