"use client";

import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Link from "@tiptap/extension-link";
import Image from "@tiptap/extension-image";
import Placeholder from "@tiptap/extension-placeholder";
import Underline from "@tiptap/extension-underline";
import { useEffect, useRef, useState } from "react";
import {
  Bold,
  Italic,
  Underline as UnderlineIcon,
  Heading1,
  Heading2,
  Heading3,
  List,
  ListOrdered,
  Quote,
  Code,
  Link as LinkIcon,
  Image as ImageIcon,
  Minus,
  Undo,
  Redo,
  type LucideIcon,
} from "lucide-react";

interface BlockCommand {
  id: string;
  title: string;
  description: string;
  icon: LucideIcon;
  command: (e: ReturnType<typeof useEditor> & object) => void;
}

const SLASH_BLOCKS: BlockCommand[] = [
  {
    id: "h1",
    title: "Başlık 1",
    description: "Büyük başlık",
    icon: Heading1,
    command: (e) => e.chain().focus().deleteRange({ from: 0, to: 0 }).toggleHeading({ level: 1 }).run(),
  },
  {
    id: "h2",
    title: "Başlık 2",
    description: "Orta başlık",
    icon: Heading2,
    command: (e) => e.chain().focus().toggleHeading({ level: 2 }).run(),
  },
  {
    id: "h3",
    title: "Başlık 3",
    description: "Küçük başlık",
    icon: Heading3,
    command: (e) => e.chain().focus().toggleHeading({ level: 3 }).run(),
  },
  {
    id: "ul",
    title: "Madde listesi",
    description: "Bullet list",
    icon: List,
    command: (e) => e.chain().focus().toggleBulletList().run(),
  },
  {
    id: "ol",
    title: "Numaralı liste",
    description: "Ordered list",
    icon: ListOrdered,
    command: (e) => e.chain().focus().toggleOrderedList().run(),
  },
  {
    id: "quote",
    title: "Alıntı",
    description: "Blockquote",
    icon: Quote,
    command: (e) => e.chain().focus().toggleBlockquote().run(),
  },
  {
    id: "code",
    title: "Kod bloğu",
    description: "Code block",
    icon: Code,
    command: (e) => e.chain().focus().toggleCodeBlock().run(),
  },
  {
    id: "hr",
    title: "Ayırıcı",
    description: "Yatay çizgi",
    icon: Minus,
    command: (e) => e.chain().focus().setHorizontalRule().run(),
  },
];

export function RichEditor({
  name,
  defaultValue,
  placeholder = "İçeriği yazmaya başlayın… `/` ile blok seç",
  minHeight = 400,
}: {
  name: string;
  defaultValue?: string | null;
  placeholder?: string;
  minHeight?: number;
}) {
  const [html, setHtml] = useState<string>(defaultValue ?? "");
  const [showSlash, setShowSlash] = useState(false);
  const [slashQuery, setSlashQuery] = useState("");
  const [slashIndex, setSlashIndex] = useState(0);
  const [imageModal, setImageModal] = useState(false);

  const editor = useEditor({
    extensions: [
      StarterKit.configure({
        heading: { levels: [1, 2, 3] },
      }),
      Underline,
      Link.configure({
        openOnClick: false,
        HTMLAttributes: { class: "text-[var(--sky-600)] underline" },
      }),
      Image.configure({
        HTMLAttributes: { class: "rounded-xl my-4" },
      }),
      Placeholder.configure({ placeholder }),
    ],
    content: defaultValue || "",
    editorProps: {
      attributes: {
        class:
          "prose prose-base max-w-none focus:outline-none px-6 py-6 min-h-[400px]",
      },
    },
    onUpdate: ({ editor }) => {
      setHtml(editor.getHTML());
    },
    immediatelyRender: false,
  });

  // Slash menu detection
  useEffect(() => {
    if (!editor) return;
    const onUpdate = () => {
      const { $from } = editor.state.selection;
      const lineText = $from.parent.textContent;
      const beforeCursor = lineText.slice(0, $from.parentOffset);
      const match = beforeCursor.match(/\/(\w*)$/);
      if (match) {
        setShowSlash(true);
        setSlashQuery(match[1].toLowerCase());
        setSlashIndex(0);
      } else {
        setShowSlash(false);
      }
    };
    editor.on("update", onUpdate);
    editor.on("selectionUpdate", onUpdate);
    return () => {
      editor.off("update", onUpdate);
      editor.off("selectionUpdate", onUpdate);
    };
  }, [editor]);

  const filteredBlocks = SLASH_BLOCKS.filter(
    (b) =>
      !slashQuery ||
      b.title.toLowerCase().includes(slashQuery) ||
      b.id.includes(slashQuery),
  );

  // Slash menu keyboard
  useEffect(() => {
    if (!showSlash || !editor) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        setShowSlash(false);
        e.preventDefault();
        return;
      }
      if (e.key === "ArrowDown") {
        setSlashIndex((i) => Math.min(i + 1, filteredBlocks.length - 1));
        e.preventDefault();
        return;
      }
      if (e.key === "ArrowUp") {
        setSlashIndex((i) => Math.max(i - 1, 0));
        e.preventDefault();
        return;
      }
      if (e.key === "Enter") {
        const block = filteredBlocks[slashIndex];
        if (block) {
          e.preventDefault();
          // Delete the slash + query first
          const { $from } = editor.state.selection;
          const from = $from.pos - (slashQuery.length + 1);
          editor.chain().focus().deleteRange({ from, to: $from.pos }).run();
          block.command(
            editor as unknown as ReturnType<typeof useEditor> & object,
          );
          setShowSlash(false);
        }
        return;
      }
    };
    window.addEventListener("keydown", handler, true);
    return () => window.removeEventListener("keydown", handler, true);
  }, [showSlash, slashIndex, filteredBlocks, editor, slashQuery]);

  if (!editor) return null;

  return (
    <div>
      <input type="hidden" name={name} value={html} />

      <div className="overflow-hidden rounded-2xl border border-[var(--border)] bg-white">
        {/* Top toolbar — always visible, fixed */}
        <div className="flex flex-wrap items-center gap-0.5 border-b border-[var(--border)] bg-[var(--navy-50)]/40 p-2">
          <ToolbarButton
            active={editor.isActive("bold")}
            onClick={() => editor.chain().focus().toggleBold().run()}
            icon={Bold}
            label="Kalın (⌘B)"
          />
          <ToolbarButton
            active={editor.isActive("italic")}
            onClick={() => editor.chain().focus().toggleItalic().run()}
            icon={Italic}
            label="İtalik (⌘I)"
          />
          <ToolbarButton
            active={editor.isActive("underline")}
            onClick={() => editor.chain().focus().toggleUnderline().run()}
            icon={UnderlineIcon}
            label="Altı çizili"
          />
          <Divider />
          <ToolbarButton
            active={editor.isActive("heading", { level: 1 })}
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 1 }).run()
            }
            icon={Heading1}
            label="Başlık 1"
          />
          <ToolbarButton
            active={editor.isActive("heading", { level: 2 })}
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 2 }).run()
            }
            icon={Heading2}
            label="Başlık 2"
          />
          <ToolbarButton
            active={editor.isActive("heading", { level: 3 })}
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 3 }).run()
            }
            icon={Heading3}
            label="Başlık 3"
          />
          <Divider />
          <ToolbarButton
            active={editor.isActive("bulletList")}
            onClick={() => editor.chain().focus().toggleBulletList().run()}
            icon={List}
            label="Madde listesi"
          />
          <ToolbarButton
            active={editor.isActive("orderedList")}
            onClick={() => editor.chain().focus().toggleOrderedList().run()}
            icon={ListOrdered}
            label="Numaralı liste"
          />
          <ToolbarButton
            active={editor.isActive("blockquote")}
            onClick={() => editor.chain().focus().toggleBlockquote().run()}
            icon={Quote}
            label="Alıntı"
          />
          <ToolbarButton
            active={editor.isActive("codeBlock")}
            onClick={() => editor.chain().focus().toggleCodeBlock().run()}
            icon={Code}
            label="Kod"
          />
          <Divider />
          <ToolbarButton
            onClick={() => {
              const previousUrl = editor.getAttributes("link").href;
              const url = window.prompt("URL", previousUrl ?? "https://");
              if (url === null) return;
              if (url === "") {
                editor.chain().focus().extendMarkRange("link").unsetLink().run();
                return;
              }
              editor
                .chain()
                .focus()
                .extendMarkRange("link")
                .setLink({ href: url })
                .run();
            }}
            active={editor.isActive("link")}
            icon={LinkIcon}
            label="Bağlantı"
          />
          <ToolbarButton
            onClick={() => setImageModal(true)}
            icon={ImageIcon}
            label="Görsel ekle"
          />
          <Divider />
          <ToolbarButton
            onClick={() => editor.chain().focus().undo().run()}
            icon={Undo}
            label="Geri al"
          />
          <ToolbarButton
            onClick={() => editor.chain().focus().redo().run()}
            icon={Redo}
            label="İleri al"
          />
        </div>

        <div className="relative">
          <EditorContent editor={editor} style={{ minHeight }} />

          {showSlash && filteredBlocks.length > 0 && (
            <div className="absolute left-6 top-12 z-10 w-72 rounded-xl border border-[var(--border)] bg-white p-1 shadow-xl">
              <p className="px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-[var(--muted)]">
                Blok seç
              </p>
              {filteredBlocks.map((b, i) => {
                const Icon = b.icon;
                return (
                  <button
                    key={b.id}
                    type="button"
                    onMouseEnter={() => setSlashIndex(i)}
                    onClick={() => {
                      const { $from } = editor.state.selection;
                      const from = $from.pos - (slashQuery.length + 1);
                      editor
                        .chain()
                        .focus()
                        .deleteRange({ from, to: $from.pos })
                        .run();
                      b.command(
                        editor as unknown as ReturnType<typeof useEditor> &
                          object,
                      );
                      setShowSlash(false);
                    }}
                    className={`flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm ${
                      i === slashIndex
                        ? "bg-[var(--navy-50)]"
                        : "hover:bg-[var(--navy-50)]/60"
                    }`}
                  >
                    <div className="flex size-8 items-center justify-center rounded-md bg-white text-[var(--navy)]">
                      <Icon className="size-4" />
                    </div>
                    <div>
                      <p className="font-medium text-[var(--navy)]">{b.title}</p>
                      <p className="text-[11px] text-[var(--muted)]">
                        {b.description}
                      </p>
                    </div>
                  </button>
                );
              })}
            </div>
          )}
        </div>

      </div>

      {/* Footer info */}
      <p className="mt-2 text-xs text-[var(--muted)]">
        ‹/› ile blok ekle • Seçili metin için araç çubuğu otomatik açılır
      </p>

      {imageModal && (
        <ImagePickerModal
          onClose={() => setImageModal(false)}
          onPick={(url) => {
            editor.chain().focus().setImage({ src: url }).run();
            setImageModal(false);
          }}
        />
      )}
    </div>
  );
}

function ToolbarButton({
  icon: Icon,
  label,
  active,
  onClick,
}: {
  icon: LucideIcon;
  label: string;
  active?: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      title={label}
      aria-label={label}
      className={`flex size-8 items-center justify-center rounded-md transition ${
        active
          ? "bg-[var(--navy)] text-white"
          : "text-[var(--muted)] hover:bg-white hover:text-[var(--navy)]"
      }`}
    >
      <Icon className="size-4" />
    </button>
  );
}

function Divider() {
  return <div className="mx-1 h-5 w-px bg-[var(--border)]" />;
}

// ─── Image picker — uses media library API ───────────────

interface MediaFile {
  id: string;
  name: string;
  url: string;
}

function ImagePickerModal({
  onClose,
  onPick,
}: {
  onClose: () => void;
  onPick: (url: string) => void;
}) {
  const [files, setFiles] = useState<MediaFile[] | null>(null);
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    fetch("/api/admin/media/list")
      .then((r) => r.json())
      .then((d) => setFiles(d.files || []))
      .catch(() => setFiles([]));
  }, []);

  function handleFile(file: File) {
    setUploading(true);
    setProgress(0);
    const fd = new FormData();
    fd.append("file", file);
    const xhr = new XMLHttpRequest();
    xhr.open("POST", "/api/admin/media/upload");
    xhr.upload.addEventListener("progress", (e) => {
      if (e.lengthComputable) setProgress(Math.round((e.loaded / e.total) * 100));
    });
    xhr.onload = () => {
      try {
        const data = JSON.parse(xhr.responseText);
        if (data.url) {
          onPick(data.url);
        }
      } catch {
        /* ignore */
      }
      setUploading(false);
    };
    xhr.onerror = () => {
      setUploading(false);
    };
    xhr.send(fd);
  }

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4"
      onClick={onClose}
    >
      <div
        className="w-full max-w-3xl rounded-2xl bg-white p-5 shadow-2xl"
        onClick={(e) => e.stopPropagation()}
      >
        <h3 className="text-base font-semibold text-[var(--navy)]">
          Görsel ekle
        </h3>

        <div className="mt-4 flex gap-2">
          <button
            type="button"
            onClick={() => inputRef.current?.click()}
            disabled={uploading}
            className="rounded-full bg-[var(--navy)] px-4 py-2 text-xs font-medium text-white hover:bg-[var(--navy-700)] disabled:opacity-60"
          >
            {uploading ? `Yükleniyor… ${progress}%` : "Yeni görsel yükle"}
          </button>
          <input
            ref={inputRef}
            type="file"
            accept="image/*"
            className="hidden"
            onChange={(e) => {
              const f = e.target.files?.[0];
              if (f) handleFile(f);
              e.target.value = "";
            }}
          />
        </div>

        {uploading && (
          <div className="mt-3 h-1.5 overflow-hidden rounded-full bg-[var(--navy-50)]">
            <div
              className="h-full bg-[var(--sky)] transition-all"
              style={{ width: `${progress}%` }}
            />
          </div>
        )}

        <div className="mt-5 max-h-[60vh] overflow-y-auto">
          <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-[var(--muted)]">
            Kütüphane
          </p>
          {!files ? (
            <p className="py-8 text-center text-sm text-[var(--muted)]">
              Yükleniyor…
            </p>
          ) : files.length === 0 ? (
            <p className="py-8 text-center text-sm text-[var(--muted)]">
              Kütüphane boş. Yeni görsel yükleyin.
            </p>
          ) : (
            <div className="grid grid-cols-3 gap-2 sm:grid-cols-4 lg:grid-cols-5">
              {files.map((f) => (
                <button
                  key={f.id}
                  type="button"
                  onClick={() => onPick(f.url)}
                  className="aspect-square overflow-hidden rounded-lg border border-[var(--border)] transition hover:border-[var(--sky)]"
                >
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={f.url}
                    alt={f.name}
                    className="size-full object-cover"
                    loading="lazy"
                  />
                </button>
              ))}
            </div>
          )}
        </div>

        <div className="mt-4 text-right">
          <button
            type="button"
            onClick={onClose}
            className="rounded-full border border-[var(--border)] bg-white px-4 py-2 text-xs font-medium text-[var(--muted)] hover:text-[var(--navy)]"
          >
            Kapat
          </button>
        </div>
      </div>
    </div>
  );
}
