/* =========================================================================
 *  CTWCAD — File card with cursor-tracked 3D tilt
 * =======================================================================*/
const { useMotionValue: _umv, useSpring: _usp, useTransform: _utr, motion: _m } = window.FramerMotion;

/* Helper — render a name string with a case-insensitive substring of `q`
 * wrapped in <mark> for highlighted search results. Returns either the
 * raw string or an array of nodes; React handles both. */
function highlightName(name, q) {
  if (!q || !name) return name;
  const lower = name.toLowerCase();
  const idx = lower.indexOf(q.toLowerCase());
  if (idx === -1) return name;
  return [
    name.slice(0, idx),
    <mark key="m" className="ct-mark">{name.slice(idx, idx + q.length)}</mark>,
    name.slice(idx + q.length),
  ];
}

/* Inline rename input. Shared by file-card, file-row, folder-card,
 * folder-row. Pre-selects the basename without the file extension on
 * mount (Files.app / Drive convention) so typing replaces the name but
 * keeps the suffix. Enter saves, Esc cancels, blur saves. */
function InlineRename({ initial, onSubmit, onCancel, isFolder }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    el.focus();
    // Pre-select the base, leaving the extension unselected so the user
    // can type a new name without nuking the .step / .stl / etc.
    const dot = isFolder ? -1 : initial.lastIndexOf(".");
    try {
      if (dot > 0) el.setSelectionRange(0, dot);
      else el.select();
    } catch {}
  }, []);
  return (
    <input
      ref={ref}
      className="ct-rename-input ct-mono"
      defaultValue={initial}
      onClick={(e) => e.stopPropagation()}
      onMouseDown={(e) => e.stopPropagation()}
      onDoubleClick={(e) => e.stopPropagation()}
      onKeyDown={(e) => {
        if (e.key === "Enter")  { e.preventDefault(); onSubmit(e.currentTarget.value); }
        else if (e.key === "Escape") { e.preventDefault(); onCancel(); }
      }}
      onBlur={(e) => onSubmit(e.currentTarget.value)}
    />
  );
}

function FileCard({
  file, onOpen, onContextMenu, onDragStart, index = 0,
  selected = false, editing = false, highlight = "",
  onSelect, onStartRename, onSubmitRename, onCancelRename,
}) {
  const ref = useRef(null);
  const mx = window.FramerMotion.useMotionValue(0);
  const my = window.FramerMotion.useMotionValue(0);
  const sx = window.FramerMotion.useSpring(mx, { stiffness: 220, damping: 22 });
  const sy = window.FramerMotion.useSpring(my, { stiffness: 220, damping: 22 });
  const rotX = window.FramerMotion.useTransform(sy, [-0.5, 0.5], [6, -6]);
  const rotY = window.FramerMotion.useTransform(sx, [-0.5, 0.5], [-6, 6]);

  const onMove = (e) => {
    const r = ref.current.getBoundingClientRect();
    mx.set((e.clientX - r.left) / r.width - 0.5);
    my.set((e.clientY - r.top) / r.height - 0.5);
  };
  const onLeave = () => { mx.set(0); my.set(0); };

  // The card-click handler now routes through onSelect when supplied
  // (FileBrowserView uses this to apply ctrl/shift modifier semantics).
  // If onSelect isn't provided, fall back to the legacy onOpen path —
  // recent-files / dashboard surfaces still use that.
  const handleClick = (e) => {
    if (editing) return;
    if (onSelect) onSelect(e);
    else onOpen?.();
  };
  const handleDouble = (e) => {
    // Double-click on the name cell starts inline rename. Anywhere else
    // on the card opens the file (matches Drive's behaviour).
    if (e.target.closest(".ct-card-name")) {
      e.stopPropagation();
      onStartRename?.();
      return;
    }
    onOpen?.();
  };

  const M = window.FramerMotion.motion;
  return (
    <M.div
      ref={ref}
      className={"ct-card " + (selected ? "is-selected " : "") + (editing ? "is-editing" : "")}
      style={{ rotateX: rotX, rotateY: rotY, transformPerspective: 800 }}
      onMouseMove={onMove}
      onMouseLeave={onLeave}
      onClick={handleClick}
      onDoubleClick={handleDouble}
      onContextMenu={(e) => { e.preventDefault(); onContextMenu?.(e, file); }}
      draggable={!editing}
      onDragStart={(e) => onDragStart?.(e, file)}
      initial={{ opacity: 0, y: 12, scale: 0.97 }}
      animate={{ opacity: 1, y: 0, scale: 1 }}
      transition={{ delay: index * 0.04, type: "spring", stiffness: 240, damping: 24 }}
      whileHover={{ y: -4 }}
    >
      {selected && <div className="ct-select-badge"><Icon name="check" size={12}/></div>}
      <div className="ct-card-thumb">
        <CADThumb file={file} />
        <div className="ct-card-actions">
          <button className="ct-iconbtn" title="Open in CTWCAD" onClick={(e) => { e.stopPropagation(); window.open(`ctwcad://open?file_id=${file.id}`, "_self"); }}>
            <Icon name="external-link" size={14} />
          </button>
          <button className="ct-iconbtn" title="Download" onClick={(e) => {
            e.stopPropagation();
            window.dispatchEvent(new CustomEvent("ctwcad:item-action", {
              detail: { action: "download", kind: "file", file },
            }));
          }}>
            <Icon name="download" size={14} />
          </button>
          <button className="ct-iconbtn" title="Share" onClick={(e) => {
            e.stopPropagation();
            window.dispatchEvent(new CustomEvent("ctwcad:item-action", {
              detail: { action: "share", kind: "file", file },
            }));
          }}>
            <Icon name="share-2" size={14} />
          </button>
          <button className="ct-iconbtn" title="More" onClick={(e) => { e.stopPropagation(); onContextMenu?.(e, file); }}>
            <Icon name="more-horizontal" size={14} />
          </button>
        </div>
        {file.shareState !== "private" && (
          <div className="ct-share-pill"><Icon name={file.shareState === "link" ? "link" : "users"} size={11} />
            <span>{file.shareState === "link" ? "Link" : "Project"}</span>
          </div>
        )}
      </div>
      <div className="ct-card-meta">
        {editing ? (
          <InlineRename
            initial={file.name}
            onSubmit={(v) => onSubmitRename?.(v)}
            onCancel={() => onCancelRename?.()}
          />
        ) : (
          <div className="ct-card-name" title={file.name}>{highlightName(file.name, highlight)}</div>
        )}
        {Array.isArray(file.tags) && file.tags.length > 0 && (
          <div className="ct-card-tags">
            {file.tags.slice(0, 4).map(t => (
              <button
                key={t}
                type="button"
                className="ct-card-tag-chip"
                onClick={(e) => {
                  e.stopPropagation();
                  window.dispatchEvent(new CustomEvent("ctwcad:item-action", {
                    detail: { action: "filter-by-tag", kind: "file", file, tag: t },
                  }));
                }}
                title={`Filter by #${t}`}
              >
                #{t}
              </button>
            ))}
            {file.tags.length > 4 && (
              <span className="ct-card-tag-more ct-mono ct-dim">+{file.tags.length - 4}</span>
            )}
          </div>
        )}
        <div className="ct-card-row">
          <span className="ct-mono ct-dim">v{file.versionCount}</span>
          <span className="ct-dot" />
          <span className="ct-mono ct-dim">{fmtBytes(file.sizeBytes)}</span>
          <span className="ct-dot" />
          <span className="ct-dim">{fmtRelative(file.updatedAt)}</span>
        </div>
      </div>
    </M.div>
  );
}

function FileRow({
  file, onOpen, onContextMenu, index,
  selected = false, editing = false, highlight = "",
  onSelect, onStartRename, onSubmitRename, onCancelRename,
}) {
  const M = window.FramerMotion.motion;
  const handleClick = (e) => {
    if (editing) return;
    if (onSelect) onSelect(e);
    else onOpen?.();
  };
  const handleDouble = (e) => {
    if (e.target.closest(".ct-row-name")) {
      e.stopPropagation();
      onStartRename?.();
      return;
    }
    onOpen?.();
  };
  return (
    <M.div
      className={"ct-row " + (selected ? "is-selected" : "")}
      initial={{ opacity: 0, y: 4 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ delay: index * 0.02, duration: 0.25, ease: [0.22, 1, 0.36, 1] }}
      onClick={handleClick}
      onDoubleClick={handleDouble}
      onContextMenu={(e) => { e.preventDefault(); onContextMenu?.(e, file); }}
    >
      <div className="ct-row-thumb"><CADThumb file={file} /></div>
      <div className="ct-row-name">
        {editing ? (
          <InlineRename
            initial={file.name}
            onSubmit={(v) => onSubmitRename?.(v)}
            onCancel={() => onCancelRename?.()}
          />
        ) : (
          <div className="ct-row-title">{highlightName(file.name, highlight)}</div>
        )}
        <div className="ct-row-sub ct-mono ct-dim">v{file.versionCount} · {file.kind}</div>
      </div>
      <div className="ct-row-cell ct-mono ct-dim">{fmtBytes(file.sizeBytes)}</div>
      <div className="ct-row-cell ct-dim">{fmtRelative(file.updatedAt)}</div>
      <div className="ct-row-cell">
        {file.shareState === "private" ? <span className="ct-dim">Private</span> :
         file.shareState === "link" ? <span><Icon name="link" size={12}/> Link</span> :
         <span><Icon name="users" size={12}/> Project</span>}
      </div>
    </M.div>
  );
}

function FolderCard({
  folder, onOpen, onContextMenu, index = 0,
  selected = false, editing = false, highlight = "",
  onSelect, onStartRename, onSubmitRename, onCancelRename,
}) {
  const M = window.FramerMotion.motion;
  const handleClick = (e) => {
    if (editing) return;
    if (onSelect) onSelect(e);
    else onOpen?.();
  };
  const handleDouble = (e) => {
    if (e.target.closest(".ct-card-name")) {
      e.stopPropagation();
      onStartRename?.();
      return;
    }
    onOpen?.();
  };
  return (
    <M.div
      className={"ct-card ct-card-folder " + (selected ? "is-selected " : "") + (editing ? "is-editing" : "")}
      onClick={handleClick}
      onDoubleClick={handleDouble}
      onContextMenu={(e) => { e.preventDefault(); onContextMenu?.(e, folder); }}
      initial={{ opacity: 0, y: 12, scale: 0.97 }}
      animate={{ opacity: 1, y: 0, scale: 1 }}
      transition={{ delay: index * 0.04, type: "spring", stiffness: 240, damping: 24 }}
      whileHover={{ y: -3 }}
      layoutId={`folder-${folder.id}`}
    >
      {selected && <div className="ct-select-badge"><Icon name="check" size={12}/></div>}
      <div className="ct-card-thumb ct-folder-thumb">
        <svg viewBox="0 0 100 70" className="ct-folder-svg">
          <path d="M6 16 L34 16 L40 10 L94 10 L94 60 L6 60 z" fill="none" stroke="currentColor" strokeWidth="0.8"/>
          <path d="M6 24 L94 24" stroke="currentColor" strokeWidth="0.4" opacity="0.4"/>
        </svg>
        <div className="ct-folder-count ct-mono">{folder.childCount} items</div>
      </div>
      <div className="ct-card-meta">
        {editing ? (
          <InlineRename
            initial={folder.name}
            isFolder
            onSubmit={(v) => onSubmitRename?.(v)}
            onCancel={() => onCancelRename?.()}
          />
        ) : (
          <div className="ct-card-name">{highlightName(folder.name, highlight)}</div>
        )}
        <div className="ct-card-row">
          <span className="ct-dim">{fmtRelative(folder.updatedAt)}</span>
        </div>
      </div>
    </M.div>
  );
}

/* List-view counterpart to FolderCard. The previous inline JSX in
 * views-browser didn't support selection / inline rename / highlight,
 * so we promote it to a real component for parity with FileRow. */
function FolderRow({
  folder, onOpen, onContextMenu, index = 0,
  selected = false, editing = false, highlight = "",
  onSelect, onStartRename, onSubmitRename, onCancelRename,
}) {
  const M = window.FramerMotion.motion;
  const handleClick = (e) => {
    if (editing) return;
    if (onSelect) onSelect(e);
    else onOpen?.();
  };
  const handleDouble = (e) => {
    if (e.target.closest(".ct-row-name")) {
      e.stopPropagation();
      onStartRename?.();
      return;
    }
    onOpen?.();
  };
  return (
    <M.div
      className={"ct-row " + (selected ? "is-selected" : "")}
      initial={{ opacity: 0, y: 4 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ delay: index * 0.02, duration: 0.25, ease: [0.22, 1, 0.36, 1] }}
      onClick={handleClick}
      onDoubleClick={handleDouble}
      onContextMenu={(e) => { e.preventDefault(); onContextMenu?.(e, folder); }}
    >
      <div className="ct-row-thumb ct-row-thumb-folder"><Icon name="folder" size={20}/></div>
      <div className="ct-row-name">
        {editing ? (
          <InlineRename
            initial={folder.name}
            isFolder
            onSubmit={(v) => onSubmitRename?.(v)}
            onCancel={() => onCancelRename?.()}
          />
        ) : (
          <div className="ct-row-title">{highlightName(folder.name, highlight)}</div>
        )}
        <div className="ct-row-sub ct-mono ct-dim">{folder.childCount} items</div>
      </div>
      <div className="ct-row-cell ct-dim">—</div>
      <div className="ct-row-cell ct-dim">{fmtRelative(folder.updatedAt)}</div>
      <div className="ct-row-cell ct-dim">Folder</div>
    </M.div>
  );
}

Object.assign(window, { FileCard, FileRow, FolderCard, FolderRow, InlineRename, highlightName });
