import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Req, Res, UseGuards } from '@nestjs/common';
import type { Request, Response } from 'express';
import { AuthenticatedUser } from '../auth/auth.types';
import { AuthGuard } from '../common/auth.guard';
import { RequirePermission } from '../common/permission.decorator';
import { PermissionGuard } from '../common/permission.guard';
import { CreateCampaignDto } from './dto/create-campaign.dto';
import { SendCampaignDto } from './dto/send-campaign.dto';
import { UpdateCampaignDto } from './dto/update-campaign.dto';
import { CampaignsService } from './campaigns.service';

@UseGuards(AuthGuard, PermissionGuard)
@Controller('campaigns')
export class CampaignsController {
  constructor(private readonly campaignsService: CampaignsService) {}

  @Get()
  @RequirePermission('campaigns', 'view')
  findAll() {
    return this.campaignsService.findAll();
  }

  @Post()
  @RequirePermission('campaigns', 'edit')
  create(
    @Req() request: Request & { user: AuthenticatedUser },
    @Body() dto: CreateCampaignDto,
  ) {
    return this.campaignsService.create(dto, request.user, request.ip);
  }

  @Get(':id')
  @RequirePermission('campaigns', 'view')
  findOne(
    @Param('id') id: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    return this.campaignsService.findOne(
      id,
      page ? Number(page) : 1,
      limit ? Number(limit) : 5,
    );
  }

  @Post(':id/duplicate')
  @RequirePermission('campaigns', 'edit')
  duplicate(
    @Req() request: Request & { user: AuthenticatedUser },
    @Param('id') id: string,
  ) {
    return this.campaignsService.duplicate(id, request.user, request.ip);
  }

  @Patch(':id')
  @RequirePermission('campaigns', 'edit')
  update(
    @Req() request: Request & { user: AuthenticatedUser },
    @Param('id') id: string,
    @Body() dto: UpdateCampaignDto,
  ) {
    return this.campaignsService.update(id, dto, request.user, request.ip);
  }

  @Delete(':id')
  @RequirePermission('campaigns', 'delete')
  remove(
    @Req() request: Request & { user: AuthenticatedUser },
    @Param('id') id: string,
  ) {
    return this.campaignsService.remove(id, request.user, request.ip);
  }

  @Post(':id/send')
  @RequirePermission('campaigns', 'manage')
  send(
    @Req() request: Request & { user: AuthenticatedUser },
    @Param('id') id: string,
    @Body() dto: SendCampaignDto,
  ) {
    return this.campaignsService.send(id, dto, request.user, request.ip);
  }

  @Get(':id/export')
  @RequirePermission('campaigns', 'view')
  async export(
    @Req() request: Request & { user: AuthenticatedUser },
    @Res() response: Response,
    @Param('id') id: string,
    @Query('format') format?: string,
  ) {
    const result = await this.campaignsService.exportReport(
      id,
      format === 'xlsx' ? 'xlsx' : 'csv',
      request.user,
      request.ip,
    );

    response.setHeader('Content-Type', result.contentType);
    response.setHeader('Content-Disposition', `attachment; filename="${result.fileName}"`);
    response.send(result.buffer);
  }
}
