"use client";

import { useState } from "react";
import { useEditor, EditorContent, NodeViewWrapper, NodeViewContent, ReactNodeViewRenderer } from "@tiptap/react";
import { Node, mergeAttributes } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
import CodeBlock from "@tiptap/extension-code-block";
import Image from "@tiptap/extension-image";
import Link from "@tiptap/extension-link";
import Underline from "@tiptap/extension-underline";
import { Copy, Check } from "lucide-react";
import { KinescopePlayer } from "@/components/player/kinescope-player";

function CodeBlockStudentView({ node }: { node: { textContent: string } }) {
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    // WYSIWYG: копируем содержимое блока ровно как показано. Для Obsidian-сниппетов
    // (dataview/query) забор ```...``` хранится прямо в содержимом → копируется целиком.
    try {
      await navigator.clipboard.writeText(node.textContent);
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    } catch {
      // clipboard недоступен (нет https / нет прав) — тихо игнорируем
    }
  };

  return (
    <NodeViewWrapper className="relative group my-4">
      <button
        type="button"
        onClick={handleCopy}
        contentEditable={false}
        aria-label="Скопировать код"
        className="absolute top-2 right-2 z-10 flex items-center gap-1 px-2 py-1 text-xs select-none transition-opacity"
        style={{
          border: "1.5px solid var(--border)",
          background: "var(--background)",
          color: copied ? "var(--foreground)" : "var(--muted-foreground)",
          fontFamily: "var(--font-mono, monospace)",
        }}
      >
        {copied ? <Check size={13} strokeWidth={3} /> : <Copy size={13} />}
        {copied ? "Скопировано" : "Копировать"}
      </button>
      <pre>
        <NodeViewContent<"code"> as="code" />
      </pre>
    </NodeViewWrapper>
  );
}

const CodeBlockWithCopy = CodeBlock.extend({
  addNodeView() {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return ReactNodeViewRenderer(CodeBlockStudentView as any);
  },
});

function KinescopeVideoStudentView({
  node,
  extension,
}: {
  node: { attrs: Record<string, unknown> };
  extension: { options: { poster?: string } };
}) {
  const videoId = node.attrs.videoId as string;
  if (!videoId) return null;
  return (
    <NodeViewWrapper>
      <div className="my-6">
        <KinescopePlayer videoId={videoId} poster={extension.options.poster} />
      </div>
    </NodeViewWrapper>
  );
}

const KinescopeVideoExtension = Node.create<{ poster?: string }>({
  name: "kinescopeVideo",
  group: "block",
  atom: true,

  addOptions() {
    return { poster: undefined };
  },

  addAttributes() {
    return { videoId: { default: "" } };
  },

  parseHTML() {
    return [{ tag: "div[data-kinescope-video]" }];
  },

  renderHTML({ HTMLAttributes }) {
    return ["div", mergeAttributes({ "data-kinescope-video": "" }, HTMLAttributes)];
  },

  addNodeView() {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return ReactNodeViewRenderer(KinescopeVideoStudentView as any);
  },
});

export function LessonContent({ content, coverImage }: { content: object; coverImage?: string | null }) {
  const editor = useEditor({
    extensions: [
      StarterKit.configure({ codeBlock: false }),
      CodeBlockWithCopy,
      Underline,
      Image.configure({ inline: false }),
      Link.configure({ openOnClick: true }),
      KinescopeVideoExtension.configure({ poster: coverImage ?? undefined }),
    ],
    content,
    editable: false,
    editorProps: {
      attributes: {
        class: "prose prose-slate max-w-none focus:outline-none",
      },
    },
  });

  return <EditorContent editor={editor} />;
}
