import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { PlansService } from './plans.service';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { RolesGuard } from '../../common/guards/roles.guard';
import { Roles } from '../../common/decorators/roles.decorator';
import { UserRole } from '@prisma/client';
import { CreatePlanDto } from './dto/create-plan.dto';
import { UpdatePlanDto } from './dto/update-plan.dto';

@ApiTags('plans')
@Controller('plans')
export class PlansController {
  constructor(private readonly plans: PlansService) {}

  @Get()
  @ApiOkResponse({ description: 'List available plans' })
  list() {
    return this.plans.list();
  }

  @Get('admin')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.SUPERADMIN)
  @ApiBearerAuth('bearer')
  @ApiOkResponse({
    description: 'Admin list of plans (paginated + searchable)',
  })
  listAdmin(
    @Query('page') page?: string,
    @Query('limit') limit?: string,
    @Query('q') q?: string,
    @Query('code') code?: string,
    @Query('isActive') isActive?: string,
  ) {
    const p = page != null ? Number(page) : null;
    const l = limit != null ? Number(limit) : null;
    const wantsPaged =
      (p != null && Number.isFinite(p)) || (l != null && Number.isFinite(l));
    const pageNum =
      p != null && Number.isFinite(p) ? Math.max(1, Math.floor(p)) : 1;
    const limitNum =
      l != null && Number.isFinite(l)
        ? Math.min(100, Math.max(1, Math.floor(l)))
        : 20;

    return this.plans.listPaged({
      page: wantsPaged ? pageNum : 1,
      limit: wantsPaged ? limitNum : 50,
      q: (q ?? '').toString(),
      code: code?.toString(),
      isActive: isActive?.toString(),
    });
  }

  @Post()
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.SUPERADMIN)
  @ApiBearerAuth('bearer')
  @ApiOkResponse({ description: 'Create a plan (upsert by code)' })
  create(@Body() dto: CreatePlanDto) {
    return this.plans.upsertByCode(dto);
  }

  @Patch(':id')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.SUPERADMIN)
  @ApiBearerAuth('bearer')
  @ApiOkResponse({ description: 'Update a plan' })
  update(@Param('id') id: string, @Body() dto: UpdatePlanDto) {
    return this.plans.update(id, dto);
  }

  @Delete(':id')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.SUPERADMIN)
  @ApiBearerAuth('bearer')
  @ApiOkResponse({ description: 'Delete a plan' })
  remove(@Param('id') id: string) {
    return this.plans.remove(id);
  }

  @Post('seed-defaults')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles(UserRole.SUPERADMIN)
  @ApiBearerAuth('bearer')
  @ApiOkResponse({ description: 'Upsert default plans (basic/growth/pro)' })
  seedDefaults() {
    return this.plans.seedDefaults();
  }

  @Post('seed-defaults-public')
  @ApiOkResponse({
    description:
      'Idempotent: seeds defaults only if no plans exist (safe for first boot)',
  })
  seedDefaultsPublic() {
    return this.plans.ensureDefaultsSeededIfEmpty();
  }
}
