import {
  Body,
  Controller,
  Get,
  Param,
  ParseIntPipe,
  Patch,
  Post,
  Put,
  Query,
  Request,
  UseGuards,
} from "@nestjs/common";
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
import { RequirePermission } from "../auth/decorators/require-permission.decorator";
import { JwtAuthGuard } from "../auth/guards/jwt-auth.guard";
import { PermissionGuard } from "../auth/guards/permission.guard";
import { CatalogosService } from "./catalogos.service";
import { CreateCatalogoVehicularDto } from "./dto/create-catalogo-vehicular.dto";
import { CreateCosaTraeDto } from "./dto/create-cosa-trae.dto";
import { CreateTipoDanoDto } from "./dto/create-tipo-dano.dto";
import { CreateTipoVehiculoDto } from "./dto/create-tipo-vehiculo.dto";
import { CatalogoVehicularTipo } from "./entities/catalogo-vehicular.entity";

@ApiTags("catalogos")
@ApiBearerAuth()
@UseGuards(JwtAuthGuard, PermissionGuard)
@RequirePermission("catalogos", "read")
@Controller("catalogos")
export class CatalogosController {
  constructor(private readonly catalogosService: CatalogosService) {}

  @Get("tipos-vehiculo")
  @ApiOperation({ summary: "Listar tipos de vehiculo activos" })
  async findAllTiposVehiculo() {
    return this.catalogosService.findAllTiposVehiculo();
  }

  @Post("tipos-vehiculo")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Crear tipo de vehiculo" })
  async createTipoVehiculo(
    @Body() dto: CreateTipoVehiculoDto,
    @Request() req: any,
  ) {
    return this.catalogosService.createTipoVehiculo(dto, req.user?.id);
  }

  @Put("tipos-vehiculo/:id")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Actualizar tipo de vehiculo" })
  async updateTipoVehiculo(
    @Param("id") id: number,
    @Body() dto: CreateTipoVehiculoDto,
    @Request() req: any,
  ) {
    return this.catalogosService.updateTipoVehiculo(id, dto, req.user?.id);
  }

  @Patch("tipos-vehiculo/:id/inactivar")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Inactivar tipo de vehiculo" })
  async inactivateTipoVehiculo(@Param("id") id: number, @Request() req: any) {
    return this.catalogosService.inactivateTipoVehiculo(id, req.user?.id);
  }

  @Get("cosas-trae")
  @ApiOperation({ summary: "Listar cosas que trae activas" })
  async findAllCosasTrae() {
    return this.catalogosService.findAllCosasTrae();
  }

  @Post("cosas-trae")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Crear cosa que trae" })
  async createCosaTrae(@Body() dto: CreateCosaTraeDto) {
    return this.catalogosService.createCosaTrae(dto);
  }

  @Put("cosas-trae/:id")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Actualizar cosa que trae" })
  async updateCosaTrae(
    @Param("id") id: number,
    @Body() dto: CreateCosaTraeDto,
  ) {
    return this.catalogosService.updateCosaTrae(id, dto);
  }

  @Patch("cosas-trae/:id/inactivar")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Inactivar cosa que trae" })
  async inactivateCosaTrae(@Param("id") id: number) {
    return this.catalogosService.inactivateCosaTrae(id);
  }

  @Get("tipos-dano")
  @ApiOperation({ summary: "Listar tipos de dano activos" })
  async findAllTiposDano() {
    return this.catalogosService.findAllTiposDano();
  }

  @Post("tipos-dano")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Crear tipo de dano" })
  async createTipoDano(@Body() dto: CreateTipoDanoDto) {
    return this.catalogosService.createTipoDano(dto);
  }

  @Put("tipos-dano/:id")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Actualizar tipo de dano" })
  async updateTipoDano(
    @Param("id") id: number,
    @Body() dto: CreateTipoDanoDto,
  ) {
    return this.catalogosService.updateTipoDano(id, dto);
  }

  @Patch("tipos-dano/:id/inactivar")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Inactivar tipo de dano" })
  async inactivateTipoDano(@Param("id") id: number) {
    return this.catalogosService.inactivateTipoDano(id);
  }

  @Get("vehicular")
  @ApiOperation({ summary: "Listar catalogo vehicular por tipo y filtros" })
  async listVehicular(
    @Query("tipo") tipo: CatalogoVehicularTipo,
    @Query("marca") marca?: string,
    @Query("modelo") modelo?: string,
    @Query("motor") motor?: string,
    @Query("tipoVehiculoId") tipoVehiculoId?: string,
  ) {
    const parsedTipoVehiculoId = tipoVehiculoId
      ? Number(tipoVehiculoId)
      : undefined;
    return this.catalogosService.listCatalogosVehiculares(tipo, {
      marca,
      modelo,
      motor,
      tipoVehiculoId: parsedTipoVehiculoId,
    });
  }

  @Post("vehicular")
  @RequirePermission("catalogos", "write")
  @ApiOperation({
    summary: "Crear item de catalogo vehicular (marca/modelo/motor/cilindraje)",
  })
  async createVehicular(@Body() dto: CreateCatalogoVehicularDto) {
    return this.catalogosService.createCatalogoVehicular(dto);
  }

  @Put("vehicular/:id")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Actualizar item de catalogo vehicular" })
  async updateVehicular(
    @Param("id", ParseIntPipe) id: number,
    @Body() dto: Partial<CreateCatalogoVehicularDto>,
  ) {
    return this.catalogosService.updateCatalogoVehicular(id, dto);
  }

  @Patch("vehicular/:id/inactivar")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Inactivar item de catalogo vehicular" })
  async inactivateVehicular(@Param("id", ParseIntPipe) id: number) {
    return this.catalogosService.inactivateCatalogoVehicular(id);
  }

  @Post("seed")
  @RequirePermission("catalogos", "write")
  @ApiOperation({ summary: "Sembrar datos iniciales (tipos, cosas, danos)" })
  async seed() {
    return this.catalogosService.seedCatalogos();
  }
}
