import {
  Body,
  Controller,
  Get,
  Param,
  Patch,
  Post,
  Query,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import {
  IsBoolean,
  IsDateString,
  IsEnum,
  IsNumber,
  IsOptional,
  IsString,
  IsUUID,
  Min,
} from 'class-validator';
import { PlanTier } from '@prisma/client';
import { BillingService } from './billing.service';
import { Roles } from '../../common/decorators/roles.decorator';
import {
  CurrentUser,
  AuthenticatedUser,
} from '../../common/decorators/current-user.decorator';

class UpsertPlanDto {
  @IsString() code!: string;
  @IsString() name!: string;
  @IsOptional() @IsEnum(PlanTier) tier?: PlanTier;
  @IsNumber() @Min(0) fixedPrice!: number;
  @IsNumber() @Min(0) pricePerLot!: number;
  @IsOptional() @IsString() currency?: string;
  @IsOptional() features?: Record<string, boolean>;
}

class ToggleFeatureDto {
  @IsString() featureKey!: string;
  @IsBoolean() enabled!: boolean;
}

class SubscribeDto {
  @IsString() tenantId!: string;
  @IsString() planCode!: string;
}

class GenerateInvoiceDto {
  @IsDateString() periodStart!: string;
  @IsDateString() periodEnd!: string;
}

@ApiTags('billing')
@ApiBearerAuth()
@Controller()
export class BillingController {
  constructor(private readonly service: BillingService) {}

  @Post('plans')
  @Roles('SUPERADMIN')
  upsertPlan(@CurrentUser() u: AuthenticatedUser, @Body() dto: UpsertPlanDto) {
    return this.service.upsertPlan(u, dto);
  }

  @Get('plans')
  listPlans(@CurrentUser() u: AuthenticatedUser) {
    return this.service.listPlans(u);
  }

  @Post('tenants/:tenantId/feature-toggles')
  @Roles('SUPERADMIN')
  toggle(
    @CurrentUser() u: AuthenticatedUser,
    @Param('tenantId') tenantId: string,
    @Body() dto: ToggleFeatureDto,
  ) {
    return this.service.toggleFeature(u, tenantId, dto.featureKey, dto.enabled);
  }

  @Get('tenants/:tenantId/feature-toggles')
  listFeatures(
    @CurrentUser() u: AuthenticatedUser,
    @Param('tenantId') tenantId: string,
  ) {
    return this.service.listFeatures(u, tenantId);
  }

  @Post('subscriptions')
  @Roles('SUPERADMIN')
  subscribe(@CurrentUser() u: AuthenticatedUser, @Body() dto: SubscribeDto) {
    return this.service.subscribe(u, dto);
  }

  @Post('tenants/:tenantId/saas-invoices')
  @Roles('SUPERADMIN')
  generate(
    @CurrentUser() u: AuthenticatedUser,
    @Param('tenantId') tenantId: string,
    @Body() dto: GenerateInvoiceDto,
  ) {
    return this.service.generateInvoice(u, tenantId, {
      periodStart: new Date(dto.periodStart),
      periodEnd: new Date(dto.periodEnd),
    });
  }

  @Get('saas-invoices')
  list(@CurrentUser() u: AuthenticatedUser, @Query('tenantId') tenantId?: string) {
    return this.service.listInvoices(u, tenantId);
  }

  @Patch('saas-invoices/:id/paid')
  @Roles('SUPERADMIN')
  markPaid(@CurrentUser() u: AuthenticatedUser, @Param('id') id: string) {
    return this.service.markInvoicePaid(u, id);
  }
}
