import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";

export type BibleVerse = { verse: number; text: string };
export type BiblePassage = {
  reference: string;
  translation: string;
  verses: BibleVerse[];
  fullText: string;
  error?: string;
};

type CacheEntry = { data: BiblePassage; expires: number };
const cache = new Map<string, CacheEntry>();
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;

const SUPPORTED = new Set(["kjv", "web", "asv", "bbe", "ylt", "darby"]);

export const getBiblePassage = createServerFn({ method: "GET" })
  .inputValidator(
    z.object({
      reference: z.string().min(1).max(120),
      translation: z.string().min(2).max(10).default("kjv").optional(),
    })
  )
  .handler(async ({ data }): Promise<BiblePassage> => {
    const reference = data.reference.trim();
    const translation = (data.translation ?? "kjv").toLowerCase();
    const tx = SUPPORTED.has(translation) ? translation : "kjv";
    const key = `${reference}::${tx}`;
    const now = Date.now();
    const hit = cache.get(key);
    if (hit && hit.expires > now) return hit.data;

    try {
      const url = `https://bible-api.com/${encodeURIComponent(reference)}?translation=${tx}`;
      const res = await fetch(url);
      if (!res.ok) {
        return {
          reference,
          translation: tx.toUpperCase(),
          verses: [],
          fullText: "",
          error: `Upstream ${res.status}`,
        };
      }
      const json = (await res.json()) as {
        reference?: string;
        text?: string;
        translation_id?: string;
        translation_name?: string;
        verses?: Array<{ verse: number; text: string }>;
      };
      const verses: BibleVerse[] = Array.isArray(json.verses)
        ? json.verses.map((v) => ({
            verse: Number(v.verse) || 0,
            text: String(v.text ?? "").trim(),
          }))
        : [];
      const passage: BiblePassage = {
        reference: json.reference || reference,
        translation: (json.translation_id || tx).toUpperCase(),
        verses,
        fullText: String(json.text ?? verses.map((v) => v.text).join(" ")).trim(),
      };
      cache.set(key, { data: passage, expires: now + THIRTY_DAYS });
      return passage;
    } catch (e) {
      console.error("getBiblePassage failed", reference, e);
      return {
        reference,
        translation: tx.toUpperCase(),
        verses: [],
        fullText: "",
        error: "Network error",
      };
    }
  });
