import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { createClient } from "@supabase/supabase-js";
import { customAlphabet } from "nanoid";
import { requireSupabaseAuth } from "@/integrations/supabase/auth-middleware";
import type { Database } from "@/integrations/supabase/types";
import type { PhotoshootInput, PhotoshootPlan } from "./photoshoot-data";
import type { MoodboardImages } from "./moodboard.functions";

const slug = customAlphabet("abcdefghijklmnopqrstuvwxyz0123456789", 10);

export const togglePublicShare = createServerFn({ method: "POST" })
  .middleware([requireSupabaseAuth])
  .inputValidator((d: unknown) => z.object({ id: z.string().uuid(), makePublic: z.boolean() }).parse(d))
  .handler(async ({ data, context }) => {
    const { data: row, error: readErr } = await context.supabase
      .from("photoshoots")
      .select("id, share_slug, is_public")
      .eq("id", data.id)
      .single();
    if (readErr) throw new Error(readErr.message);

    let nextSlug = row.share_slug;
    if (data.makePublic && !nextSlug) nextSlug = slug();

    const { error } = await context.supabase
      .from("photoshoots")
      .update({ is_public: data.makePublic, share_slug: nextSlug })
      .eq("id", data.id);
    if (error) throw new Error(error.message);
    return { isPublic: data.makePublic, slug: nextSlug };
  });

export interface PublicPhotoshoot {
  title: string;
  storyTitle: string;
  storyNarrative: string;
  input: PhotoshootInput;
  plan: PhotoshootPlan;
  moodboardImages: MoodboardImages | null;
}

export const getPublicPhotoshoot = createServerFn({ method: "GET" })
  .inputValidator((d: unknown) => z.object({ slug: z.string().min(4).max(40) }).parse(d))
  .handler(async ({ data }): Promise<PublicPhotoshoot | null> => {
    const url = process.env.SUPABASE_URL;
    const key = process.env.SUPABASE_PUBLISHABLE_KEY;
    if (!url || !key) throw new Error("Missing Supabase server env");
    const client = createClient<Database>(url, key, {
      auth: { storage: undefined, persistSession: false, autoRefreshToken: false },
    });
    const { data: row, error } = await client
      .from("photoshoots")
      .select("title, input, plan, moodboard_images, is_public, share_slug")
      .eq("share_slug", data.slug)
      .eq("is_public", true)
      .maybeSingle();
    if (error) throw new Error(error.message);
    if (!row) return null;
    const plan = row.plan as unknown as PhotoshootPlan;
    return {
      title: row.title,
      storyTitle: plan.storyTitle,
      storyNarrative: plan.storyNarrative,
      input: row.input as unknown as PhotoshootInput,
      plan,
      moodboardImages: (row.moodboard_images as MoodboardImages | null) ?? null,
    };
  });
