import { useMemo, useState, useEffect, useCallback } from "react";
import { KoenigComposer, KoenigEditor, CardMenuPlugin } from "@tryghost/koenig-lexical";
import "koenig-styles";
import makeFileUploader from "./useFileUpload";

export default function Editor({ initialState, onChange, csrfToken, uploadUrls, oembedUrl, unsplashApiKey, snippetsUrl }) {
  const fileUploader = useMemo(() => makeFileUploader(csrfToken, uploadUrls), [csrfToken, uploadUrls]);

  const [snippets, setSnippets] = useState([]);

  useEffect(() => {
    if (!snippetsUrl) return;
    fetch(snippetsUrl, { headers: { "X-CSRFToken": csrfToken || "" } })
      .then((r) => r.ok ? r.json() : [])
      .then(setSnippets)
      .catch(() => {});
  }, [snippetsUrl, csrfToken]);

  const createSnippet = useCallback(async ({ name, value }) => {
    if (!snippetsUrl) return;
    const resp = await fetch(snippetsUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-CSRFToken": csrfToken || "",
      },
      body: JSON.stringify({ name, value: JSON.stringify(value) }),
    });
    if (!resp.ok) return;
    const created = await resp.json();
    setSnippets((prev) => {
      const idx = prev.findIndex((s) => s.name === created.name);
      if (idx >= 0) {
        const next = [...prev];
        next[idx] = created;
        return next;
      }
      return [...prev, created].sort((a, b) => a.name.localeCompare(b.name));
    });
  }, [snippetsUrl, csrfToken]);

  const cardConfig = useMemo(() => ({
    fetchEmbed: async (url, { type } = {}) => {
      const params = new URLSearchParams({ url });
      if (type) params.set("type", type);
      const resp = await fetch(`${oembedUrl}?${params}`, {
        headers: { "X-CSRFToken": csrfToken || "" },
      });
      if (!resp.ok) return {};
      return resp.json();
    },
    unsplash: unsplashApiKey
      ? { defaultHeaders: { Authorization: `Client-ID ${unsplashApiKey}` } }
      : false,
    membersEnabled: true,
    snippets: snippets.map((s) => ({
      id: s.id,
      name: s.name,
      value: typeof s.value === "string" ? JSON.parse(s.value) : s.value,
    })),
    createSnippet,
  }), [oembedUrl, csrfToken, unsplashApiKey, snippets, createSnippet]);

  return (
    <KoenigComposer
      initialEditorState={initialState || undefined}
      fileUploader={fileUploader}
      cardConfig={cardConfig}
    >
      <KoenigEditor
        onChange={(serializedState) => {
          if (onChange) {
            onChange(JSON.stringify(serializedState));
          }
        }}
      >
        <CardMenuPlugin />
      </KoenigEditor>
    </KoenigComposer>
  );
}
