"use server";

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

type SeedJournal = {
  slug: string;
  title: string;
  excerpt: string;
  content: string;
  coverImage: string;
  category: string;
  isFeatured: boolean;
  publishedAt: string;
};

const PUBLIC_SEED_JOURNALS: SeedJournal[] = [
  {
    slug: "mastering-job-hunt-in-malaysia",
    title: "Mastering the Job Hunt in Malaysia: A Complete Guide",
    excerpt:
      "A step-by-step breakdown of how to navigate Malaysia's job market, build your resume, and land interviews at top companies.",
    content:
      "A practical guide covering resume structure, targeted job applications, interview preparation, and follow-up strategies tailored for Malaysia's current hiring landscape.",
    coverImage: "https://images.unsplash.com/photo-1521737604893-d14cc237f11d?w=600&q=80",
    category: "Career",
    isFeatured: true,
    publishedAt: "2026-05-28T00:00:00.000Z",
  },
  {
    slug: "scholarship-application-tips",
    title: "10 Tips to Win International Scholarships",
    excerpt:
      "From crafting a compelling personal statement to acing interviews — the strategies that helped our members secure full scholarships.",
    content:
      "This article outlines scholarship search strategy, statement writing, recommendation planning, and interview readiness to improve acceptance outcomes.",
    coverImage: "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=600&q=80",
    category: "Education",
    isFeatured: true,
    publishedAt: "2026-05-25T00:00:00.000Z",
  },
  {
    slug: "top-online-business-ideas-2026",
    title: "Top 10 Online Business Ideas for 2026",
    excerpt:
      "The digital economy is booming. Here are the most promising business models for Malaysian entrepreneurs this year.",
    content:
      "Explore validated online business models, market-fit checks, basic financial planning, and launch playbooks suitable for first-time founders.",
    coverImage: "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=600&q=80",
    category: "Business",
    isFeatured: true,
    publishedAt: "2026-05-20T00:00:00.000Z",
  },
  {
    slug: "work-life-balance-remote",
    title: "Finding Work-Life Balance as a Remote Worker",
    excerpt:
      "Remote work is here to stay. Learn how to set boundaries, stay productive, and avoid burnout while working from home.",
    content:
      "A tactical framework for schedule control, async communication, digital boundaries, and wellbeing routines in remote teams.",
    coverImage: "https://images.unsplash.com/photo-1484788984921-03950022c9ef?w=600&q=80",
    category: "Lifestyle",
    isFeatured: true,
    publishedAt: "2026-05-15T00:00:00.000Z",
  },
  {
    slug: "ai-in-recruitment-2026",
    title: "How AI is Changing Recruitment in Southeast Asia",
    excerpt:
      "Artificial Intelligence is reshaping how companies hire. Discover what candidates and recruiters need to know in 2026.",
    content:
      "Understand resume parsing, AI screening criteria, interview automation, and the practical implications for applicants and HR teams.",
    coverImage: "https://images.unsplash.com/photo-1677442135703-1787eea5ce01?w=600&q=80",
    category: "Technology",
    isFeatured: true,
    publishedAt: "2026-05-12T00:00:00.000Z",
  },
  {
    slug: "research-methodology-guide",
    title: "A Beginner's Guide to Research Methodology",
    excerpt:
      "Whether you're writing a thesis or conducting industry research, this guide walks you through the key methodologies.",
    content:
      "Covers qualitative, quantitative, and mixed-methods design, sampling, data collection, and how to choose valid methods per objective.",
    coverImage: "https://images.unsplash.com/photo-1456513080510-7bf3a84b82f8?w=600&q=80",
    category: "Education",
    isFeatured: true,
    publishedAt: "2026-05-08T00:00:00.000Z",
  },
  {
    slug: "malaysia-startup-ecosystem",
    title: "Malaysia's Startup Ecosystem in 2026",
    excerpt:
      "An overview of funding trends, growth sectors, and opportunities for founders and operators in Malaysia.",
    content:
      "A snapshot of accelerators, investor behavior, and sector momentum with practical notes for early-stage teams.",
    coverImage: "https://images.unsplash.com/photo-1559136555-9303baea8ebd?w=400&q=80",
    category: "Business",
    isFeatured: false,
    publishedAt: "2026-05-05T00:00:00.000Z",
  },
  {
    slug: "stem-education-future",
    title: "STEM Education and the Future of Work",
    excerpt:
      "How STEM skill development maps to emerging job demand and long-term employability.",
    content:
      "Reviews curriculum priorities, project-based learning, and industry alignment for future-ready graduates.",
    coverImage: "https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=400&q=80",
    category: "Education",
    isFeatured: false,
    publishedAt: "2026-05-02T00:00:00.000Z",
  },
  {
    slug: "mental-health-workplace",
    title: "Mental Health in the Malaysian Workplace",
    excerpt:
      "A practical look at burnout prevention, psychological safety, and sustainable performance.",
    content:
      "Discusses policy, leadership behaviors, and team rituals that improve retention and workplace wellbeing.",
    coverImage: "https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=400&q=80",
    category: "Lifestyle",
    isFeatured: false,
    publishedAt: "2026-04-28T00:00:00.000Z",
  },
  {
    slug: "fintech-trends-2026",
    title: "Fintech Trends Reshaping Personal Finance",
    excerpt:
      "Key fintech product shifts and behavior changes impacting everyday finance decisions.",
    content:
      "Examines payments, savings, lending, and embedded finance trends with user-level implications.",
    coverImage: "https://images.unsplash.com/photo-1563986768609-322da13575f3?w=400&q=80",
    category: "Technology",
    isFeatured: false,
    publishedAt: "2026-04-25T00:00:00.000Z",
  },
];

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, folder: "journal-slides" | "shop-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", folder);

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

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

// ─── CATEGORIES ──────────────────────────────────────────────────────────────

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

  try {
    if (id) {
      await db.journalCategory.update({ where: { id }, data: { name, slug } });
    } else {
      await db.journalCategory.create({ data: { name, slug } });
    }
    revalidatePath("/admin/journals");
    return { ok: true };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to save category" };
  }
}

export async function deleteCategoryAction(id: string) {
  try {
    await db.journalCategory.delete({ where: { id } });
    revalidatePath("/admin/journals");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

// ─── JOURNALS ────────────────────────────────────────────────────────────────

export async function saveJournalAction(data: FormData) {
  const id = data.get("id") as string | null;
  const title = data.get("title") as string;
  const slug = data.get("slug") as string;
  const excerpt = data.get("excerpt") as string;
  const content = data.get("content") as string;
  const coverImage = data.get("coverImage") as string;
  const categoryId = data.get("categoryId") as string;
  const status = data.get("status") as "draft" | "published" | "flagged";
  const authorId = data.get("authorId") as string;
  const isFeatured = data.get("isFeatured") === "true";

  try {
    const journalData = {
      title,
      slug,
      excerpt,
      content,
      coverImage: coverImage || null,
      categoryId: categoryId || null,
      status,
      isFeatured,
      publishedAt: status === "published" ? new Date() : null,
    };

    if (id) {
      await db.journal.update({ where: { id }, data: journalData });
    } else {
      await db.journal.create({ data: { ...journalData, authorId } });
    }
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to save journal" };
  }
}

export async function deleteJournalAction(id: string) {
  try {
    await db.journal.delete({ where: { id } });
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

export async function toggleJournalFeatured(id: string, isFeatured: boolean) {
  try {
    await db.journal.update({ where: { id }, data: { isFeatured } });
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

export async function importPublicSeedJournalsAction() {
  try {
    const adminUser = await db.user.findFirst({ where: { role: "admin" }, select: { id: true } });
    const fallbackUser = adminUser ?? (await db.user.findFirst({ select: { id: true } }));

    if (!fallbackUser) {
      return { ok: false, error: "No user found to assign as author." };
    }

    const categoryByName = new Map<string, string>();
    for (const categoryName of [...new Set(PUBLIC_SEED_JOURNALS.map((j) => j.category))]) {
      const slug = categoryName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
      const category = await db.journalCategory.upsert({
        where: { slug },
        update: { name: categoryName },
        create: { name: categoryName, slug },
        select: { id: true },
      });
      categoryByName.set(categoryName, category.id);
    }

    let imported = 0;
    let updated = 0;

    for (const item of PUBLIC_SEED_JOURNALS) {
      const existing = await db.journal.findUnique({ where: { slug: item.slug }, select: { id: true } });
      const data = {
        title: item.title,
        excerpt: item.excerpt,
        content: item.content,
        coverImage: normalizeImageUrl(item.coverImage) || null,
        categoryId: categoryByName.get(item.category) ?? null,
        status: "published" as const,
        isFeatured: item.isFeatured,
        publishedAt: new Date(item.publishedAt),
      };

      if (existing) {
        await db.journal.update({ where: { id: existing.id }, data });
        updated += 1;
      } else {
        await db.journal.create({ data: { ...data, slug: item.slug, authorId: fallbackUser.id } });
        imported += 1;
      }
    }

    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true, imported, updated };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to import journals" };
  }
}

// ─── SLIDER ──────────────────────────────────────────────────────────────────

export async function saveSlideAction(data: FormData) {
  const id = data.get("id") as string | null;
  const imageUrlRaw = data.get("imageUrl") as string;
  const imageFile = data.get("imageFile") as File | null;
  const title = data.get("title") as string;
  const subtitle = data.get("subtitle") as string;
  const ctaText = data.get("ctaText") as string;
  const ctaLink = data.get("ctaLink") as string;
  const sortOrder = parseInt(data.get("sortOrder") as string) || 0;
  const isActive = data.get("isActive") === "true";

  try {
    const uploadedImage = imageFile && imageFile.size > 0 ? await storeUploadedImage(imageFile, "journal-slides") : null;
    const imageUrl = normalizeImageUrl(uploadedImage ?? imageUrlRaw);
    if (!imageUrl) {
      return { ok: false, error: "Provide an image URL or upload an image." };
    }

    const slideData = { imageUrl, title, subtitle, ctaText, ctaLink, sortOrder, isActive };
    if (id) {
      await db.journalSlide.update({ where: { id }, data: slideData });
    } else {
      await db.journalSlide.create({ data: slideData });
    }
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to save slide" };
  }
}

export async function deleteSlideAction(id: string) {
  try {
    await db.journalSlide.delete({ where: { id } });
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

// ─── PUBLICATIONS ────────────────────────────────────────────────────────────

export async function savePublicationAction(data: FormData) {
  const id = data.get("id") as string | null;
  const name = data.get("name") as string;
  const description = data.get("description") as string;
  const logoUrl = data.get("logoUrl") as string;
  const websiteUrl = data.get("websiteUrl") as string;
  const sortOrder = parseInt(data.get("sortOrder") as string) || 0;
  const isActive = data.get("isActive") === "true";

  try {
    const pubData = { name, description, logoUrl, websiteUrl, sortOrder, isActive };
    if (id) {
      await db.publication.update({ where: { id }, data: pubData });
    } else {
      await db.publication.create({ data: pubData });
    }
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to save publication" };
  }
}

export async function deletePublicationAction(id: string) {
  try {
    await db.publication.delete({ where: { id } });
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

// ─── TESTIMONIALS ────────────────────────────────────────────────────────────

export async function saveTestimonialAction(data: FormData) {
  const id = data.get("id") as string | null;
  const name = data.get("name") as string;
  const position = data.get("position") as string;
  const company = data.get("company") as string;
  const content = data.get("content") as string;
  const avatarUrl = data.get("avatarUrl") as string;
  const rating = parseInt(data.get("rating") as string) || 5;
  const isActive = data.get("isActive") === "true";

  try {
    const testimonialData = { name, position, company, content, avatarUrl, rating, isActive };
    if (id) {
      await db.journalTestimonial.update({ where: { id }, data: testimonialData });
    } else {
      await db.journalTestimonial.create({ data: testimonialData });
    }
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch (err: unknown) {
    return { ok: false, error: err instanceof Error ? err.message : "Failed to save testimonial" };
  }
}

export async function deleteTestimonialAction(id: string) {
  try {
    await db.journalTestimonial.delete({ where: { id } });
    revalidatePath("/admin/journals");
    revalidatePath("/journal");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

// ─── SUBSCRIBERS ─────────────────────────────────────────────────────────────

export async function toggleSubscriberActive(id: string, isActive: boolean) {
  try {
    await db.journalSubscriber.update({ where: { id }, data: { isActive } });
    revalidatePath("/admin/journals");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}

export async function deleteSubscriberAction(id: string) {
  try {
    await db.journalSubscriber.delete({ where: { id } });
    revalidatePath("/admin/journals");
    return { ok: true };
  } catch {
    return { ok: false };
  }
}
