'use client';

import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
import { TextColorIcon, HighlighterIcon, Link02Icon, CodeSimpleIcon, TextClearIcon } from '@zen/core/shared/icons';
import { INLINE_COLORS, INLINE_COLOR_KEYS, markKey } from './types.js';

// Toolbar flottant de formatage. Affiché tant qu'une sélection non-vide
// existe dans un bloc. Ancré au-dessus du rect de sélection ; flip en
// dessous si pas assez de place.
//
// Ne contient pas d'état métier — tous les changements remontent via
// `onToggleMark(mark)`. Le parent recalcule `activeMarks` à chaque rendu.

const TOOLBAR_HEIGHT = 36;
const TOOLBAR_GAP = 8;
const VIEWPORT_MARGIN = 8;

const SIMPLE_BUTTONS = [
  { type: 'bold', label: 'B', title: 'Gras (Ctrl+B)', className: 'font-bold' },
  { type: 'italic', label: 'I', title: 'Italique (Ctrl+I)', className: 'italic' },
  { type: 'underline', label: 'U', title: 'Soulignement (Ctrl+U)', className: 'underline' },
  { type: 'strike', label: 'S', title: 'Barré', className: 'line-through' },
  { type: 'code', label: <CodeSimpleIcon width={15} height={15} />, title: 'Code (Ctrl+E)', className: '' },
];

export default function InlineToolbar({ rect, activeMarks, onToggleMark, onClearMarks, onPinChange, usedColors }) {
  const ref = useRef(null);
  const [pos, setPos] = useState({ top: 0, left: 0, flipped: false });
  const [popover, setPopover] = useState(null); // 'color' | 'highlight' | 'link' | null
  const [linkUrl, setLinkUrl] = useState('');
  const [linkNewTab, setLinkNewTab] = useState(false);

  useEffect(() => {
    onPinChange?.(popover !== null);
  }, [popover, onPinChange]);

  useLayoutEffect(() => {
    if (!rect || typeof window === 'undefined') return;
    const width = ref.current?.offsetWidth ?? 280;
    const height = ref.current?.offsetHeight ?? TOOLBAR_HEIGHT;
    const vw = window.innerWidth;
    const vh = window.innerHeight;
    const spaceAbove = rect.top - VIEWPORT_MARGIN;
    const flipBelow = spaceAbove < height + TOOLBAR_GAP;
    let top = flipBelow
      ? rect.bottom + TOOLBAR_GAP
      : rect.top - height - TOOLBAR_GAP;
    let left = rect.left + rect.width / 2 - width / 2;
    if (left + width + VIEWPORT_MARGIN > vw) left = vw - width - VIEWPORT_MARGIN;
    if (left < VIEWPORT_MARGIN) left = VIEWPORT_MARGIN;
    if (top < VIEWPORT_MARGIN) top = VIEWPORT_MARGIN;
    if (top + height + VIEWPORT_MARGIN > vh) top = vh - height - VIEWPORT_MARGIN;
    setPos({ top, left, flipped: flipBelow });
  }, [rect]);


  function isActive(type, payloadKey) {
    if (!Array.isArray(activeMarks)) return false;
    if (payloadKey) return activeMarks.some(m => markKey(m) === payloadKey);
    return activeMarks.some(m => m.type === type);
  }

  function handleSimple(type) {
    onToggleMark?.({ type });
  }

  function handleColor(color) {
    onToggleMark?.({ type: 'color', color });
    setPopover(null);
  }

  function handleHighlight(color) {
    onToggleMark?.({ type: 'highlight', color });
    setPopover(null);
  }

  function handleLinkSubmit(e) {
    e.preventDefault();
    if (!linkUrl) return;
    onToggleMark?.({ type: 'link', href: linkUrl, newTab: linkNewTab });
    setLinkUrl('');
    setPopover(null);
  }

  function handleLinkRemove() {
    // Trouver la mark active pour reproduire la même clé (toggle off).
    const link = activeMarks.find(m => m.type === 'link');
    if (link) onToggleMark?.({ type: 'link', href: link.href, ...(link.newTab ? { newTab: true } : {}) });
    setPopover(null);
  }

  function openLinkPopover() {
    const link = activeMarks.find(m => m.type === 'link');
    setLinkUrl(link?.href ?? '');
    setLinkNewTab(link ? !!link.newTab : false);
    setPopover(p => (p === 'link' ? null : 'link'));
  }

  return (
    <div
      ref={ref}
      data-inline-toolbar
      className="fixed z-50 flex items-center gap-0.5 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md px-1 py-1"
      style={{ top: pos.top, left: pos.left }}
    >
      {SIMPLE_BUTTONS.map(btn => (
        <button
          key={btn.type}
          type="button"
          title={btn.title}
          onMouseDown={(e) => e.preventDefault()}
          onClick={() => handleSimple(btn.type)}
          className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${btn.className} ${isActive(btn.type) ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
        >
          {btn.label}
        </button>
      ))}

      <span className="mx-1 w-px h-5 bg-neutral-200 dark:bg-neutral-700" aria-hidden />

      <button
        type="button"
        title="Couleur du texte"
        onMouseDown={(e) => e.preventDefault()}
        onClick={() => setPopover(p => (p === 'color' ? null : 'color'))}
        className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('color') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
      >
        <TextColorIcon width={16} height={16} />
      </button>
      <button
        type="button"
        title="Surlignage"
        onMouseDown={(e) => e.preventDefault()}
        onClick={() => setPopover(p => (p === 'highlight' ? null : 'highlight'))}
        className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('highlight') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
      >
        <HighlighterIcon width={16} height={16} />
      </button>
      <button
        type="button"
        title="Lien (Ctrl+K)"
        onMouseDown={(e) => e.preventDefault()}
        onClick={openLinkPopover}
        className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('link') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
      >
        <Link02Icon width={16} height={16} />
      </button>

      <span className="mx-1 w-px h-5 bg-neutral-200 dark:bg-neutral-700" aria-hidden />

      <button
        type="button"
        title="Effacer le formatage"
        onMouseDown={(e) => e.preventDefault()}
        onClick={() => onClearMarks?.()}
        className="w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800"
      >
        <TextClearIcon width={16} height={16} />
      </button>

      {popover === 'color' && (
        <ColorGrid
          mode="text"
          activeKey={activeMarks.find(m => m.type === 'color')?.color}
          usedColors={usedColors?.color}
          onPick={handleColor}
        />
      )}
      {popover === 'highlight' && (
        <ColorGrid
          mode="highlight"
          activeKey={activeMarks.find(m => m.type === 'highlight')?.color}
          usedColors={usedColors?.highlight}
          onPick={handleHighlight}
        />
      )}
      {popover === 'link' && (
        <form
          onSubmit={handleLinkSubmit}
          className="absolute top-full left-0 mt-1 flex flex-col gap-1.5 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md px-2 py-1.5"
        >
          <div className="flex items-center gap-1">
            <input
              autoFocus
              type="url"
              placeholder="https://..."
              value={linkUrl}
              onChange={(e) => setLinkUrl(e.target.value)}
              className="w-56 px-2 py-1 text-sm rounded border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 text-neutral-900 dark:text-white outline-none focus:border-blue-500"
            />
            <button
              type="submit"
              className="px-2 py-1 text-xs rounded bg-blue-600 hover:bg-blue-700 text-white"
            >
              OK
            </button>
            {isActive('link') && (
              <button
                type="button"
                onClick={handleLinkRemove}
                title="Retirer le lien"
                className="px-2 py-1 text-xs rounded text-red-600 hover:bg-red-50 dark:hover:bg-red-900/30"
              >
                ✕
              </button>
            )}
          </div>
          <label className="flex items-center gap-2 text-xs text-neutral-700 dark:text-neutral-300 select-none cursor-pointer">
            <input
              type="checkbox"
              checked={linkNewTab}
              onChange={(e) => setLinkNewTab(e.target.checked)}
              className="cursor-pointer"
            />
            Ouvrir dans un nouvel onglet
          </label>
        </form>
      )}
    </div>
  );
}

const USED_COLORS_LIMIT = 8;

function ColorGrid({ mode, activeKey, usedColors, onPick }) {
  const pickerRef = useRef(null);
  const used = Array.isArray(usedColors) ? usedColors.slice(0, USED_COLORS_LIMIT) : [];
  const isText = mode === 'text';

  function openCustomPicker() {
    pickerRef.current?.click();
  }

  function handleCustomChange(e) {
    const value = e.target.value;
    if (value) onPick(value);
  }

  return (
    <div className="absolute top-full left-0 mt-1 flex items-center gap-1 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md px-2 py-1.5">
      {INLINE_COLOR_KEYS.map(key => {
        const palette = INLINE_COLORS[key];
        const tw = isText ? palette.text : palette.highlight;
        return (
          <button
            key={key}
            type="button"
            title={key}
            onMouseDown={(e) => e.preventDefault()}
            onClick={() => onPick(key)}
            className={`w-6 h-6 flex items-center justify-center rounded ${tw} ${activeKey === key ? 'ring-2 ring-blue-500' : ''}`}
          >
            <span className={isText ? 'font-semibold' : ''}>A</span>
          </button>
        );
      })}
      {used.length > 0 && (
        <span className="mx-1 w-px h-5 bg-neutral-200 dark:bg-neutral-700" aria-hidden />
      )}
      {used.map(value => (
        <button
          key={value}
          type="button"
          title={`Utilisée : ${value}`}
          onMouseDown={(e) => e.preventDefault()}
          onClick={() => onPick(value)}
          style={isText ? { color: value } : { backgroundColor: value }}
          className={`w-6 h-6 flex items-center justify-center rounded ${activeKey === value ? 'ring-2 ring-blue-500' : ''}`}
        >
          <span className={isText ? 'font-semibold' : ''}>A</span>
        </button>
      ))}
      <span className="mx-1 w-px h-5 bg-neutral-200 dark:bg-neutral-700" aria-hidden />
      <button
        type="button"
        title="Couleur personnalisée"
        onMouseDown={(e) => e.preventDefault()}
        onClick={openCustomPicker}
        className="w-6 h-6 flex items-center justify-center rounded border border-dashed border-neutral-300 dark:border-neutral-600 text-neutral-500 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800"
      >
        <span aria-hidden>+</span>
      </button>
      <input
        ref={pickerRef}
        type="color"
        onChange={handleCustomChange}
        onMouseDown={(e) => e.stopPropagation()}
        className="absolute opacity-0 pointer-events-none w-0 h-0"
        tabIndex={-1}
        aria-hidden
      />
    </div>
  );
}
