import {
  Body,
  Controller,
  ForbiddenException,
  Get,
  Param,
  Patch,
  Post,
  UseGuards,
} from '@nestjs/common'
import { ActorService } from '../auth/actor.service.js'
import { CurrentUser } from '../auth/current-user.decorator.js'
import { JwtAuthGuard } from '../auth/jwt-auth.guard.js'
import type { AuthentikJwtPayload } from '../auth/jwt-payload.interface.js'
import { TenantsService } from '../tenants/tenants.service.js'
import { CreateSubscriptionDto } from './dto/create-subscription.dto.js'
import { UpdateSubscriptionDto } from './dto/update-subscription.dto.js'
import { SubscriptionsService } from './subscriptions.service.js'

@Controller('subscriptions')
@UseGuards(JwtAuthGuard)
export class SubscriptionsController {
  constructor(
    private readonly subs: SubscriptionsService,
    private readonly tenants: TenantsService,
    private readonly actor: ActorService,
  ) {}

  @Post()
  async create(@Body() dto: CreateSubscriptionDto, @CurrentUser() jwt: AuthentikJwtPayload) {
    const actor = await this.actor.resolve(jwt)
    if (!actor.platformAdmin) {
      throw new ForbiddenException('Only platform admins can create subscriptions')
    }
    return this.subs.create(dto)
  }

  @Get()
  async findAll(@CurrentUser() jwt: AuthentikJwtPayload) {
    const actor = await this.actor.resolve(jwt)
    if (actor.platformAdmin) return this.subs.findAll()
    return this.subs.findAllForTenants(actor.tenantIds)
  }

  @Get(':slug')
  async findOne(@Param('slug') slug: string, @CurrentUser() jwt: AuthentikJwtPayload) {
    const actor = await this.actor.resolve(jwt)
    const tenant = await this.tenants.findOneBySlug(slug)
    if (!actor.platformAdmin && !actor.tenantIds.some((id) => id.equals(tenant._id))) {
      throw new ForbiddenException(`No access to tenant "${slug}"`)
    }
    return this.subs.findByTenantSlug(slug)
  }

  @Patch(':slug')
  async update(
    @Param('slug') slug: string,
    @Body() dto: UpdateSubscriptionDto,
    @CurrentUser() jwt: AuthentikJwtPayload,
  ) {
    const actor = await this.actor.resolve(jwt)
    if (!actor.platformAdmin) {
      throw new ForbiddenException('Only platform admins can update subscriptions')
    }
    return this.subs.update(slug, dto)
  }
}
