import { Fragment, useEffect, useRef, useState } from 'react';
import { PANEL_TITLES, WORKSPACE_PANELS } from '../data/panels';
import { useConnection } from '../context/ConnectionContext';
import { useSettings } from '../context/SettingsContext';
import { isWindows, windowControls } from '../platform';

const DROPDOWN_IDLE_MS = 1000;

const MENU_ICONS = [
  { id: 'help', label: 'Help', icon: 'assets/help.svg' },
  { id: 'settings', label: 'Settings', icon: 'assets/circle_wrench.svg' },
  { id: 'account', label: 'Account', icon: 'assets/account.svg' },
];

const WORKSPACE_TABS = [
  {
    id: 'revision',
    label: 'Revision Control',
    icon: 'assets/revisioncontrol.svg',
    className: 'menu-tab-btn--revision',
  },
  {
    id: 'organization',
    label: 'Organization',
    icon: 'assets/organization.svg',
    className: 'menu-tab-btn--organization',
  },
  {
    id: 'time',
    label: 'Time Tracking',
    icon: 'assets/timer.svg',
    className: 'menu-tab-btn--time',
  },
  {
    id: 'administration',
    label: 'Administration',
    icon: 'assets/fingerprint.svg',
    className: 'menu-tab-btn--administration',
  },
];

export function MenuBar({
  activeWorkspace,
  onWorkspaceChange,
  visibility,
  onToggleVisible,
  onOpenModal,
}) {
  const { showServerNames, showTimeTracking, boldTabStyling } = useSettings();
  const { connected, orgName, account, organizationEnabled } = useConnection();
  const [windowsOpen, setWindowsOpen] = useState(false);
  // Custom frameless-window controls live in this bar on Windows only.
  const showWindowControls = isWindows && Boolean(windowControls);
  const [isMaximized, setIsMaximized] = useState(false);
  const barRef = useRef(null);
  const idleTimerRef = useRef(null);
  // Server-backed pages have no windows to open while disconnected.
  const needsConnection = activeWorkspace !== 'time' && !connected;
  const panelIds = needsConnection ? [] : WORKSPACE_PANELS[activeWorkspace] ?? [];
  const isServerAdmin = connected && (account?.role === 'admin' || account?.role === 'owner');
  const workspaceTabs = WORKSPACE_TABS.filter((tab) => {
    if (tab.id === 'administration' && !isServerAdmin) return false;
    if (tab.id === 'time' && !showTimeTracking) return false;
    // Organization is a server-backed page: it needs a live connection whose
    // server has it enabled. (organizationEnabled defaults true with no session,
    // so the connection check is what hides it while disconnected.)
    if (tab.id === 'organization' && (!connected || !organizationEnabled)) return false;
    return true;
  });
  // If only one workspace would show, there's nothing to switch between —
  // hide the tab bar entirely rather than show a single, unclickable-feeling tab.
  const visibleTabs = workspaceTabs.length <= 1 ? [] : workspaceTabs;

  const clearIdleTimer = () => {
    if (idleTimerRef.current) {
      clearTimeout(idleTimerRef.current);
      idleTimerRef.current = null;
    }
  };

  const startIdleTimer = () => {
    clearIdleTimer();
    if (!windowsOpen) return;
    idleTimerRef.current = setTimeout(() => setWindowsOpen(false), DROPDOWN_IDLE_MS);
  };

  useEffect(() => {
    const onMouseUp = (e) => {
      if (!barRef.current?.contains(e.target)) setWindowsOpen(false);
    };
    const onKey = (e) => {
      if (e.key === 'Escape') setWindowsOpen(false);
    };
    document.addEventListener('mouseup', onMouseUp);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mouseup', onMouseUp);
      document.removeEventListener('keydown', onKey);
      clearIdleTimer();
    };
  }, []);

  useEffect(() => {
    if (!windowsOpen) clearIdleTimer();
    else startIdleTimer();
  }, [windowsOpen]);

  // Keep the maximize/restore icon in sync with the OS window state. onResized
  // fires on every maximize/restore/snap; it resolves to an unlisten fn.
  useEffect(() => {
    if (!showWindowControls) return undefined;
    let unlisten;
    windowControls.isMaximized().then(setIsMaximized);
    windowControls
      .onResized(async () => setIsMaximized(await windowControls.isMaximized()))
      .then((fn) => {
        unlisten = fn;
      });
    return () => unlisten?.();
  }, [showWindowControls]);

  const windowsMenuItem = (
    <div
      key="windows"
      className={`menu-item menu-item--icon${windowsOpen ? ' menu-item--open' : ''}`}
    >
      <button
        type="button"
        className="menu-bar-icon-btn"
        aria-label="Windows"
        aria-expanded={windowsOpen}
        onMouseDown={(e) => {
          e.preventDefault();
          setWindowsOpen((open) => !open);
        }}
      >
        <img src="assets/mosiac.svg" alt="" />
      </button>
      <div
        className={`menu-dropdown${isWindows ? ' menu-dropdown--align-right' : ''}`}
        // Opt the dropdown out of the bar's "deep" drag region so clicking
        // its non-interactive rows (e.g. the disabled "No windows" span)
        // doesn't start a window drag.
        data-tauri-drag-region="false"
        onMouseEnter={clearIdleTimer}
        onMouseLeave={startIdleTimer}
      >
        {panelIds.length === 0 ? (
          <span className="menu-dropdown-item menu-dropdown-item--disabled">
            {needsConnection ? 'Not connected to a server' : 'No windows'}
          </span>
        ) : (
          panelIds.map((panelId) => (
            <button
              key={panelId}
              type="button"
              className="menu-dropdown-item menu-dropdown-item--window"
              onMouseDown={(e) => e.stopPropagation()}
              onClick={(e) => {
                e.stopPropagation();
                onToggleVisible(panelId, !visibility[panelId]);
              }}
            >
              <span className="menu-window-bullet" aria-hidden="true">
                {visibility[panelId] ? '•' : ' '}
              </span>
              {PANEL_TITLES[panelId]}
            </button>
          ))
        )}
      </div>
    </div>
  );

  const connectionsButton = showServerNames ? (
    <button
      key="connections"
      type="button"
      className={`menu-bar-server-btn${connected ? '' : ' menu-bar-server-btn--offline'}`}
      aria-label="Connections"
      onClick={() => onOpenModal('connections')}
    >
      <span className="menu-bar-server-name">
        {orgName ?? 'Login'}
      </span>
      <img src="assets/globe.svg" alt="" className="menu-bar-server-icon" />
    </button>
  ) : (
    <button
      key="connections"
      type="button"
      className="menu-bar-icon-btn"
      aria-label="Connections"
      onClick={() => onOpenModal('connections')}
    >
      <img src="assets/globe.svg" alt="" />
    </button>
  );

  return (
    // data-tauri-drag-region="deep" makes the whole bar (including the gaps
    // inside .menu-bar-tabs / .menu-bar-icons) a window-drag handle; Tauri's
    // drag script still excludes clickable descendants (buttons, tabs). A bare
    // attribute would only work on pixels whose direct hit target is the <nav>
    // itself. Requires core:window:allow-start-dragging in capabilities.
    <nav ref={barRef} className="menu-bar" data-tauri-drag-region="deep">
      <div
        className={`menu-bar-tabs${boldTabStyling ? ' menu-bar-tabs--bold' : ''}`}
        role="tablist"
        aria-label="Workspace"
      >
        {visibleTabs.map(({ id, label, icon, className }, i) => {
          const selected = activeWorkspace === id;
          return (
            // Pipe separators sit between adjacent tabs (browser theme only;
            // hidden via CSS in bold mode). Rendered here rather than as a
            // pseudo-element so the selected tab's pill never encloses one.
            <Fragment key={id}>
              {i > 0 && <span className="menu-tab-sep" aria-hidden="true" />}
              <button
                type="button"
                role="tab"
                aria-selected={selected}
                className={`menu-tab-btn ${className}${selected ? ' menu-tab-btn--active' : ''}`}
                onClick={() => onWorkspaceChange(id)}
              >
                <img className="menu-tab-icon" src={icon} alt="" />
                <span className="menu-tab-label">{label}</span>
              </button>
            </Fragment>
          );
        })}
      </div>

      <div className={`menu-bar-icons${isWindows ? ' menu-bar-icons--reversed' : ''}`}>
        {windowsMenuItem}
        {connectionsButton}
        {MENU_ICONS.map(({ id, label, icon }) => (
          <button
            key={id}
            type="button"
            className="menu-bar-icon-btn"
            aria-label={label}
            onClick={() => onOpenModal(id)}
          >
            <img src={icon} alt="" />
          </button>
        ))}
      </div>

      {showWindowControls && (
        // Frameless-window controls (Windows only). Each is a <button> so
        // Tauri's "deep" drag region excludes it from window-drag. Sits flush
        // to the physical top-right corner (see .menu-bar-window-controls).
        <div className="menu-bar-window-controls">
          <button
            type="button"
            className="menu-bar-window-control"
            aria-label="Minimize"
            onClick={() => windowControls.minimize()}
          >
            <img src="assets/subtract.svg" alt="" />
          </button>
          <button
            type="button"
            className="menu-bar-window-control"
            aria-label={isMaximized ? 'Restore' : 'Maximize'}
            onClick={() => windowControls.toggleMaximize()}
          >
            <img src={isMaximized ? 'assets/unmaximize.svg' : 'assets/maximize.svg'} alt="" />
          </button>
          <button
            type="button"
            className="menu-bar-window-control menu-bar-window-control--close"
            aria-label="Close"
            onClick={() => windowControls.close()}
          >
            <img src="assets/close.svg" alt="" />
          </button>
        </div>
      )}
    </nav>
  );
}
