import { useEffect, useRef, useState } from 'react';
import type { UserStatus } from '@backspace/shared';
import { useAuthStore } from '../../stores/authStore';
import { useT, type TranslationKey } from '../../i18n';

interface AccountMenuProps {
  onClose: () => void;
  onEditProfile: () => void;
}

const STATUSES: { value: UserStatus; key: TranslationKey; dot: string }[] = [
  { value: 'online', key: 'accountMenu.status.online', dot: 'bg-status-online' },
  { value: 'idle', key: 'accountMenu.status.idle', dot: 'bg-status-idle' },
  { value: 'dnd', key: 'accountMenu.status.dnd', dot: 'bg-status-dnd' },
  // 'offline' chosen deliberately is what other clients call invisible.
  { value: 'offline', key: 'accountMenu.status.offline', dot: 'bg-txt-tertiary' },
];

export function AccountMenu({ onClose, onEditProfile }: AccountMenuProps) {
  const t = useT();
  const user = useAuthStore((s) => s.user);
  const updateProfile = useAuthStore((s) => s.updateProfile);
  const [copied, setCopied] = useState(false);
  const menuRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handlePointer = (e: MouseEvent | TouchEvent) => {
      if (!menuRef.current?.contains(e.target as Node)) onClose();
    };
    const handleKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') { e.stopPropagation(); onClose(); }
    };
    // touchstart alongside mousedown: iOS Safari does not reliably synthesise
    // mousedown from a tap, matching what the other popovers here do.
    document.addEventListener('mousedown', handlePointer);
    document.addEventListener('touchstart', handlePointer);
    document.addEventListener('keydown', handleKey);
    return () => {
      document.removeEventListener('mousedown', handlePointer);
      document.removeEventListener('touchstart', handlePointer);
      document.removeEventListener('keydown', handleKey);
    };
  }, [onClose]);

  if (!user) return null;

  const handleStatus = async (status: UserStatus) => {
    if (status === (user.status ?? 'online')) return onClose();
    try {
      await updateProfile({ status });
    } finally {
      onClose();
    }
  };

  const handleCopyId = async () => {
    try {
      await navigator.clipboard.writeText(user.id);
      setCopied(true);
      // Left open on purpose: the confirmation is the only feedback, and
      // closing immediately would hide it.
      setTimeout(() => setCopied(false), 1500);
    } catch {
      // Clipboard is unavailable over plain http or without permission.
    }
  };

  return (
    <div
      ref={menuRef}
      role="menu"
      className="absolute bottom-full left-2 right-2 mb-2 z-[200] glass rounded-xl overflow-hidden py-1.5 shadow-xl"
    >
      <button
        role="menuitem"
        onClick={() => { onEditProfile(); onClose(); }}
        className="w-full px-3 py-2 flex items-center gap-2.5 text-[13.5px] text-txt-secondary hover:bg-interactive-hover hover:text-txt-primary transition-colors"
      >
        <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
          <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25ZM20.71 7.04a1 1 0 0 0 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83Z" />
        </svg>
        {t('accountMenu.editProfile')}
      </button>

      <div className="h-px bg-white/[0.06] my-1.5 mx-2" />
      <div className="px-3 pb-1 text-[10px] font-semibold uppercase tracking-wider text-txt-tertiary">
        {t('accountMenu.status')}
      </div>
      {STATUSES.map((option) => (
        <button
          key={option.value}
          role="menuitemradio"
          aria-checked={(user.status ?? 'online') === option.value}
          onClick={() => void handleStatus(option.value)}
          className="w-full px-3 py-1.5 flex items-center gap-2.5 text-[13.5px] text-txt-secondary hover:bg-interactive-hover hover:text-txt-primary transition-colors"
        >
          <span className={`w-2.5 h-2.5 rounded-full ${option.dot}`} />
          <span className="flex-1 text-left">{t(option.key)}</span>
          {(user.status ?? 'online') === option.value && (
            <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
              <path d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
            </svg>
          )}
        </button>
      ))}

      <div className="h-px bg-white/[0.06] my-1.5 mx-2" />
      <button
        role="menuitem"
        onClick={() => void handleCopyId()}
        className="w-full px-3 py-2 flex items-center gap-2.5 text-[13.5px] text-txt-secondary hover:bg-interactive-hover hover:text-txt-primary transition-colors"
      >
        <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
          <path d="M16 1H4a2 2 0 0 0-2 2v14h2V3h12V1Zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Zm0 16H8V7h11v14Z" />
        </svg>
        {copied ? t('accountMenu.copied') : t('accountMenu.copyId')}
      </button>
    </div>
  );
}
