import { Prisma } from '@prisma/client';
import { prisma } from '../../../config/database';

interface UpsertData {
  postalCode: string;
  city?: string | null;
  province?: string | null;
  centroidLat?: number | null;
  centroidLng?: number | null;
}

export const postalCodesService = {
  async upsert(data: UpsertData) {
    return prisma.postalCodeCache.upsert({
      where: { postalCode: data.postalCode },
      update: {
        city: data.city ?? undefined,
        province: data.province ?? undefined,
        centroidLat: data.centroidLat ?? undefined,
        centroidLng: data.centroidLng ?? undefined,
        lastUpdated: new Date(),
      },
      create: {
        postalCode: data.postalCode,
        city: data.city ?? null,
        province: data.province ?? null,
        centroidLat: data.centroidLat ?? null,
        centroidLng: data.centroidLng ?? null,
      },
    });
  },

  async findByPostalCode(code: string) {
    return prisma.postalCodeCache.findUnique({
      where: { postalCode: code },
    });
  },

  async findAll(filters: { page: number; limit: number; search?: string }) {
    const { page, limit, search } = filters;
    const skip = (page - 1) * limit;

    const where: Prisma.PostalCodeCacheWhereInput = {};
    if (search) {
      where.OR = [
        { postalCode: { contains: search, mode: 'insensitive' } },
        { city: { contains: search, mode: 'insensitive' } },
        { province: { contains: search, mode: 'insensitive' } },
      ];
    }

    const [items, total] = await Promise.all([
      prisma.postalCodeCache.findMany({
        where,
        skip,
        take: limit,
        orderBy: { lastUpdated: 'desc' },
      }),
      prisma.postalCodeCache.count({ where }),
    ]);

    return {
      postalCodes: items,
      pagination: { page, limit, total, totalPages: Math.ceil(total / limit) },
    };
  },

  async delete(code: string) {
    return prisma.postalCodeCache.delete({
      where: { postalCode: code },
    });
  },
};
