import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  ParseUUIDPipe,
} from '@nestjs/common';
import { QuoteService } from './quote.service';
import { CreateQuoteDto } from './dto/create-quote.dto';
import { UpdateQuoteDto } from './dto/update-quote.dto';
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';

@Controller('queries/:queryId/quotes')
@UseGuards(JwtAuthGuard, PermissionGuard)
export class QuoteController {
  constructor(private readonly service: QuoteService) {}

  @Get('summary')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async findSummaries(@Param('queryId', ParseUUIDPipe) queryId: string) {
    const data = await this.service.findSummaries(queryId);
    return successResponse(data, 'Quote summaries fetched');
  }

  @Get(':quoteId')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async findOne(
    @Param('queryId', ParseUUIDPipe) queryId: string,
    @Param('quoteId', ParseUUIDPipe) quoteId: string,
  ) {
    const data = await this.service.findQuoteDetail(queryId, quoteId);
    return successResponse(data, 'Quote detail fetched');
  }

  @Get()
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async findByQuery(@Param('queryId', ParseUUIDPipe) queryId: string) {
    const data = await this.service.findByQueryId(queryId);
    return successResponse(data, 'Quotes fetched successfully');
  }

  @Post()
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.CREATE })
  async create(@Param('queryId', ParseUUIDPipe) queryId: string, @Body() dto: CreateQuoteDto) {
    const result = await this.service.createQuote(queryId, dto);
    return successResponse(result, result.message);
  }

  @Patch(':quoteId')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.EDIT })
  async update(
    @Param('queryId', ParseUUIDPipe) queryId: string,
    @Param('quoteId', ParseUUIDPipe) quoteId: string,
    @Body() dto: UpdateQuoteDto,
  ) {
    const result = await this.service.updateQuote(queryId, quoteId, dto);
    return successResponse(result, result.message);
  }

  @Delete(':quoteId')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.DELETE })
  async delete(
    @Param('queryId', ParseUUIDPipe) queryId: string,
    @Param('quoteId', ParseUUIDPipe) quoteId: string,
  ) {
    const result = await this.service.deleteQuote(queryId, quoteId);
    return successResponse(result, result.message);
  }

  @Patch(':quoteId/select')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.EDIT })
  async select(
    @Param('queryId', ParseUUIDPipe) queryId: string,
    @Param('quoteId', ParseUUIDPipe) quoteId: string,
  ) {
    const result = await this.service.selectQuote(queryId, quoteId);
    return successResponse(result, result.message);
  }

  @Post(':quoteId/duplicate')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.CREATE })
  async duplicate(
    @Param('queryId', ParseUUIDPipe) queryId: string,
    @Param('quoteId', ParseUUIDPipe) quoteId: string,
  ) {
    const result = await this.service.duplicateQuote(queryId, quoteId);
    return successResponse(result, result.message);
  }
}

@Controller('queries')
@UseGuards(JwtAuthGuard, PermissionGuard)
export class QuotePriceLookupController {
  constructor(private readonly service: QuoteService) {}

  @Get('price-lookup/transport')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async lookupTransportPrice(
    @Query('transport_service_id') transportServiceId: string,
    @Query('vehicle_type_id') vehicleTypeId: string,
    @Query('date') date?: string,
    // Mode is derived from is_shared on the FE line item:
    //   true  → SIC (per-person rate, vehicle_type_id ignored)
    //   false → PVT (per-vehicle rate, vehicle_type_id required)
    // Accept lowercase strings since query params arrive as text;
    // 'true'/'1' both interpreted as SIC for resilience.
    @Query('is_shared') isSharedRaw?: string,
  ) {
    const isShared = isSharedRaw === 'true' || isSharedRaw === '1';
    const result = await this.service.lookupTransportPrice(
      transportServiceId,
      vehicleTypeId,
      date,
      isShared,
    );
    return successResponse(result, 'Price lookup complete');
  }

  @Get('price-lookup/activity')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async lookupActivityPrice(
    @Query('activity_id') activityId: string,
    @Query('ticket_id') ticketId?: string,
    @Query('age_group') ageGroup?: string,
    @Query('date') date?: string,
  ) {
    const result = await this.service.lookupActivityPrice(
      activityId,
      ticketId || null,
      ageGroup || 'adult',
      date,
    );
    return successResponse(result, 'Price lookup complete');
  }

  @Get('exchange-rate')
  @Permissions({ module: ModuleName.QUERY, accessLevel: AccessLevel.VIEW })
  async lookupExchangeRate(
    @Query('from') fromCurrencyId: string,
    @Query('to') toCurrencyId: string,
  ) {
    const result = await this.service.lookupExchangeRate(fromCurrencyId, toCurrencyId);
    return successResponse(result, 'Exchange rate lookup complete');
  }
}
