import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Post,
  Req,
  UseGuards,
} from '@nestjs/common';
import {
  ApiBearerAuth,
  ApiConflictResponse,
  ApiOkResponse,
  ApiProperty,
  ApiTags,
} from '@nestjs/swagger';
import {
  IsInt,
  IsOptional,
  IsString,
  Max,
  MaxLength,
  Min,
  MinLength,
} from 'class-validator';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import type { RequestAutenticado } from '../auth/jwt-auth.guard';
import { CicloVidaService } from './ciclo-vida.service';

export class RecriarDto {
  @ApiProperty({ minimum: 1, maximum: 38 })
  @IsInt()
  @Min(1)
  @Max(38)
  matchdayFrom!: number;

  @ApiProperty({ minimum: 1, maximum: 38 })
  @IsInt()
  @Min(1)
  @Max(38)
  matchdayTo!: number;

  @ApiProperty({ required: false })
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(60)
  name?: string;
}

@ApiTags('Ciclo de vida')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('pools')
export class CicloVidaController {
  constructor(private readonly ciclo: CicloVidaService) {}

  /** Histórico de bolões encerrados do participante. */
  @Get('history')
  @ApiOkResponse({ description: 'títulos e participações encerradas' })
  historico(@Req() req: RequestAutenticado) {
    return this.ciclo.historico(req.conta.id);
  }

  /** Campeão e ranking final de bolão já encerrado — leitura, para todos. */
  @Get(':poolId/closing')
  @ApiOkResponse({ description: 'campeão e ranking final' })
  @ApiConflictResponse({ description: 'bolão ainda não encerrado' })
  encerramento(
    @Param('poolId') poolId: string,
    @Req() req: RequestAutenticado,
  ) {
    return this.ciclo.lerEncerramento(poolId, req.conta.id);
  }

  /** Encerra se a última rodada foi apurada. Recusa se houver jogo pendente. */
  @Post(':poolId/close')
  @ApiConflictResponse({ description: 'ainda há jogo sem resultado' })
  encerrar(@Param('poolId') poolId: string, @Req() req: RequestAutenticado) {
    return this.ciclo.encerrarSePronto(poolId, req.conta.id);
  }

  /** Encerramento antecipado — única saída para bolão travado. */
  @Post(':poolId/close-early')
  encerrarAntecipado(
    @Param('poolId') poolId: string,
    @Req() req: RequestAutenticado,
  ) {
    return this.ciclo.encerrarAntecipadamente(poolId, req.conta.id);
  }

  @Post(':poolId/archive')
  @ApiConflictResponse({ description: 'bolão em andamento não é arquivável' })
  arquivar(@Param('poolId') poolId: string, @Req() req: RequestAutenticado) {
    return this.ciclo.arquivar(poolId, req.conta.id);
  }

  @Delete(':poolId/archive')
  desarquivar(@Param('poolId') poolId: string, @Req() req: RequestAutenticado) {
    return this.ciclo.desarquivar(poolId, req.conta.id);
  }

  /** Recria para a temporada seguinte, herdando galera e regras. */
  @Post(':poolId/recreate')
  recriar(
    @Param('poolId') poolId: string,
    @Body() dto: RecriarDto,
    @Req() req: RequestAutenticado,
  ) {
    return this.ciclo.recriar(
      poolId,
      req.conta.id,
      dto.matchdayFrom,
      dto.matchdayTo,
      dto.name,
    );
  }
}
