import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { getRequest } from "@tanstack/react-start/server";
import { createClient } from "@supabase/supabase-js";
import type { Database } from "@/integrations/supabase/types";

// Catalog of allowed product analytics events. Add to the union when introducing
// a new event; rejected values are silently dropped server-side.
const EVENT_NAMES = [
  "signup",
  "login",
  "onboarding_completed",
  "first_photoshoot",
  "photoshoot_plan_generated",
  "moodboard_image_generated",
  "plan_saved",
  "pdf_exported",
  "share_link_created",
  "upgrade_clicked",
  "checkout_completed",
] as const;

const TrackSchema = z.object({
  event: z.enum(EVENT_NAMES),
  props: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.null()])).optional(),
});

// Public server fn: accepts optional bearer; resolves user_id when present.
// Writes via admin client because analytics_events denies client writes.
export const trackEvent = createServerFn({ method: "POST" })
  .inputValidator((d: unknown) => TrackSchema.parse(d))
  .handler(async ({ data }) => {
    let userId: string | null = null;
    try {
      const req = getRequest();
      const auth = req?.headers?.get("authorization");
      if (auth?.startsWith("Bearer ")) {
        const token = auth.slice(7);
        const sb = createClient<Database>(
          process.env.SUPABASE_URL!,
          process.env.SUPABASE_PUBLISHABLE_KEY!,
          { auth: { persistSession: false, autoRefreshToken: false } },
        );
        const { data: claims } = await sb.auth.getClaims(token);
        userId = (claims?.claims?.sub as string | undefined) ?? null;
      }
    } catch {
      // best-effort user resolution; anonymous events are allowed
    }

    try {
      const { supabaseAdmin } = await import("@/integrations/supabase/client.server");
      await supabaseAdmin.from("analytics_events").insert({
        user_id: userId,
        event: data.event,
        props: (data.props ?? {}) as never,
      });
    } catch (e) {
      console.error("[analytics] insert failed:", e);
    }
    return { ok: true };
  });
