import {
    Body,
    Controller,
    Delete,
    Get,
    HttpException,
    HttpStatus,
    Param,
    Patch,
    Post,
    Put,
    Query,
    UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth, ApiBody, ApiCreatedResponse, ApiOperation, ApiParam, ApiQuery } from '@nestjs/swagger';
import type { LoginUserInfo } from 'src/auth/dto/login.dto';
import { GetUser } from 'src/auth/get-user.decorator';
import { ClientesService } from './clientes.service';
import { CreateClienteDto } from './dto/create-cliente.dto';
import { response_cliente_all, response_cliente_find, response_cliente_standard } from './dto/doc-swagger';
import { UpdateClienteDto } from './dto/update-cliente.dto';

@Controller({ path: 'clientes', version: '1' })
export class ClientesController {
  constructor(private readonly clientesService: ClientesService) {}

  @Post()
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiBody({ type: CreateClienteDto })
  @ApiCreatedResponse(response_cliente_find)
  create(@Body() createClienteDto: CreateClienteDto, @GetUser() user: LoginUserInfo) {
    return this.clientesService.create(createClienteDto, user.empresa_id, user.id);
  }
  @Get('search')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async search(@GetUser() user: LoginUserInfo, @Query('q') query: string, @Query('limit') limit?: string) {
    const clientes = await this.clientesService.search(query, user.empresa_id, Number(limit) || 20);
    return {
      message: 'Búsqueda realizada exitosamente',
      data: clientes,
    };
  }

  @Get('export')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  async exportAll(@GetUser() user: LoginUserInfo, @Query('q') q?: string) {
    const data = await this.clientesService.findAllForExport(user.empresa_id, q);
    return { message: 'Exportación exitosa', data };
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'page', type: 'string', required: false, description: 'Pagina actual' })
  @ApiParam({ name: 'limit', type: 'string', required: false, description: 'Limit' })
  @ApiCreatedResponse(response_cliente_all)
  @Get()
  async findAll(
    @GetUser() user: LoginUserInfo,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
    @Query('q') q?: string,
    @Query('mora_estado') mora_estado?: string,
  ) {
    try {
      const {
        items,
        total,
        page: currentPage,
        limit: pageLimit,
        lastPage,
      } = await this.clientesService.findAll(Number(page) || 1, Number(limit) || 10, user.empresa_id, q, mora_estado);

      return {
        message: 'Clientes 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,
      );
    }
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del cliente' })
  @ApiCreatedResponse(response_cliente_find)
  @Get(':id')
  async findOne(@Param('id') id: string) {
    return await this.clientesService.findOne(id);
  }

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

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del cliente' })
  @ApiBody({ type: UpdateClienteDto })
  @ApiCreatedResponse(response_cliente_standard)
  @Put(':id')
  update(@Param('id') id: string, @GetUser() user: LoginUserInfo, @Body() updateClienteDto: UpdateClienteDto) {
    return this.clientesService.update(id, updateClienteDto, user.empresa_id, user.id);
  }

  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del cliente' })
  @Delete(':id')
  @ApiCreatedResponse(response_cliente_standard)
  remove(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.clientesService.remove(id, user.empresa_id, user.id);
  }

  // ==================== FASE 2: CONTROL DE CRÉDITO ====================

  @Get(':id/credito')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Obtener información de crédito del cliente' })
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del cliente' })
  getCreditInfo(@Param('id') id: string) {
    return this.clientesService.getCreditInfo(id);
  }

  @Get(':id/credito/verificar')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Verificar disponibilidad de crédito para un monto' })
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del cliente' })
  @ApiQuery({ name: 'monto', type: 'number', required: true, description: 'Monto a verificar' })
  verificarCredito(@Param('id') id: string, @Query('monto') monto: string) {
    return this.clientesService.verificarCredito(id, Number(monto) || 0);
  }

  @Patch(':id/credito')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Actualizar configuración de crédito del cliente' })
  @ApiParam({ name: 'id', type: 'string', required: true, description: 'ID del cliente' })
  updateCreditConfig(
    @Param('id') id: string,
    @Body()
    data: {
      limite_credito?: number;
      credito_habilitado?: boolean;
      moneda_credito?: string;
      dias_mora_maximo?: number;
      bloqueado_credito?: boolean;
    },
    @GetUser() user: LoginUserInfo,
  ) {
    return this.clientesService.updateCreditConfig(id, data, user.empresa_id, user.id);
  }

  // ── Direcciones adicionales ──────────────────────────────────────

  @Get(':id/direcciones')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Listar direcciones adicionales del cliente' })
  getDirecciones(@Param('id') id: string, @GetUser() user: LoginUserInfo) {
    return this.clientesService.getDirecciones(id, user.empresa_id);
  }

  @Post(':id/direcciones')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Agregar dirección adicional al cliente' })
  createDireccion(@Param('id') id: string, @Body() data: DireccionDto, @GetUser() user: LoginUserInfo) {
    return this.clientesService.createDireccion(id, data, user.empresa_id);
  }

  @Put(':id/direcciones/:dirId')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Actualizar dirección adicional' })
  updateDireccion(@Param('id') id: string, @Param('dirId') dirId: string, @Body() data: DireccionDto, @GetUser() user: LoginUserInfo) {
    return this.clientesService.updateDireccion(id, dirId, data, user.empresa_id);
  }

  @Delete(':id/direcciones/:dirId')
  @UseGuards(AuthGuard('jwt'))
  @ApiBearerAuth()
  @ApiOperation({ summary: 'Eliminar dirección adicional' })
  deleteDireccion(@Param('id') id: string, @Param('dirId') dirId: string, @GetUser() user: LoginUserInfo) {
    return this.clientesService.deleteDireccion(id, dirId, user.empresa_id);
  }
}

interface DireccionDto {
  label?: string;
  direccion?: string;
  nro?: string;
  referencia?: string;
  pais_id?: string;
  departamento_id?: string;
  distrito_id?: string;
  ciudad_id?: string;
  es_principal?: boolean;
}
