import { Controller, Get, HttpCode, HttpStatus, Req } from '@nestjs/common';
import { Logger } from 'pino-nestjs';
import { BusinessConfigService } from './businessConfig.service';
import { DeviceService } from '../devices/device.service';
import { GeoService } from '../devices/geo.service';
import { resolveClientIp } from '@/utils/ip';

function readHeader(req: any, key: string): string {
  const rawValue = req.headers[key];
  if (Array.isArray(rawValue)) {
    return String(rawValue[0] || '').trim();
  }
  return String(rawValue || '').trim();
}

@Controller('config')
export class BusinessConfigController {
  constructor(
    private readonly configService: BusinessConfigService,
    private readonly deviceService: DeviceService,
    private readonly geoService: GeoService,
    private readonly logger: Logger,
  ) {}

  // Public, pre-login endpoint — opportunistically registers/updates the
  // calling device so push tokens and version info are captured even before
  // the user signs in. Best-effort: never blocks or fails the config response.
  @Get()
  @HttpCode(HttpStatus.OK)
  getConfig(@Req() req: any) {
    this.trackDevice(req);
    return this.configService.getAppConfig();
  }

  private trackDevice(req: any): void {
    const deviceId = readHeader(req, 'x-device-id') || readHeader(req, 'device-id');
    const expoPushToken = readHeader(req, 'x-expo-push-token') || readHeader(req, 'expo-push-token');
    const platform = readHeader(req, 'x-platform').toLowerCase();
    const appVersion = readHeader(req, 'x-app-version');
    const buildNumber = readHeader(req, 'x-build-number');

    if (!deviceId || (platform !== 'ios' && platform !== 'android') || !appVersion) {
      return;
    }

    const ip = resolveClientIp(req);
    const geo = ip ? this.geoService.lookup(ip) : null;

    this.deviceService
      .upsertDevice({
        device_id: deviceId,
        expo_push_token: expoPushToken || undefined,
        platform,
        app_version: appVersion,
        build_number: buildNumber || undefined,
        ...(geo ? { ip_geo: geo } : {}),
        ...(ip ? { ip } : {}),
        user_id: req.user?.id,
      })
      .catch((error: any) => {
        this.logger.warn('trackDevice: upsertDevice failed (non-blocking)', { message: error?.message });
      });
  }
}
