// ---------------------------------------------------------------------------
// HfUser NodeView
//
// WYSIWYG rendition of the Hugging Face user card, mirroring the DOM
// emitted by `app/src/components/HfUser.astro` in the upstream
// research-article-template so what you see in the editor matches
// what the publisher writes.
//
// Why a dedicated view (vs. the generic AtomicView):
//   The generic placeholder shows a dashed card with form fields,
//   which made authors guess what the final block looks like. The
//   upstream component is small and visual (avatar + name + handle),
//   so it's worth reproducing inline and revealing the form only
//   when the node is selected (or when the username is still empty,
//   right after insertion).
//
// Anchors:
//   We use <span> instead of <a> inside the editor so accidental
//   clicks don't navigate away from the document. The publisher
//   transformer (publisher/transformers/hf-user.ts) re-renders the
//   same DOM with real <a href> tags for the static HTML output.
// ---------------------------------------------------------------------------

import { useCallback } from "react";
import { NodeViewWrapper } from "@tiptap/react";
import type { NodeViewProps } from "@tiptap/react";

function FieldRow({
  label,
  value,
  placeholder,
  onChange,
}: {
  label: string;
  value: string;
  placeholder?: string;
  onChange: (val: string) => void;
}) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
      <span
        style={{
          fontSize: 12,
          color: "var(--muted-color)",
          minWidth: 90,
        }}
      >
        {label}
      </span>
      <input
        type="text"
        value={value}
        placeholder={placeholder ?? label}
        onChange={(e) => onChange(e.target.value)}
        style={{
          flex: 1,
          minWidth: 0,
          padding: "4px 8px",
          background: "var(--page-bg)",
          border: "1px solid var(--border-color)",
          borderRadius: 4,
          color: "var(--text-color)",
          fontSize: 13,
          outline: "none",
        }}
      />
    </div>
  );
}

export function HfUserNodeView({
  node,
  updateAttributes,
  selected,
}: NodeViewProps) {
  const username = String(node.attrs.username || "").trim();
  const name = String(node.attrs.name || "").trim();
  const url = String(node.attrs.url || "").trim();

  const displayName = name || username || "username";
  const avatarSrc = username
    ? `https://huggingface.co/api/users/${encodeURIComponent(username)}/avatar`
    : "";
  const urlPlaceholder = username
    ? `https://huggingface.co/${username}`
    : "https://huggingface.co/…";

  const handleAttr = useCallback(
    (key: string) => (value: string) => updateAttributes({ [key]: value }),
    [updateAttributes],
  );

  // Show the inline editor on selection or while the card is empty
  // (right after insertion, prompting the author to fill at least
  // the username).
  const showEditor = selected || !username;

  return (
    <NodeViewWrapper data-component="hfUser">
      <div contentEditable={false} style={{ margin: "0.75em 0" }}>
        <div
          className="hf-user"
          style={
            selected
              ? {
                  outline: "2px solid var(--primary-color)",
                  outlineOffset: 2,
                  borderRadius: 12,
                }
              : undefined
          }
        >
          <div className="hf-user__left">
            {avatarSrc ? (
              <img
                className="hf-user__avatar"
                src={avatarSrc}
                alt={`${displayName} avatar`}
                width={44}
                height={44}
                loading="lazy"
                decoding="async"
                referrerPolicy="no-referrer"
              />
            ) : (
              <div
                className="hf-user__avatar"
                aria-hidden="true"
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  background: "var(--surface-bg)",
                  color: "var(--muted-color)",
                  fontSize: 18,
                  fontWeight: 700,
                }}
              >
                ?
              </div>
            )}
            <span className="hf-user__text">
              <span className="hf-user__name">{displayName}</span>
              <span className="hf-user__row">
                <span className="hf-user__username">
                  @{username || "username"}
                </span>
              </span>
            </span>
          </div>
        </div>

        {showEditor && (
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              gap: 6,
              marginTop: 8,
              padding: "10px 12px",
              border: "1px dashed var(--border-color)",
              borderRadius: 8,
              background: "var(--surface-bg)",
              maxWidth: 360,
            }}
          >
            <FieldRow
              label="Username"
              value={username}
              placeholder="username"
              onChange={handleAttr("username")}
            />
            <FieldRow
              label="Display name"
              value={name}
              placeholder="Full Name"
              onChange={handleAttr("name")}
            />
            <FieldRow
              label="URL"
              value={url}
              placeholder={urlPlaceholder}
              onChange={handleAttr("url")}
            />
          </div>
        )}
      </div>
    </NodeViewWrapper>
  );
}

HfUserNodeView.displayName = "HfUserView";
