"use server";

import { db } from "@/lib/db";
import { revalidatePath } from "next/cache";
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
import { randomUUID } from "node:crypto";

function slugify(value: string): string {
  return value
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/(^-|-$)/g, "");
}

function normalizeImageUrl(value: string): string {
  const input = value.trim();
  if (!input) return "";
  if (input.startsWith("http://") || input.startsWith("https://") || input.startsWith("data:") || input.startsWith("blob:")) return input;
  if (input.startsWith("//")) return `https:${input}`;
  if (input.startsWith("/")) return input;
  return `/${input}`;
}

async function saveUpload(file: File, subfolder: "tour-packages" | "tour-slides"): Promise<string> {
  if (!file || file.size === 0) throw new Error("No file uploaded");
  if (!file.type.startsWith("image/")) throw new Error("Only image uploads are allowed");

  const ext = path.extname(file.name || "").toLowerCase() || ".jpg";
  const safeExt = ext.replace(/[^.a-z0-9]/g, "") || ".jpg";
  const fileName = `${Date.now()}-${randomUUID()}${safeExt}`;
  const dir = path.join(process.cwd(), "public", "uploads", subfolder);

  await mkdir(dir, { recursive: true });
  const bytes = Buffer.from(await file.arrayBuffer());
  await writeFile(path.join(dir, fileName), bytes);

  return `/uploads/${subfolder}/${fileName}`;
}

// Categories

export async function saveTourCategoryAction(formData: FormData) {
  const id = String(formData.get("id") || "").trim();
  const name = String(formData.get("name") || "").trim();
  const slugRaw = String(formData.get("slug") || "").trim();

  if (!name) return { ok: false, error: "Category name is required" };
  const slug = slugRaw || slugify(name);

  if (id) {
    await db.tourCategory.update({ where: { id }, data: { name, slug } });
  } else {
    await db.tourCategory.create({ data: { name, slug } });
  }

  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

export async function deleteTourCategoryAction(id: string) {
  await db.tourCategory.delete({ where: { id } });
  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

// Countries

export async function saveTourCountryAction(formData: FormData) {
  const id = String(formData.get("id") || "").trim();
  const name = String(formData.get("name") || "").trim();
  const slugRaw = String(formData.get("slug") || "").trim();

  if (!name) return { ok: false, error: "Country name is required" };
  const slug = slugRaw || slugify(name);

  if (id) {
    await db.tourCountry.update({ where: { id }, data: { name, slug } });
  } else {
    await db.tourCountry.create({ data: { name, slug } });
  }

  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

export async function deleteTourCountryAction(id: string) {
  try {
    await db.tourCountry.delete({ where: { id } });
    revalidatePath("/admin/tours");
    revalidatePath("/tours");
    return { ok: true };
  } catch {
    return { ok: false, error: "Country is in use by cities or packages." };
  }
}

// Cities

export async function saveTourCityAction(formData: FormData) {
  const id = String(formData.get("id") || "").trim();
  const name = String(formData.get("name") || "").trim();
  const slugRaw = String(formData.get("slug") || "").trim();
  const countryId = String(formData.get("countryId") || "").trim();

  if (!name) return { ok: false, error: "City name is required" };
  if (!countryId) return { ok: false, error: "Country is required" };
  const slug = slugRaw || slugify(name);

  if (id) {
    await db.tourCity.update({ where: { id }, data: { name, slug, countryId } });
  } else {
    await db.tourCity.create({ data: { name, slug, countryId } });
  }

  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

export async function deleteTourCityAction(id: string) {
  try {
    await db.tourCity.delete({ where: { id } });
    revalidatePath("/admin/tours");
    revalidatePath("/tours");
    return { ok: true };
  } catch {
    return { ok: false, error: "City is in use by packages." };
  }
}

// Packages

export async function saveTourPackageAction(formData: FormData) {
  const id = String(formData.get("id") || "").trim();
  const title = String(formData.get("title") || "").trim();
  const slugRaw = String(formData.get("slug") || "").trim();
  const destinationRaw = String(formData.get("destination") || "").trim();
  const duration = String(formData.get("duration") || "").trim() || null;
  const description = String(formData.get("description") || "").trim() || null;
  const itinerary = String(formData.get("itinerary") || "").trim() || null;
  const inclusions = String(formData.get("inclusions") || "").trim() || null;
  const exclusions = String(formData.get("exclusions") || "").trim() || null;
  const pricePerPax = Number(formData.get("pricePerPax") || 0);
  const minPax = Number(formData.get("minPax") || 1) || 1;
  const maxPaxRaw = String(formData.get("maxPax") || "").trim();
  const maxPax = maxPaxRaw ? Number(maxPaxRaw) : null;
  const isFeatured = String(formData.get("isFeatured") || "false") === "true";
  const isActive = String(formData.get("isActive") || "true") === "true";
  const categoryId = String(formData.get("categoryId") || "").trim() || null;
  const countryId = String(formData.get("countryId") || "").trim() || null;
  const cityId = String(formData.get("cityId") || "").trim() || null;

  const imagesRaw = String(formData.get("images") || "").trim();
  const imageUrls = imagesRaw
    .split("\n")
    .map((s) => normalizeImageUrl(s))
    .filter(Boolean);

  if (!title) return { ok: false, error: "Package title is required" };
  if (!pricePerPax || Number.isNaN(pricePerPax)) return { ok: false, error: "Valid price is required" };

  let destination: string | null = destinationRaw || null;
  if (countryId || cityId) {
    const [country, city] = await Promise.all([
      countryId ? db.tourCountry.findUnique({ where: { id: countryId }, select: { name: true } }) : Promise.resolve(null),
      cityId ? db.tourCity.findUnique({ where: { id: cityId }, select: { name: true } }) : Promise.resolve(null),
    ]);
    const cityName = city?.name || "";
    const countryName = country?.name || "";
    destination = [cityName, countryName].filter(Boolean).join(", ") || destination;
  }

  const slug = slugRaw || slugify(title);

  const payload = {
    title,
    slug,
    destination,
    duration,
    description,
    itinerary,
    inclusions,
    exclusions,
    pricePerPax,
    minPax,
    maxPax,
    isFeatured,
    isActive,
    categoryId,
    countryId,
    cityId,
  };

  if (id) {
    await db.tourPackage.update({ where: { id }, data: payload });
    await db.tourImage.deleteMany({ where: { packageId: id } });
    if (imageUrls.length) {
      await db.tourImage.createMany({
        data: imageUrls.map((url, idx) => ({ packageId: id, url, isPrimary: idx === 0, sortOrder: idx })),
      });
    }
  } else {
    const created = await db.tourPackage.create({ data: payload });
    if (imageUrls.length) {
      await db.tourImage.createMany({
        data: imageUrls.map((url, idx) => ({ packageId: created.id, url, isPrimary: idx === 0, sortOrder: idx })),
      });
    }
  }

  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

export async function deleteTourPackageAction(id: string) {
  await db.tourPackage.delete({ where: { id } });
  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

// Slider

export async function saveTourSlideAction(formData: FormData) {
  const id = String(formData.get("id") || "").trim();
  const imageUrlRaw = String(formData.get("imageUrl") || "").trim();
  const imageFile = formData.get("imageFile") as File | null;
  const title = String(formData.get("title") || "").trim() || null;
  const subtitle = String(formData.get("subtitle") || "").trim() || null;
  const ctaText = String(formData.get("ctaText") || "").trim() || null;
  const ctaLink = String(formData.get("ctaLink") || "").trim() || null;
  const sortOrder = Number(formData.get("sortOrder") || 0) || 0;
  const isActive = String(formData.get("isActive") || "true") === "true";

  const uploaded = imageFile && imageFile.size > 0 ? await saveUpload(imageFile, "tour-slides") : "";
  const imageUrl = normalizeImageUrl(uploaded || imageUrlRaw);
  if (!imageUrl) return { ok: false, error: "Provide image URL or upload an image." };

  const data = { imageUrl, title, subtitle, ctaText, ctaLink, sortOrder, isActive };

  if (id) {
    await db.tourSlide.update({ where: { id }, data });
  } else {
    await db.tourSlide.create({ data });
  }

  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

export async function deleteTourSlideAction(id: string) {
  await db.tourSlide.delete({ where: { id } });
  revalidatePath("/admin/tours");
  revalidatePath("/tours");
  return { ok: true };
}

// Bookings CRM

export async function updateTourBookingStatusAction(id: string, status: "enquiry" | "confirmed" | "completed" | "cancelled") {
  await db.tourBooking.update({ where: { id }, data: { status } });
  revalidatePath("/admin/tours");
  return { ok: true };
}

export async function deleteTourBookingAction(id: string) {
  await db.tourBooking.delete({ where: { id } });
  revalidatePath("/admin/tours");
  return { ok: true };
}

export async function uploadTourPackageImageAction(formData: FormData) {
  const imageFile = formData.get("imageFile") as File | null;
  if (!imageFile || imageFile.size === 0) {
    return { ok: false, error: "No image file selected" };
  }

  try {
    const url = await saveUpload(imageFile, "tour-packages");
    return { ok: true, url };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to upload" };
  }
}
