import {
    Body,
    Controller,
    Delete,
    Get,
    HttpException,
    HttpStatus,
    Param,
    Post,
    Put,
    Query,
    UseGuards,
    ValidationPipe,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiCreatedResponse, ApiParam, ApiTags } from '@nestjs/swagger';
import { RequireModule } from 'src/auth/decorators/require-module.decorator';
import { RequirePermission } from 'src/auth/decorators/require-permission.decorator';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { ModuleGuard } from 'src/auth/guards/module.guard';
import { PermissionGuard } from 'src/auth/guards/permission.guard';
import { CategoriasService } from './categorias.service';
import { CreateCategoriaDto } from './dto/create-categoria.dto';
import {
    response_categoria_all,
    response_categoria_children,
    response_categoria_roots,
    response_categoria_standard,
} from './dto/doc-swagger';
import { UpdateCategoriaDto } from './dto/update-categoria.dto';

@ApiTags('Categorías')
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), ModuleGuard)
@RequireModule('INVENTARIO')
@Controller({ path: 'categorias', version: '1' })
export class CategoriasController {
  constructor(private readonly categoriasService: CategoriasService) {}

  @Post()
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_CREAR')
  @ApiBody({ type: CreateCategoriaDto })
  @ApiCreatedResponse(response_categoria_standard)
  create(@Body(ValidationPipe) createCategoriaDto: CreateCategoriaDto, @GetUser() user: LoginUserInfo) {
    return this.categoriasService.create(createCategoriaDto, user.empresa_id, user.id);
  }

  @Get()
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_VER')
  @ApiParam({ name: 'page', type: 'string', required: false, description: 'Pagina actual' })
  @ApiParam({ name: 'limit', type: 'string', required: false, description: 'Limit' })
  @ApiCreatedResponse(response_categoria_all)
  async findAll(@GetUser() user: LoginUserInfo, @Query('page') page?: string, @Query('limit') limit?: string) {
    try {
      const {
        items,
        total,
        page: currentPage,
        limit: pageLimit,
        lastPage,
      } = await this.categoriasService.findAll(Number(page) || 1, Number(limit) || 10, user.empresa_id, user.id);

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

  @Get('roots')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_VER')
  @ApiCreatedResponse(response_categoria_roots)
  findRoots(@GetUser() user: LoginUserInfo) {
    return this.categoriasService.findRoots(user.empresa_id, user.id);
  }

  @Get('tree')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_VER')
  findTree(@GetUser() user: LoginUserInfo) {
    return this.categoriasService.findTree(user.empresa_id);
  }

  @Get('children/:padre_id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_VER')
  @ApiParam({ name: 'padre_id', type: 'string', required: true, description: 'ID categoría padre' })
  @ApiCreatedResponse(response_categoria_children)
  findChildren(@Param('padre_id') padre_id: string, @GetUser() user: LoginUserInfo) {
    return this.categoriasService.findChildren(padre_id, user.empresa_id);
  }

  @Get(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_VER')
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID de la categoría' })
  @ApiCreatedResponse(response_categoria_standard)
  findOne(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.categoriasService.findOne(id, user.empresa_id);
  }

  @Put('activar-desactivar/:id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_EDITAR')
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID de la categoría' })
  activarDesactivar(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.categoriasService.activarDesactivar(id, user.empresa_id, user.id);
  }

  @Put(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_EDITAR')
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID de la categoría' })
  @ApiBody({ type: UpdateCategoriaDto })
  update(
    @Param('id') id: string,
    @Body(ValidationPipe) updateCategoriaDto: UpdateCategoriaDto,
    @GetUser() user: LoginUserInfo,
  ) {
    return this.categoriasService.update(id, updateCategoriaDto, user.empresa_id, user.id);
  }

  @Delete(':id')
  @UseGuards(PermissionGuard)
  @RequirePermission('INVENTARIO', 'INV_CAT_CATEGORIA_ELIMINAR')
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID de la categoría' })
  @ApiCreatedResponse(response_categoria_standard)
  remove(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.categoriasService.remove(id, user.empresa_id, user.id);
  }
}
