import {
  Body,
  Controller,
  Get,
  Param,
  ParseUUIDPipe,
  Patch,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import { Permissions } from '../../auth/decorators/permissions.decorator';
import { AccessLevel, ModuleName } from '../../entities/role-permission.entity';
import { successResponse } from '../../common/responses/api-response';
import { BookingCashCollectionService } from './booking-cash-collection.service';
import { UpsertBookingCashCollectionDto } from './dto/upsert-booking-cash-collection.dto';
import { ConfirmCollectionDto } from './dto/confirm-collection.dto';
import { ConfirmMdCashDto } from './dto/confirm-md-cash.dto';
import { VoidConfirmationDto } from './dto/void-confirmation.dto';

@Controller('booking-cash-collections')
@UseGuards(JwtAuthGuard, PermissionGuard)
export class BookingCashCollectionController {
  constructor(private readonly service: BookingCashCollectionService) {}

  @Get('booking/:bookingId/parties')
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.VIEW,
  })
  async parties(@Param('bookingId', ParseUUIDPipe) bookingId: string) {
    const data = await this.service.listParties(bookingId);
    return successResponse(data, 'Cash collection parties fetched');
  }

  @Get('booking/:bookingId')
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.VIEW,
  })
  async findByBooking(
    @Param('bookingId', ParseUUIDPipe) bookingId: string,
    @Query('date') date: string,
    @Query('transport_item_id') transportItemId?: string,
    @Query('activity_item_id') activityItemId?: string,
    @Query('special_item_id') specialItemId?: string,
  ) {
    const ids = [transportItemId, activityItemId, specialItemId].filter(Boolean);
    if (ids.length !== 1) {
      return successResponse(null, 'No cash collection');
    }
    const line = transportItemId
      ? { kind: 'TRANSPORT' as const, item_id: transportItemId }
      : activityItemId
        ? { kind: 'ACTIVITY' as const, item_id: activityItemId }
        : { kind: 'SPECIAL' as const, item_id: specialItemId! };
    const row = await this.service.findByLine(bookingId, date, line);
    return successResponse(row, row ? 'Cash collection fetched' : 'No cash collection');
  }

  @Post()
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.EDIT,
  })
  async upsert(@Body() dto: UpsertBookingCashCollectionDto) {
    const row = await this.service.upsert(dto);
    return successResponse(row, 'Cash collection requirement saved');
  }

  @Post(':id/confirm')
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.EDIT,
  })
  async confirm(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: ConfirmCollectionDto,
  ) {
    const row = await this.service.confirm(id, dto);
    return successResponse(row, 'Expense confirmed');
  }

  @Post(':id/confirm-cash')
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.EDIT,
  })
  async confirmCash(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: ConfirmMdCashDto,
  ) {
    const data = await this.service.confirmCash(id, dto);
    return successResponse(data, 'Cash collection confirmed');
  }

  @Post(':id/void-confirmation')
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.DELETE,
  })
  async voidConfirmation(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: VoidConfirmationDto,
  ) {
    const row = await this.service.voidLatestConfirmation(id, dto);
    return successResponse(row, 'Confirmation voided — status PENDING');
  }

  @Patch(':id/cancel')
  @Permissions({
    module: ModuleName.PAYMENT_COLLECTION,
    accessLevel: AccessLevel.EDIT,
  })
  async cancel(@Param('id', ParseUUIDPipe) id: string) {
    const row = await this.service.cancel(id);
    return successResponse(row, 'Cash collection cancelled');
  }
}
