import {
  Body,
  Controller,
  Get,
  Param,
  ParseIntPipe,
  Put,
  Query,
  Request,
  Res,
  UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiBearerAuth } from '@nestjs/swagger';
import type { Response } from 'express';
import { CashboxExportQueryDto } from './dto/cashbox-export-query.dto';
import { UpsertCashboxExportSubscriptionDTO } from './dto/upsert-cashbox-export-subscription.dto';
import { CashboxExportService } from './cashbox-export.service';
import { CashboxExportSubscriptionService } from './cashbox-export-subscription.service';

type AuthenticatedRequest = { user: { id: number } };

@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'))
@Controller({ path: 'cashbox-export', version: '1' })
export class CashboxExportController {
  constructor(
    private readonly service: CashboxExportService,
    private readonly subscriptionService: CashboxExportSubscriptionService,
  ) {}

  @Get(':teamId')
  async exportCashbox(
    @Request() request: AuthenticatedRequest,
    @Param('teamId', ParseIntPipe) teamId: number,
    @Query() query: CashboxExportQueryDto,
    @Res({ passthrough: false }) res: Response,
  ): Promise<void> {
    const { buffer, contentType, filename } = await this.service.exportForUser(
      teamId,
      request.user.id,
      query.from,
      query.to,
      query.format,
    );
    res.set({
      'Content-Type': contentType,
      'Content-Disposition': `attachment; filename="${filename}"`,
    });
    res.send(buffer);
  }

  @Get(':teamId/subscription')
  getSubscription(
    @Request() request: AuthenticatedRequest,
    @Param('teamId', ParseIntPipe) teamId: number,
  ) {
    return this.subscriptionService.getSubscription(teamId, request.user.id);
  }

  @Put(':teamId/subscription')
  upsertSubscription(
    @Request() request: AuthenticatedRequest,
    @Param('teamId', ParseIntPipe) teamId: number,
    @Body() dto: UpsertCashboxExportSubscriptionDTO,
  ) {
    return this.subscriptionService.upsertSubscription(teamId, request.user.id, dto);
  }
}
