'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { $getSelection, $isRangeSelection } from 'lexical';
import { TOGGLE_LINK_COMMAND } from '@lexical/link';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { normalizeUrl, isValidUrl, INVALID_URL_MESSAGE, $findLinkNode } from './link-utils';

const POPOVER_STYLE = {
  position: 'fixed' as const,
  zIndex: 99999,
  background: '#1e293b',
  backdropFilter: 'blur(8px)',
  border: '1px solid rgba(148, 163, 184, 0.25)',
  borderRadius: '12px',
  boxShadow: '0 4px 12px rgba(0, 0, 0, 0.3)',
  color: '#f8fafc',
};

// Floating link editor plugin — portaled to document.body so it renders
// above Puck's iframe preview.
export function FloatingLinkEditorPlugin({
  anchorRef,
}: {
  anchorRef: React.RefObject<HTMLDivElement | null>;
}) {
  const [editor] = useLexicalComposerContext();
  const [linkUrl, setLinkUrl] = useState<string | null>(null);
  const [linkTarget, setLinkTarget] = useState<string | null>(null);
  const [popoverPos, setPopoverPos] = useState<{ top: number; left: number } | null>(null);
  const [isEditing, setIsEditing] = useState(false);
  const [editUrl, setEditUrl] = useState('');
  const [editOpenInNewTab, setEditOpenInNewTab] = useState(true);
  const [editError, setEditError] = useState('');
  const popoverRef = useRef<HTMLDivElement>(null);
  const editInputRef = useRef<HTMLInputElement>(null);
  const isEditingRef = useRef(false);

  useEffect(() => {
    isEditingRef.current = isEditing;
  }, [isEditing]);

  useEffect(() => {
    return editor.registerUpdateListener(({ editorState }) => {
      editorState.read(() => {
        const selection = $getSelection();
        if (!$isRangeSelection(selection)) {
          if (!isEditingRef.current) {
            setLinkUrl(null);
            setLinkTarget(null);
            setPopoverPos(null);
          }
          return;
        }

        const node = selection.anchor.getNode();
        const linkNode = $findLinkNode(node);

        if (linkNode) {
          setLinkUrl(linkNode.getURL());
          setLinkTarget(linkNode.getTarget());
          const linkDom = editor.getElementByKey(linkNode.getKey());
          if (linkDom) {
            // Use viewport-relative coordinates for fixed positioning
            const linkRect = linkDom.getBoundingClientRect();
            const popoverWidth = 350;
            const popoverHeight = 160;
            const gap = 4;

            let top = linkRect.bottom + gap;
            let left = linkRect.left;

            if (left + popoverWidth > window.innerWidth) {
              left = Math.max(0, window.innerWidth - popoverWidth);
            }

            if (top + popoverHeight > window.innerHeight) {
              top = linkRect.top - popoverHeight - gap;
            }

            setPopoverPos({ top, left });
          }
        } else {
          setLinkUrl(null);
          setLinkTarget(null);
          setPopoverPos(null);
          setIsEditing(false);
        }
      });
    });
  }, [editor, anchorRef]);

  const handleEdit = useCallback(() => {
    setEditUrl(linkUrl || '');
    setEditOpenInNewTab(linkTarget === '_blank');
    setEditError('');
    setIsEditing(true);
    setTimeout(() => editInputRef.current?.focus(), 0);
  }, [linkUrl, linkTarget]);

  const handleEditApply = useCallback(() => {
    const normalized = normalizeUrl(editUrl);

    if (normalized === '') {
      editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
      setIsEditing(false);
      return;
    }

    if (!isValidUrl(normalized)) {
      setEditError(INVALID_URL_MESSAGE);
      return;
    }

    editor.dispatchCommand(TOGGLE_LINK_COMMAND, {
      url: normalized,
      target: editOpenInNewTab ? '_blank' : null,
      rel: editOpenInNewTab ? 'noopener noreferrer' : null,
    });
    setIsEditing(false);
  }, [editor, editUrl, editOpenInNewTab]);

  const handleEditKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        handleEditApply();
      } else if (e.key === 'Escape') {
        setIsEditing(false);
      }
    },
    [handleEditApply]
  );

  const handleToggleTarget = useCallback(() => {
    if (!linkUrl) return;
    const newTarget = linkTarget === '_blank' ? null : '_blank';
    editor.dispatchCommand(TOGGLE_LINK_COMMAND, {
      url: linkUrl,
      target: newTarget,
      rel: newTarget === '_blank' ? 'noopener noreferrer' : null,
    });
  }, [editor, linkUrl, linkTarget]);

  const handleRemove = useCallback(() => {
    editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
  }, [editor]);

  if (!linkUrl || !popoverPos) return null;

  if (isEditing) {
    return createPortal(
      <div
        ref={popoverRef}
        style={{
          ...POPOVER_STYLE,
          top: `${popoverPos.top}px`,
          left: `${popoverPos.left}px`,
          padding: '16px',
          minWidth: '280px',
        }}
      >
        <input
          ref={editInputRef}
          type="text"
          value={editUrl}
          onChange={(e) => {
            setEditUrl(e.target.value);
            setEditError('');
          }}
          onKeyDown={handleEditKeyDown}
          placeholder="Enter URL"
          aria-label="URL"
          style={{
            width: '100%',
            padding: '12px 16px',
            background: 'rgba(15, 23, 42, 0.75)',
            border: `1px solid ${editError ? '#f87171' : 'rgba(148, 163, 184, 0.25)'}`,
            borderRadius: '8px',
            color: '#f8fafc',
            fontSize: '16px',
          }}
        />
        {editError && (
          <div role="alert" style={{ color: '#f87171', fontSize: '14px', marginTop: '4px' }}>
            {editError}
          </div>
        )}
        <label
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: '8px',
            marginTop: '8px',
            color: '#f8fafc',
            fontSize: '14px',
            cursor: 'pointer',
          }}
        >
          <input
            type="checkbox"
            checked={editOpenInNewTab}
            onChange={(e) => setEditOpenInNewTab(e.target.checked)}
            aria-label="Open in new tab"
            style={{ cursor: 'pointer', accentColor: '#38bdf8', width: '20px', height: '20px' }}
          />
          Open in new tab
        </label>
        <div style={{ display: 'flex', gap: '8px', marginTop: '12px', justifyContent: 'flex-end' }}>
          <button
            type="button"
            onClick={() => setIsEditing(false)}
            style={{
              padding: '8px 16px',
              background: 'transparent',
              border: '1px solid #38bdf8',
              borderRadius: '8px',
              color: '#38bdf8',
              cursor: 'pointer',
              fontSize: '14px',
              fontWeight: 600,
            }}
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={handleEditApply}
            disabled={!!editError}
            style={{
              padding: '8px 16px',
              background: editError ? 'rgba(71, 85, 105, 0.4)' : '#38bdf8',
              border: 'none',
              borderRadius: '8px',
              color: editError ? 'rgba(226, 232, 240, 0.65)' : '#0f172a',
              cursor: editError ? 'not-allowed' : 'pointer',
              fontSize: '14px',
              fontWeight: 600,
            }}
          >
            Apply
          </button>
        </div>
      </div>,
      document.body
    );
  }

  return createPortal(
    <div
      ref={popoverRef}
      style={{
        ...POPOVER_STYLE,
        top: `${popoverPos.top}px`,
        left: `${popoverPos.left}px`,
        display: 'flex',
        alignItems: 'center',
        gap: '8px',
        padding: '8px 12px',
        fontSize: '14px',
        maxWidth: '400px',
      }}
    >
      <a
        href={linkUrl}
        target="_blank"
        rel="noopener noreferrer"
        style={{
          color: '#38bdf8',
          textDecoration: 'underline',
          overflow: 'hidden',
          textOverflow: 'ellipsis',
          whiteSpace: 'nowrap',
          maxWidth: '120px',
        }}
        title={linkUrl}
      >
        {linkUrl}
      </a>
      <button
        type="button"
        onClick={handleToggleTarget}
        style={{
          padding: '4px 12px',
          background: linkTarget === '_blank' ? 'rgba(56, 189, 248, 0.16)' : 'transparent',
          border: `1px solid ${linkTarget === '_blank' ? 'rgba(56, 189, 248, 0.35)' : 'rgba(148, 163, 184, 0.25)'}`,
          borderRadius: '999px',
          color: linkTarget === '_blank' ? '#38bdf8' : 'rgba(148, 163, 184, 0.85)',
          cursor: 'pointer',
          fontSize: '12px',
          fontWeight: 600,
          whiteSpace: 'nowrap',
        }}
        title={
          linkTarget === '_blank'
            ? 'Opens in new tab (click to change)'
            : 'Opens in same tab (click to change)'
        }
        aria-label={linkTarget === '_blank' ? 'Opens in new tab' : 'Opens in same tab'}
      >
        {linkTarget === '_blank' ? 'New tab' : 'Same tab'}
      </button>
      <button
        type="button"
        onClick={handleEdit}
        style={{
          padding: '4px 12px',
          background: 'transparent',
          border: '1px solid #38bdf8',
          borderRadius: '8px',
          color: '#38bdf8',
          cursor: 'pointer',
          fontSize: '12px',
          fontWeight: 600,
        }}
        title="Edit link"
      >
        Edit
      </button>
      <button
        type="button"
        onClick={handleRemove}
        style={{
          padding: '4px 12px',
          background: '#f87171',
          border: 'none',
          borderRadius: '8px',
          color: '#ffffff',
          cursor: 'pointer',
          fontSize: '12px',
          fontWeight: 600,
        }}
        title="Remove link"
      >
        Remove
      </button>
    </div>,
    document.body
  );
}
