import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import { wsClient } from './lib/ws';
import ViewMode from './ViewMode';
import EditMode from './EditMode';
import FullscreenMode from './FullscreenMode';
import ControlDialogs from './ControlDialogs';
import { applyZoom, getStoredZoom, setServerDefaultZoom, watchDpr } from './ZoomControl';
import { AuthContext, DEFAULT_ME, fetchMe, canRead } from './lib/auth';
import type { Interface, Me } from './lib/types';

type AppMode = 'view' | 'edit';

// If URL has ?fs=<id>, render bare fullscreen canvas
const fsParam = new URLSearchParams(window.location.search).get('fs');

export default function App() {
  const [mode, setMode] = useState<AppMode>('view');
  const [wsStatus, setWsStatus] = useState('connecting');
  const [editTarget, setEditTarget] = useState<Interface | null>(null);
  // Interface to show when returning to view mode after editing
  const [viewTarget, setViewTarget] = useState<Interface | null>(null);
  // Resolved identity + global access level for the current user.
  const [me, setMe] = useState<Me>(DEFAULT_ME);

  useEffect(() => {
    const unsub = wsClient.status.subscribe(setWsStatus);
    return unsub;
  }, []);

  useEffect(() => {
    applyZoom(getStoredZoom(), false);
    const unwatchDpr = watchDpr();
    if (!fsParam) wsClient.connect('/ws');
    fetchMe().then(me => {
      setMe(me);
      setServerDefaultZoom(me.defaultZoom);
    });
    return unwatchDpr;
  }, []);

  if (fsParam) {
    return <FullscreenMode interfaceId={fsParam} />;
  }

  function enterEdit(iface?: Interface) {
    setEditTarget(iface ?? null);
    setMode('edit');
  }

  // `iface === null` means the editor discarded an unsaved/new panel; keep
  // showing whatever was previously open (held in viewTarget).
  function exitEdit(iface: Interface | null) {
    if (iface) setViewTarget(iface);
    setMode('view');
    setEditTarget(null);
  }

  if (!canRead(me.level)) {
    return (
      <div class="app-root">
        <div class="access-denied">
          <h1>Access denied</h1>
          <p>
            Your account{me.user ? ` (${me.user})` : ''} does not have permission
            to access this application. Contact an administrator.
          </p>
        </div>
      </div>
    );
  }

  return (
    <AuthContext.Provider value={me}>
      <div class="app-root">
        <ControlDialogs />
        {wsStatus === 'disconnected' && (
          <div class="connection-banner">WebSocket disconnected — reconnecting…</div>
        )}
        {mode === 'view' ? (
          <ViewMode onEdit={enterEdit} initialInterface={viewTarget} onView={setViewTarget} />
        ) : (
          <EditMode key={editTarget?.id || 'new'} initial={editTarget} onDone={exitEdit} />
        )}
      </div>
    </AuthContext.Provider>
  );
}
