import {
    Body,
    Controller,
    Delete,
    Get,
    HttpException,
    HttpStatus,
    Param,
    Post,
    Put,
    Query,
    UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiCreatedResponse, ApiExcludeEndpoint, ApiParam, ApiResponse } from '@nestjs/swagger';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { CreatePuntoExpedicionDto } from './dto/create-punto-expedicione.dto';
import {
    response_create_punto_expedicion,
    response_punto_expedicion_all,
    response_punto_expedicion_find,
} from './dto/doc-swagger';
import { UpdatePuntoExpedicioneDto } from './dto/update-punto-expedicione.dto';
import { PuntoExpedicionesService } from './punto-expediciones.service';

@Controller({ version: '1', path: 'punto-expediciones' })
export class PuntoExpedicionesController {
  constructor(private readonly puntoExpedicionesService: PuntoExpedicionesService) {}

  @Post()
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiBody({ type: CreatePuntoExpedicionDto })
  @ApiCreatedResponse(response_create_punto_expedicion)
  create(@Body() createPuntoExpedicioneDto: CreatePuntoExpedicionDto, @GetUser() user: LoginUserInfo) {
    return this.puntoExpedicionesService.create(createPuntoExpedicioneDto, user?.id);
  }
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'page', type: 'string', required: false, description: 'Pagina actual' })
  @ApiParam({ name: 'limit', type: 'string', required: false, description: 'Limit' })
  @ApiParam({ name: 'empresa_id', type: 'string', required: false, description: 'Filtrar por empresa' })
  @ApiParam({ name: 'sucursal_id', type: 'string', required: false, description: 'Filtrar por sucursal' })
  @ApiParam({ name: 'caja_id', type: 'string', required: false, description: 'Filtrar por caja' })
  @ApiCreatedResponse(response_punto_expedicion_all)
  @Get()
  async findAll(
    @Query('page') page?: string,
    @Query('limit') limit?: string,
    @Query('empresa_id') empresa_id?: string,
    @Query('sucursal_id') sucursal_id?: string,
    @Query('caja_id') caja_id?: string,
  ) {
    try {
      const {
        items,
        total,
        page: currentPage,
        limit: pageLimit,
        lastPage,
      } = await this.puntoExpedicionesService.findAll(
        Number(page) || 1,
        Number(limit) || 10,
        empresa_id,
        sucursal_id,
        caja_id,
      );

      return {
        message: 'Puntos de expedicion obtenidos exitosamente',
        data: items,
        total,
        page: currentPage,
        limit: pageLimit,
        lastPage,
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Error desconocido';
      throw new HttpException(
        {
          success: false,
          message: 'Error al obtener puntos de expedicion',
          error: errorMessage,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'caja_id', type: 'string', required: true, description: 'ID de la caja' })
  @Get('by-caja/:caja_id')
  findByCaja(@Param('caja_id') caja_id: string) {
    return this.puntoExpedicionesService.findByCaja(caja_id);
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID de la sucursal' })
  @ApiResponse(response_punto_expedicion_find)
  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.puntoExpedicionesService.findOne(id);
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del usuario' })
  @ApiBody({ type: UpdatePuntoExpedicioneDto })
  @Put(':id')
  @ApiCreatedResponse(response_punto_expedicion_find)
  update(@Param('id') id: string, @Body() updateUserDto: UpdatePuntoExpedicioneDto, @GetUser() user: LoginUserInfo) {
    return this.puntoExpedicionesService.update(id, updateUserDto, user?.id);
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del usuario' })
  @ApiCreatedResponse(response_punto_expedicion_find)
  @Put('activar-desactivar/:id')
  activarDesactivar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.puntoExpedicionesService.activarDesactivar(id, user?.id);
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del punto de expedición' })
  @Put(':id/set-default')
  setDefault(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.puntoExpedicionesService.setDefault(id, user?.id);
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del punto de expedición' })
  @Put(':id/unset-default')
  unsetDefault(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.puntoExpedicionesService.unsetDefault(id, user?.id);
  }

  @ApiExcludeEndpoint()
  @Delete(':id')
  remove(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.puntoExpedicionesService.remove(id, user?.id);
  }
}
