import { CircleUserRound, FolderOpen, LayoutDashboard, LogIn, LogOut, Settings } from 'lucide-react';
import React from 'react';
import { createPortal } from 'react-dom';
import { logout, type SaasAuthState } from '../saas/saas-api';
import { useDismissiblePopover } from './dismissible-popover';

type Position = { top: number; left: number };

export function LearnitiveAccountPopover({
  auth,
  variant = 'site',
  logoutRedirect = '/',
}: {
  auth: SaasAuthState;
  variant?: 'site' | 'editor';
  logoutRedirect?: string;
}) {
  const [open, setOpen] = React.useState(false);
  const [position, setPosition] = React.useState<Position>({ top: 0, left: 0 });
  const triggerRef = React.useRef<HTMLButtonElement>(null);
  const panelRef = React.useRef<HTMLDivElement>(null);
  const panelId = React.useId();
  const editor = variant === 'editor';
  const rootClassName = editor
    ? 'interactive-account-menu interactive-editor-account desktop-titlebar-no-drag'
    : 'interactive-account-menu';
  const triggerClassName = editor ? 'interactive-avatar interactive-editor-avatar' : 'interactive-avatar';
  useDismissiblePopover(open, setOpen, triggerRef, panelRef);

  const updatePosition = React.useCallback(() => {
    const trigger = triggerRef.current;
    if (!trigger || typeof window === 'undefined') return;
    const rect = trigger.getBoundingClientRect();
    const width = Math.min(editor ? 224 : 288, Math.max(176, window.innerWidth - 32));
    const left = Math.max(16, Math.min(rect.right - width, window.innerWidth - width - 16));
    const below = rect.bottom + 10;
    const estimatedHeight = auth.authenticated ? 220 : 70;
    const top = below + estimatedHeight <= window.innerHeight - 12
      ? below
      : Math.max(12, rect.top - estimatedHeight - 10);
    setPosition({ top, left });
  }, [auth.authenticated, editor]);

  React.useLayoutEffect(() => {
    if (!open) return;
    updatePosition();
    const refresh = () => updatePosition();
    window.addEventListener('resize', refresh);
    window.addEventListener('scroll', refresh, true);
    return () => {
      window.removeEventListener('resize', refresh);
      window.removeEventListener('scroll', refresh, true);
    };
  }, [open, updatePosition]);

  const triggerContent = !auth.authenticated
    ? <CircleUserRound className="size-4" />
    : auth.user.avatarUrl
      ? <img src={auth.user.avatarUrl} alt="" referrerPolicy="no-referrer" />
      : <span>{auth.user.displayName.trim().split(/\s+/u).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? '').join('') || 'T'}</span>;
  const title = auth.authenticated ? auth.user.displayName : 'Account menu';

  const popover = open && typeof document !== 'undefined'
    ? createPortal(
        <div
          ref={panelRef}
          id={panelId}
          className="interactive-account-popover interactive-account-popover-portal"
          style={{ top: position.top, left: position.left }}
          data-testid="interactive-account-popover"
        >
          {auth.authenticated ? (
            <>
              <strong>{auth.user.displayName}</strong>
              <span>{auth.user.email}</span>
              <a href="/projects" onClick={() => setOpen(false)}><FolderOpen className="size-4" /> Projects</a>
              <a href="/settings" onClick={() => setOpen(false)}><Settings className="size-4" /> Settings</a>
              {auth.user.role === 'admin' ? <a href="/admin" onClick={() => setOpen(false)}><LayoutDashboard className="size-4" /> Admin</a> : null}
              <button
                type="button"
                onClick={() => void logout().then(() => { setOpen(false); window.location.href = logoutRedirect; })}
              >
                <LogOut className="size-4" /> Logout
              </button>
            </>
          ) : (
            <a href="/login" onClick={() => setOpen(false)}><LogIn className="size-4" /> Login</a>
          )}
        </div>,
        document.body,
      )
    : null;

  return (
    <div className={rootClassName}>
      <button
        ref={triggerRef}
        type="button"
        className={triggerClassName}
        aria-label="Account menu"
        aria-expanded={open}
        aria-controls={panelId}
        title={title}
        onClick={() => setOpen((value) => !value)}
      >
        {triggerContent}
      </button>
      {popover}
    </div>
  );
}
