import {
  Controller,
  Get,
  Post,
  Param,
  Body,
  Query,
  Request,
  Ip,
  Headers,
} from '@nestjs/common';
import type { Request as ExpressRequest } from 'express';
import { Public } from '@common/decorators/public.decorator';
import { CheckinService } from '../services/checkin.service';
import { GeocodingService } from '../services/geocoding.service';
import { CheckinDto, GuestCheckinDto } from '../dto/checkin.dto';

@Controller('site-attendance/checkpoints/code')
export class SiteAttendanceCheckinController {
  constructor(
    private readonly checkinService: CheckinService,
    private readonly geocodingService: GeocodingService,
  ) {}

  @Get(':code/public')
  @Public()
  async getPublicCheckpoint(
    @Param('code') code: string,
    @Query('t') qrToken?: string,
    @Query('ticket') ticket?: string,
  ) {
    return this.checkinService.getPublicCheckpoint(code, { qrToken, ticket });
  }

  @Get(':code/user-search')
  @Public()
  async searchUsers(
    @Param('code') code: string,
    @Query('q') query: string,
  ) {
    return this.checkinService.searchUsers(code, query);
  }

  @Get(':code/today-events')
  @Public()
  async getTodayEvents(
    @Param('code') code: string,
    @Query('userId') userId: string,
  ) {
    return this.checkinService.getTodayEvents(code, userId);
  }

  @Post(':code/checkin')
  async checkin(
    @Param('code') code: string,
    @Body() dto: CheckinDto,
    @Request() req: ExpressRequest,
    @Ip() ip: string,
    @Headers('user-agent') userAgent: string,
  ) {
    const user = req.user as { userId?: string; id?: string } | undefined;
    const userId = user?.userId ?? user?.id;
    return this.checkinService.checkin(code, dto, userId!, ip, userAgent);
  }

  @Get('geocode/search')
  @Public()
  async searchPlaces(
    @Query('q') query: string,
    @Query('lang') lang?: string,
  ) {
    return this.geocodingService.searchPlaces(query, lang);
  }

  @Get('geocode/reverse')
  @Public()
  async reverseGeocode(
    @Query('lat') lat: string,
    @Query('lon') lon: string,
    @Query('lang') lang?: string,
  ) {
    return this.geocodingService.reverseGeocode(Number(lat), Number(lon), lang);
  }

  @Post(':code/guest-checkin')
  @Public()
  async guestCheckin(
    @Param('code') code: string,
    @Body() dto: GuestCheckinDto,
    @Ip() ip: string,
    @Headers('user-agent') userAgent: string,
  ) {
    return this.checkinService.guestCheckin(code, dto, ip, userAgent);
  }
}
