"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import {
  Editor,
  blocksPlugin,
  outlinePlugin,
  useGetEditor,
  type Route,
} from "@reacteditor/core";
import createTailwindCdnPlugin from "@reacteditor/plugin-tailwind-cdn";
import { aiPlugin } from "@reacteditor/plugin-ai";
import "@reacteditor/core/dist/index.css";
import "~/editor/vendor/plugin-ai.css";
import { createConfig } from "@/editor/config";
import { ShopifyProvider } from "@/editor/contexts/shopify-context";
import { Button } from "@/editor/components/ui/button";

type Schema = Record<string, { root: any; content: any[] }>;

const SHOPIFY_DOMAIN =
  process.env.NEXT_PUBLIC_SHOPIFY_DOMAIN ?? "mock.shop";
const STOREFRONT_TOKEN =
  process.env.NEXT_PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN ?? "";

function SaveButton({
  currentPath,
  onSave,
}: {
  currentPath: string;
  onSave: (route: string, data: any) => Promise<void>;
}) {
  const getEditor = useGetEditor();
  const [saving, setSaving] = useState(false);
  return (
    <Button
      onClick={async () => {
        if (saving) return;
        setSaving(true);
        const data = (getEditor() as any)?.appState?.data;
        if (data) await onSave(currentPath, data);
        await new Promise((r) => setTimeout(r, 1000));
        setSaving(false);
      }}
      disabled={saving}
    >
      {saving ? "Saving…" : "Save"}
    </Button>
  );
}

export default function EditorClient({
  initialSchema,
  initialPath,
}: {
  initialSchema: Schema;
  initialPath: string;
}) {
  const router = useRouter();
  const [schema, setSchema] = useState<Schema>(initialSchema);
  const [currentPath, setCurrentPath] = useState<string>(initialPath);

  const data = useMemo(
    () => schema[currentPath] ?? { root: { props: {} }, content: [] },
    [schema, currentPath],
  );

  const routes: Route[] = useMemo(
    () =>
      Object.entries(schema).map(([path, page]) => ({
        path,
        title:
          (page?.root as any)?.props?.title ??
          (path === "/" ? "Home" : path),
      })),
    [schema],
  );

  const config = useMemo(
    () =>
      createConfig({
        domain: SHOPIFY_DOMAIN,
        token: STOREFRONT_TOKEN || null,
      }),
    [],
  );

  const persist = useCallback(async (route: string, next: any) => {
    setSchema((s) => ({ ...s, [route]: next }));
    await fetch("/api/save-schema", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ route, data: next }),
    });
  }, []);

  const plugins = useMemo(
    () => [
      createTailwindCdnPlugin(),
      aiPlugin({
        api: "/api/chat",
        attachments: true,
        body: { route: currentPath },
      }),
      blocksPlugin(),
      outlinePlugin(),
    ],
    [currentPath],
  );

  return (
    <ShopifyProvider domain={SHOPIFY_DOMAIN} token={STOREFRONT_TOKEN}>
      <Editor
        key={currentPath}
        config={config as any}
        data={data as any}
        plugins={plugins}
        headerPath={currentPath}
        routes={routes}
        currentPath={currentPath}
        onRouteChange={(next) => {
          setCurrentPath(next);
          router.push(`/edit${next === "/" ? "" : next}`);
        }}
        onPublish={async (next) => {
          await persist(currentPath, next);
        }}
        iframe={{ enabled: true }}
        overrides={{
          headerActions: () => (
            <SaveButton currentPath={currentPath} onSave={persist} />
          ),
        }}
      />
    </ShopifyProvider>
  );
}
