import { BadRequestException, Injectable } from '@nestjs/common';
import { CacheKeys } from '../common/utils/cache-keys';
import { PrismaService } from '../prisma/prisma.service';
import { RedisService } from '../redis/redis.service';

@Injectable()
export class LocationsService {
  constructor(
    private readonly prisma: PrismaService,
    private readonly redis: RedisService,
  ) {}

  async countries() {
    const cached = await this.redis.getJson(CacheKeys.countries);
    if (cached) return { message: 'Countries fetched successfully', data: cached };
    const rows = await this.prisma.offlineMap.findMany({
      where: this.availableMapWhere(),
      distinct: ['countryName'],
      select: { countryName: true, countryCode: true },
      orderBy: { countryName: 'asc' },
    });
    const data = rows.map((row) => ({ name: row.countryName, code: row.countryCode ?? null, flag: '', region: '' }));
    await this.redis.setJson(CacheKeys.countries, data, 900);
    return { message: 'Countries fetched successfully', data };
  }

  async states(country: string) {
    if (!country?.trim()) throw new BadRequestException('country query param is required');
    const key = CacheKeys.states(country);
    const cached = await this.redis.getJson(key);
    if (cached) return { message: 'States fetched successfully', data: cached };
    const rows = await this.prisma.offlineMap.findMany({
      where: {
        ...this.availableMapWhere(),
        countryName: { equals: country.trim(), mode: 'insensitive' },
      },
      distinct: ['stateName'],
      select: { stateName: true },
      orderBy: { stateName: 'asc' },
    });
    const data = rows.map((row) => ({ name: row.stateName }));
    await this.redis.setJson(key, data, 900);
    return { message: 'States fetched successfully', data };
  }

  private availableMapWhere() {
    return {
      status: 'ACTIVE' as const,
      uploadStatus: 'COMPLETED' as const,
      deletedAt: null,
    };
  }
}
