"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 slug(name: string) {
  return name.toLowerCase().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 storeUploadedImage(file: File): 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", "shop-slides");

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

  return `/uploads/shop-slides/${fileName}`;
}

// ── Categories ────────────────────────────────────────────────────────────────

export async function saveCategoryAction(formData: FormData) {
  const id = (formData.get("id") as string).trim();
  const name = (formData.get("name") as string).trim();
  const parentId = (formData.get("parentId") as string).trim() || null;
  const s = slug(name);

  if (id) {
    await db.productCategory.update({ where: { id }, data: { name, slug: s, parentId } });
  } else {
    await db.productCategory.create({ data: { name, slug: s, parentId } });
  }
  revalidatePath("/admin/ecommerce");
}

export async function deleteCategoryAction(id: string) {
  await db.productCategory.delete({ where: { id } });
  revalidatePath("/admin/ecommerce");
}

// ── Products ──────────────────────────────────────────────────────────────────

export async function saveProductAction(formData: FormData) {
  const id = (formData.get("id") as string).trim();
  const name = (formData.get("name") as string).trim();
  const description = (formData.get("description") as string).trim() || null;
  const price = parseFloat(formData.get("price") as string) || 0;
  const stock = parseInt(formData.get("stock") as string) || 0;
  const categoryId = (formData.get("categoryId") as string).trim() || null;
  const isFeatured = formData.get("isFeatured") === "true";
  const isActive = formData.get("isActive") !== "false";

  // Images: comma-separated URLs
  const imagesRaw = (formData.get("images") as string ?? "").trim();
  const imageUrls = imagesRaw.split("\n").map(u => u.trim()).filter(Boolean);

  // Variations: JSON string
  const variationsRaw = (formData.get("variations") as string ?? "").trim();
  let variations: { sku?: string; size?: string; colour?: string; price?: number; stock?: number }[] = [];
  try { variations = variationsRaw ? JSON.parse(variationsRaw) : []; } catch { variations = []; }

  const s = slug(name);

  if (id) {
    await db.product.update({
      where: { id },
      data: { name, slug: s, description, price, stock, categoryId, isFeatured, isActive },
    });
    // Sync images: delete old, insert new
    await db.productImage.deleteMany({ where: { productId: id } });
    if (imageUrls.length) {
      await db.productImage.createMany({
        data: imageUrls.map((url, i) => ({ productId: id, url, isPrimary: i === 0, sortOrder: i })),
      });
    }
    // Sync variations
    await db.productVariation.deleteMany({ where: { productId: id } });
    if (variations.length) {
      await db.productVariation.createMany({
        data: variations.map(v => ({
          productId: id,
          sku: v.sku || null,
          size: v.size || null,
          colour: v.colour || null,
          price: v.price ?? null,
          stock: v.stock ?? 0,
        })),
      });
    }
  } else {
    const product = await db.product.create({
      data: { name, slug: s, description, price, stock, categoryId, isFeatured, isActive },
    });
    if (imageUrls.length) {
      await db.productImage.createMany({
        data: imageUrls.map((url, i) => ({ productId: product.id, url, isPrimary: i === 0, sortOrder: i })),
      });
    }
    if (variations.length) {
      await db.productVariation.createMany({
        data: variations.map(v => ({
          productId: product.id,
          sku: v.sku || null,
          size: v.size || null,
          colour: v.colour || null,
          price: v.price ?? null,
          stock: v.stock ?? 0,
        })),
      });
    }
  }
  revalidatePath("/admin/ecommerce");
  revalidatePath("/shop");
}

export async function deleteProductAction(id: string) {
  await db.product.delete({ where: { id } });
  revalidatePath("/admin/ecommerce");
  revalidatePath("/shop");
}

export async function toggleProductFeatured(id: string, isFeatured: boolean) {
  await db.product.update({ where: { id }, data: { isFeatured } });
  revalidatePath("/admin/ecommerce");
  revalidatePath("/shop");
}

// ── Shop Slider ───────────────────────────────────────────────────────────────

export async function saveSlideAction(formData: FormData) {
  const id = (formData.get("id") as string).trim();
  const imageUrlRaw = (formData.get("imageUrl") as string).trim();
  const imageFile = formData.get("imageFile") as File | null;
  const uploadedImage = imageFile && imageFile.size > 0 ? await storeUploadedImage(imageFile) : null;
  const imageUrl = normalizeImageUrl(uploadedImage ?? imageUrlRaw);
  if (!imageUrl) {
    throw new Error("Provide an image URL or upload an image.");
  }

  const data = {
    imageUrl,
    title: (formData.get("title") as string).trim() || null,
    subtitle: (formData.get("subtitle") as string).trim() || null,
    ctaText: (formData.get("ctaText") as string).trim() || null,
    ctaLink: (formData.get("ctaLink") as string).trim() || null,
    isActive: formData.get("isActive") !== "false",
  };
  if (id) {
    await db.shopSlide.update({ where: { id }, data });
  } else {
    const count = await db.shopSlide.count();
    await db.shopSlide.create({ data: { ...data, sortOrder: count } });
  }
  revalidatePath("/admin/ecommerce");
  revalidatePath("/shop");
}

export async function deleteSlideAction(id: string) {
  await db.shopSlide.delete({ where: { id } });
  revalidatePath("/admin/ecommerce");
  revalidatePath("/shop");
}

// ── Orders ────────────────────────────────────────────────────────────────────

export async function updateOrderStatusAction(id: string, status: string) {
  await db.order.update({
    where: { id },
    data: { status: status as never },
  });
  revalidatePath("/admin/ecommerce");
}
