// ---------------------------------------------------------------------------
// Generic atomic NodeView
//
// Renders any "atomic" component (no editable children) as a placeholder
// card showing the component type, icon, and its field values.
// ---------------------------------------------------------------------------

import React, { useCallback } from "react";
import { NodeViewWrapper } from "@tiptap/react";
import type { NodeViewProps } from "@tiptap/react";
import type { ComponentDef, ComponentField } from "./registry";

function AtomicFieldRow({
  field,
  value,
  onChange,
}: {
  field: ComponentField;
  value: unknown;
  onChange: (val: unknown) => void;
}) {
  if (field.type === "boolean") {
    return (
      <label
        style={{
          display: "flex",
          alignItems: "center",
          gap: 6,
          fontSize: 12,
          color: "var(--muted-color)",
          cursor: "pointer",
        }}
      >
        <input
          type="checkbox"
          checked={!!value}
          onChange={(e) => onChange(e.target.checked)}
          style={{ accentColor: "var(--primary-color)" }}
        />
        {field.label}
      </label>
    );
  }

  if (field.type === "select" && field.options) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <span style={{ fontSize: 12, color: "var(--muted-color)", minWidth: 60 }}>{field.label}</span>
        <select
          value={String(value ?? field.default ?? "")}
          onChange={(e) => onChange(e.target.value)}
          style={{
            background: "var(--surface-bg)",
            border: "1px solid var(--border-color)",
            borderRadius: 4,
            color: "var(--text-color)",
            fontSize: 12,
            padding: "2px 6px",
            outline: "none",
            flex: 1,
          }}
        >
          {field.options.map((opt) => (
            <option key={opt} value={opt}>{opt}</option>
          ))}
        </select>
      </div>
    );
  }

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

export function makeAtomicView(def: ComponentDef) {
  function AtomicNodeView({ node, updateAttributes }: NodeViewProps) {
    const handleFieldChange = useCallback(
      (fieldName: string, value: unknown) => {
        updateAttributes({ [fieldName]: value });
      },
      [updateAttributes],
    );

    const primaryField = def.fields.find((f) => f.name === "src" || f.name === "title") || def.fields[0];
    const primaryValue = primaryField ? String(node.attrs[primaryField.name] || "") : "";

    return (
      <NodeViewWrapper data-component={def.name}>
        <div
          contentEditable={false}
          style={{
            border: "1px dashed var(--border-color)",
            borderRadius: 8,
            background: "var(--surface-bg)",
            margin: "0.75em 0",
            padding: "12px 16px",
            userSelect: "none",
          }}
        >
          {/* Header */}
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: def.fields.length > 0 ? 10 : 0 }}>
            <span style={{ fontSize: 16, lineHeight: 1 }}>{def.icon}</span>
            <span style={{ fontSize: 13, fontWeight: 600, color: "var(--text-color)" }}>
              {def.label}
            </span>
            {primaryValue && (
              <span style={{ fontSize: 12, color: "var(--muted-color)", fontFamily: "monospace" }}>
                {primaryValue}
              </span>
            )}
          </div>

          {/* Fields */}
          {def.fields.length > 0 && (
            <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
              {def.fields.map((f) => (
                <AtomicFieldRow
                  key={f.name}
                  field={f}
                  value={node.attrs[f.name]}
                  onChange={(v) => handleFieldChange(f.name, v)}
                />
              ))}
            </div>
          )}
        </div>
      </NodeViewWrapper>
    );
  }

  AtomicNodeView.displayName = `${def.tag}View`;
  return AtomicNodeView;
}
