import { Body, Controller, Get, 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 { CreateAuditLogDto } from './dto/create-audit-log.dto';
import { LogsService } from './logs.service';

@UseGuards(AuthGuard)
@Controller('logs')
export class LogsController {
  constructor(private readonly logsService: LogsService) {}

  @Get('webhooks')
  getWebhookLogs(
    @Query('limit') limit?: string,
    @Query('provider') provider?: string,
    @Query('status') status?: string,
  ) {
    const parsedLimit = limit ? Number(limit) : 50;
    return this.logsService.getWebhookLogs(
      Number.isFinite(parsedLimit) ? parsedLimit : 50,
      provider,
      status,
    );
  }

  @Get('jobs')
  getJobLogs(
    @Query('limit') limit?: string,
    @Query('queue') queueName?: string,
    @Query('status') status?: string,
  ) {
    const parsedLimit = limit ? Number(limit) : 50;
    return this.logsService.getJobLogs(
      Number.isFinite(parsedLimit) ? parsedLimit : 50,
      queueName,
      status,
    );
  }

  @Get('audit-trail')
  getAuditTrail(
    @Query('page') page?: string,
    @Query('limit') limit?: string,
    @Query('range') range?: string,
    @Query('user') actorName?: string,
    @Query('actionType') actionType?: string,
    @Query('module') moduleName?: string,
    @Query('search') search?: string,
  ) {
    const parsedPage = page ? Number(page) : 1;
    const parsedLimit = limit ? Number(limit) : 200;
    return this.logsService.getAuditTrail(
      Number.isFinite(parsedPage) ? parsedPage : 1,
      Number.isFinite(parsedLimit) ? parsedLimit : 200,
      range,
      actorName,
      actionType,
      moduleName,
      search,
    );
  }

  @Get('audit-trail/export')
  async exportAuditTrail(
    @Res() response: Response,
    @Query('range') range?: string,
    @Query('user') actorName?: string,
    @Query('actionType') actionType?: string,
    @Query('module') moduleName?: string,
    @Query('search') search?: string,
  ) {
    const csv = await this.logsService.exportAuditTrailCsv(
      range,
      actorName,
      actionType,
      moduleName,
      search,
    );

    response.setHeader('Content-Type', 'text/csv; charset=utf-8');
    response.setHeader('Content-Disposition', 'attachment; filename="audit-trail-export.csv"');
    response.send(csv);
  }

  @Post('audit-trail')
  createAuditTrailEntry(
    @Req() request: Request & { user: AuthenticatedUser },
    @Body() dto: CreateAuditLogDto,
  ) {
    const forwarded = request.headers['x-forwarded-for'];
    const ipAddress = typeof forwarded === 'string' ? forwarded.split(',')[0]?.trim() : request.ip;
    return this.logsService.createAuditLog(dto, request.user, ipAddress);
  }
}
