import { Controller, Get, Post, Body, Param, UploadedFile, Query, Delete, UseInterceptors, Put, BadRequestException } from '@nestjs/common';
import { CouponsService } from './coupons.service';
import { Coupon } from './coupon.entity';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';

@Controller('coupons')
export class CouponsController {
  constructor(private readonly couponsService: CouponsService) {}

  // Listar cupons com filtro, paginação, e ordenação
  @Get()
  async findAll(
    @Query('where') where: any,
    @Query('page') page: number = 1,
    @Query('limit') limit: number = 10,
    @Query('orderBy') orderBy: string = 'createdAt',
    @Query('order') order: 'ASC' | 'DESC' = 'DESC',
  ): Promise<{ data: Coupon[], total: number }> {
    return this.couponsService.findAll(where, page, limit, orderBy, order);
  }

  // Listar cupons reivindicados com filtros
  @Get('claimed')
  async getClaimedCoupons(
    @Query('cpf') cpf?: string,
    @Query('companyId') companyId?: number,
    @Query('couponReference') couponReference?: string,
  ) {
    const filters: any = {};

    if (cpf) {
      filters.cpf = cpf;
    }

    if (companyId) {
      filters.company = { id: companyId }; // Filtra pelo ID da companhia
    }

    if (couponReference) {
      filters.coupon = { reference: couponReference };
    }

    const results = await this.couponsService.findClaimedCoupons(filters);
    console.log('Claimed coupons returned:', results);
    return results;
  }

  // Ativar um cupom pelo código
  @Put('activate')
  async activateCoupon(@Body('code') code: string): Promise<any> {
    if (!code) {
      throw new BadRequestException('Código do cupom é obrigatório.');
    }

    return this.couponsService.activateCoupon(code);
  }

  // Retorna um cupom específico pelo ID
  @Get(':id')
  async findOne(@Param('id') id: string): Promise<Coupon> {
    return this.couponsService.findOne(id);
  }

  // Reivindicar um cupom específico
  @Post(':id/claim')
  async claimCoupon(
    @Param('id') id: string,
    @Body('cpf') cpf: string,
    @Body('code') code: string,
    @Body('nomeCliente') nomeCliente: string
  ): Promise<void> {
    if (!cpf) {
      throw new Error('CPF inválido.');
    }

    await this.couponsService.claimCoupon(id, code, nomeCliente, cpf);
  }

  // Inserir ou atualizar um cupom
  @Post()
  @UseInterceptors(FileInterceptor('image', {
    storage: diskStorage({
      destination: './uploads',
      filename: (req, file, cb) => {
        const randomName = Array(32)
          .fill(null)
          .map(() => Math.round(Math.random() * 16).toString(16))
          .join('');
        cb(null, `${randomName}.jpg`);
      },
    }),
  }))
  async upsert(@Body() couponData: any, @UploadedFile() file: Express.Multer.File): Promise<Coupon> {
    if (file) {
      couponData.imageName = file.filename;
    }

    if (couponData.products) {
      couponData.products = JSON.parse(couponData.products);
    }

    return this.couponsService.upsert(couponData);
  }

  // Remover um cupom específico pelo ID
  @Delete(':id')
  async remove(@Param('id') id: string): Promise<void> {
    return this.couponsService.remove(id);
  }
}