"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { createReactBlockSpec } from "@blocknote/react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { extractBlockText } from "@/lib/blocks";

type RemoteBlock = {
  id: string;
  type?: string;
  props?: Record<string, unknown>;
  content?: unknown;
  children?: unknown;
};

const isTextBlock = (block: RemoteBlock) => block.type === "paragraph" || block.type === "heading";

export const blockReferenceBlock = createReactBlockSpec(
  {
    type: "blockReference",
    propSchema: {
      sourceDocumentId: { default: "" },
      targetBlockId: { default: "" },
      display: { default: "embed" },
    },
    content: "none",
  },
  () => ({
    render: ({ block }) => <BlockReferenceContent block={block as any} />,
  }),
)();

function BlockReferenceContent({ block }: { block: { props: { sourceDocumentId: string; targetBlockId: string } } }) {
  const router = useRouter();
  const sourceDocumentId = block.props.sourceDocumentId;
  const targetBlockId = block.props.targetBlockId;

  const [remote, setRemote] = useState<RemoteBlock | null>(null);
  const [textDraft, setTextDraft] = useState<string>("");
  const [status, setStatus] = useState<"idle" | "loading" | "error">("idle");
  const [error, setError] = useState<string>("");

  const canEdit = useMemo(() => Boolean(remote && isTextBlock(remote)), [remote]);

  useEffect(() => {
    if (!sourceDocumentId || !targetBlockId) {
      setStatus("error");
      setError("引用信息不完整");
      return;
    }
    let cancelled = false;
    setStatus("loading");
    setError("");
    setRemote(null);

    const run = async () => {
      try {
        const res = await fetch(
          `/api/blocks/get?sourceDocumentId=${encodeURIComponent(sourceDocumentId)}&blockId=${encodeURIComponent(targetBlockId)}`,
          { method: "GET", credentials: "include" },
        );
        if (!res.ok) {
          const payload = await res.json().catch(() => ({}));
          throw new Error(payload?.error ?? "获取引用块失败");
        }
        const json = await res.json();
        const next = (json?.block ?? null) as RemoteBlock | null;
        if (!cancelled) {
          setRemote(next);
          if (next && isTextBlock(next)) {
            setTextDraft(extractBlockText(next as any));
          }
          setStatus("idle");
        }
      } catch (e) {
        if (!cancelled) {
          setStatus("error");
          setError(e instanceof Error ? e.message : "获取引用块失败");
        }
      }
    };

    void run();
    return () => {
      cancelled = true;
    };
  }, [sourceDocumentId, targetBlockId]);

  const openSource = useCallback(() => {
    if (sourceDocumentId) {
      router.push(`/documents/${sourceDocumentId}`);
    }
  }, [router, sourceDocumentId]);

  const saveText = useCallback(async () => {
    if (!remote || !canEdit) return;
    const nextBlock: RemoteBlock = {
      ...remote,
      id: remote.id,
      content: [{ type: "text", text: textDraft }],
    };
    const res = await fetch("/api/blocks/patch", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      body: JSON.stringify({ sourceDocumentId, blockId: targetBlockId, nextBlock }),
    });
    if (!res.ok) {
      const payload = await res.json().catch(() => ({}));
      const msg = payload?.error ?? "同步编辑失败";
      if (typeof window !== "undefined") window.alert(msg);
      return;
    }
    if (typeof window !== "undefined") window.alert("已同步编辑到原块");
  }, [canEdit, remote, sourceDocumentId, targetBlockId, textDraft]);

  return (
    <div
      className="mt-2 rounded-md border border-dashed border-[#cbd5e1] bg-[#fafafa] px-4 py-3"
      onMouseDown={(e) => {
        // 说明：避免点击内部按钮/输入框时误触发编辑器的拖拽/选择。
        e.stopPropagation();
      }}
    >
      <div className="mb-2 flex items-center gap-2 text-xs text-gray-500">
        <span>嵌入引用</span>
        <span className="ml-auto flex items-center gap-2">
          <Button type="button" size="sm" variant="ghost" className="h-7 px-2 text-xs" onClick={openSource}>
            打开原块
          </Button>
        </span>
      </div>

      {status === "loading" ? (
        <div className="text-sm text-gray-400">加载中...</div>
      ) : status === "error" ? (
        <div className="text-sm text-red-600">{error}</div>
      ) : !remote ? (
        <div className="text-sm text-gray-400">引用块不存在</div>
      ) : canEdit ? (
        <div className="space-y-2">
          <textarea
            className="w-full resize-y rounded-md border border-[#e2e8f0] bg-white p-2 text-sm text-gray-900 outline-none"
            rows={3}
            value={textDraft}
            onChange={(e) => setTextDraft(e.target.value)}
            placeholder="在这里编辑会同步到原块（MVP：仅支持段落/标题纯文本）"
          />
          <div className="flex items-center gap-2">
            <Button type="button" size="sm" className="h-8 px-3 text-xs" onClick={() => void saveText()}>
              同步到原块
            </Button>
            <span className="text-[11px] text-gray-400">MVP：仅支持段落/标题纯文本同步</span>
          </div>
        </div>
      ) : (
        <div className="text-sm text-gray-700">
          <div className="mb-1 text-xs text-gray-400">当前块类型：{remote.type ?? "unknown"}</div>
          <div className="text-sm text-gray-800">{extractBlockText(remote as any) || "（内容为空或暂不支持渲染）"}</div>
        </div>
      )}
    </div>
  );
}

