// ============================================================
// Lexware Office - Vouchers REST Controller
// ============================================================

import {
  Controller,
  Get,
  Post,
  Delete,
  Body,
  Param,
  Query,
  ParseUUIDPipe,
  HttpCode,
  HttpStatus,
  UseGuards,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiParam,
} from '@nestjs/swagger';
import { TenantGuard } from '../auth/guards/tenant.guard';
import { CurrentUser, JwtPayload } from '../common/decorators';
import {
  paginatedResponse,
  singleResponse,
} from '../common/dto/pagination.dto';
import { LexwareVouchersService } from './lexware-vouchers.service';
import { QueryLexwareVouchersDto } from './dto/query-lexware-vouchers.dto';
import { LinkDealVoucherDto } from './dto/link-deal-voucher.dto';

@ApiTags('Lexware Office - Belege')
@ApiBearerAuth('access-token')
@UseGuards(TenantGuard)
@Controller('lexware/vouchers')
export class LexwareVouchersController {
  constructor(private readonly service: LexwareVouchersService) {}

  // --------------------------------------------------------
  // Belege abrufen
  // --------------------------------------------------------

  @Get('company/:companyId')
  @ApiOperation({ summary: 'Lexware-Belege fuer Unternehmen abrufen (Cache)' })
  @ApiParam({ name: 'companyId', type: 'string', format: 'uuid' })
  async getForCompany(
    @CurrentUser() user: JwtPayload,
    @Param('companyId', ParseUUIDPipe) companyId: string,
    @Query() query: QueryLexwareVouchersDto,
  ) {
    const result = await this.service.getVouchersForCompany(
      user.tenantId!,
      companyId,
      query,
    );
    return paginatedResponse(
      result.data,
      result.total,
      result.page,
      result.pageSize,
    );
  }

  @Get('contact/:contactId')
  @ApiOperation({ summary: 'Lexware-Belege fuer Kontakt abrufen (Cache)' })
  @ApiParam({ name: 'contactId', type: 'string', format: 'uuid' })
  async getForContact(
    @CurrentUser() user: JwtPayload,
    @Param('contactId', ParseUUIDPipe) contactId: string,
    @Query() query: QueryLexwareVouchersDto,
  ) {
    const result = await this.service.getVouchersForContact(
      user.tenantId!,
      contactId,
      query,
    );
    return paginatedResponse(
      result.data,
      result.total,
      result.page,
      result.pageSize,
    );
  }

  @Get('deal/:dealId')
  @ApiOperation({ summary: 'Lexware-Belege fuer Vorgang abrufen' })
  @ApiParam({ name: 'dealId', type: 'string', format: 'uuid' })
  async getForDeal(
    @CurrentUser() user: JwtPayload,
    @Param('dealId', ParseUUIDPipe) dealId: string,
    @Query() query: QueryLexwareVouchersDto,
  ) {
    const result = await this.service.getVouchersForDeal(
      user.tenantId!,
      dealId,
      query,
    );
    return paginatedResponse(
      result.data,
      result.total,
      result.page,
      result.pageSize,
    );
  }

  // --------------------------------------------------------
  // Beleg mit Vorgang verknuepfen / trennen
  // --------------------------------------------------------

  @Post('deal/:dealId/link')
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({ summary: 'Lexware-Beleg mit Vorgang verknuepfen' })
  @ApiParam({ name: 'dealId', type: 'string', format: 'uuid' })
  async linkToDeal(
    @CurrentUser() user: JwtPayload,
    @Param('dealId', ParseUUIDPipe) dealId: string,
    @Body() dto: LinkDealVoucherDto,
  ) {
    const result = await this.service.linkVoucherToDeal(
      user.tenantId!,
      dealId,
      dto.voucherId,
      user.sub,
    );
    return singleResponse(result);
  }

  @Delete('deal/:dealId/unlink/:voucherId')
  @ApiOperation({ summary: 'Lexware-Beleg von Vorgang trennen' })
  @ApiParam({ name: 'dealId', type: 'string', format: 'uuid' })
  @ApiParam({ name: 'voucherId', type: 'string', format: 'uuid' })
  async unlinkFromDeal(
    @CurrentUser() user: JwtPayload,
    @Param('dealId', ParseUUIDPipe) dealId: string,
    @Param('voucherId', ParseUUIDPipe) voucherId: string,
  ) {
    const result = await this.service.unlinkVoucherFromDeal(
      user.tenantId!,
      dealId,
      voucherId,
    );
    return singleResponse(result);
  }

  // --------------------------------------------------------
  // Cache manuell aktualisieren
  // --------------------------------------------------------

  @Post('refresh/company/:companyId')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Beleg-Cache fuer Unternehmen manuell aktualisieren',
  })
  @ApiParam({ name: 'companyId', type: 'string', format: 'uuid' })
  async refreshCompany(
    @CurrentUser() user: JwtPayload,
    @Param('companyId', ParseUUIDPipe) companyId: string,
  ) {
    const count = await this.service.refreshCompanyVouchers(
      user.tenantId!,
      companyId,
    );
    return {
      success: true,
      data: { refreshedCount: count },
      meta: { timestamp: new Date().toISOString() },
    };
  }

  @Post('refresh/contact/:contactId')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Beleg-Cache fuer Kontakt manuell aktualisieren' })
  @ApiParam({ name: 'contactId', type: 'string', format: 'uuid' })
  async refreshContact(
    @CurrentUser() user: JwtPayload,
    @Param('contactId', ParseUUIDPipe) contactId: string,
  ) {
    const count = await this.service.refreshContactVouchers(
      user.tenantId!,
      contactId,
    );
    return {
      success: true,
      data: { refreshedCount: count },
      meta: { timestamp: new Date().toISOString() },
    };
  }
}
