import { Body, Controller, Get, Param, ParseIntPipe, Post, Query } from '@nestjs/common';
import { createZodDto } from 'nestjs-zod';
import {
  ClientListQuerySchema,
  CreateClientNovoSchema,
  CreateContatoSchema,
  type ClientDetail,
  type ClientListQuery,
  type ClientListResponse,
  type ClientNovoResult,
  type Contato,
  type ContatoResult,
  type CtrSummary,
  type CreateClientNovo,
  type CreateContato,
  type CtrTitulo,
  type NotaFiscal,
  type PedidoSummary,
  type TopProduto,
} from '@sar/api-interface';
import { ClientsService } from './clients.service';

class ClientListQueryDto extends createZodDto(ClientListQuerySchema) {}
class CreateClientNovoDto extends createZodDto(CreateClientNovoSchema) {}
class CreateContatoDto extends createZodDto(CreateContatoSchema) {}

@Controller({ path: 'clients' })
export class ClientsController {
  constructor(private readonly clients: ClientsService) {}

  @Get()
  list(@Query() query: ClientListQueryDto): Promise<ClientListResponse> {
    const parsed = ClientListQuerySchema.parse(query) as ClientListQuery;
    return this.clients.list(parsed);
  }

  @Post('novo')
  createNovo(@Body() body: CreateClientNovoDto): Promise<ClientNovoResult> {
    const parsed = CreateClientNovoSchema.parse(body) as CreateClientNovo;
    return this.clients.createNovo(parsed);
  }

  @Get(':id/notas')
  listNotasFiscais(
    @Param('id', ParseIntPipe) id: number,
    @Query('limit') limit?: string,
  ): Promise<NotaFiscal[]> {
    const n = limit ? Math.min(parseInt(limit, 10) || 30, 100) : 30;
    return this.clients.listNotasFiscais(id, n);
  }

  @Get(':id/top-produtos')
  listTopProdutos(
    @Param('id', ParseIntPipe) id: number,
    @Query('limit') limit?: string,
  ): Promise<TopProduto[]> {
    const n = limit ? Math.min(parseInt(limit, 10) || 30, 100) : 30;
    return this.clients.listTopProdutos(id, n);
  }

  @Get(':id/orders-history')
  listOrdersHistory(
    @Param('id', ParseIntPipe) id: number,
    @Query('limit') limit?: string,
  ): Promise<PedidoSummary[]> {
    const n = limit ? Math.min(parseInt(limit, 10) || 50, 200) : 50;
    return this.clients.listOrdersHistory(id, n);
  }

  @Get(':id/ctr')
  getCtrSummary(@Param('id', ParseIntPipe) id: number): Promise<CtrSummary> {
    return this.clients.getCtrSummary(id);
  }

  @Get(':id/ctr-list')
  listCtrTitulos(
    @Param('id', ParseIntPipe) id: number,
    @Query('limit') limit?: string,
  ): Promise<CtrTitulo[]> {
    const n = limit ? Math.min(parseInt(limit, 10) || 60, 200) : 60;
    return this.clients.listCtrTitulos(id, n);
  }

  @Get(':id/contacts')
  listContacts(@Param('id', ParseIntPipe) id: number): Promise<Contato[]> {
    return this.clients.listContacts(id);
  }

  @Post(':id/contacts')
  createContato(
    @Param('id', ParseIntPipe) id: number,
    @Body() body: CreateContatoDto,
  ): Promise<ContatoResult> {
    const parsed = CreateContatoSchema.parse(body) as CreateContato;
    return this.clients.createContato(id, parsed);
  }

  @Get(':id')
  findOne(@Param('id', ParseIntPipe) id: number): Promise<ClientDetail> {
    return this.clients.findOne(id);
  }
}
