import { BadRequestException } from "@nestjs/common";
import { PrismaService } from "./prisma/prisma.service";

export function executionSteps(value: unknown) {
  if (value === undefined || value === null) return [];
  if (!Array.isArray(value) || value.length > 30) throw new BadRequestException("invalid_execution_steps");
  return value.map((step) => {
    const item = typeof step === "string" ? { title: step } : step;
    if (!item || typeof item.title !== "string" || !item.title.trim() || item.title.length > 200) throw new BadRequestException("invalid_execution_steps");
    return { title: item.title.trim(), description: String(item.description ?? "").slice(0, 2000), allowMedia: Boolean(item.allowMedia) };
  });
}

export function coordinates(body: { latitude?: unknown; longitude?: unknown }) {
  if (body.latitude == null && body.longitude == null) return { latitude: null, longitude: null };
  const latitude = Number(body.latitude), longitude = Number(body.longitude);
  if (body.latitude == null || body.longitude == null || !Number.isFinite(latitude) || !Number.isFinite(longitude) || Math.abs(latitude) > 90 || Math.abs(longitude) > 180) throw new BadRequestException("invalid_coordinates");
  return { latitude, longitude };
}

export function validPrice(value: unknown) {
  if (value === null || value === undefined || value === "") return null;
  const price = Number(value);
  if (!Number.isFinite(price) || price < 0 || price > 1_000_000_000) throw new BadRequestException("invalid_price");
  return price;
}

export function validMediaUrls(value: unknown, limit: number) {
  if (value === undefined || value === null) return [];
  if (!Array.isArray(value)) throw new BadRequestException("invalid_media_urls");
  const urls = value.slice(0, limit).map((item) => String(item));
  if (urls.some((url) => !/^\/api\/media\/[a-f0-9-]+\.(?:jpe?g|png|webp)$/i.test(url))) {
    throw new BadRequestException("invalid_media_urls");
  }
  return urls;
}

export async function defaultCurrency(prisma: Pick<PrismaService, "appSetting">): Promise<string> {
  const setting = await prisma.appSetting.findUnique({ where: { key: "currency" } });
  return typeof setting?.value === "string" ? setting.value : "EUR";
}

export async function maximumUploadImages(prisma: Pick<PrismaService, "appSetting">): Promise<number> {
  const setting = await prisma.appSetting.findUnique({ where: { key: "maxUploadImages" } });
  const configured = Number(setting?.value ?? 6);
  return Number.isFinite(configured) ? Math.min(10, Math.max(1, Math.floor(configured))) : 6;
}
