import { useEffect, useMemo } from 'react';
import { Navigate, useParams } from 'react-router';
import type { LayoutNode } from 'officerdev';
import { WorkspaceView, DEFAULT_HEADSCALE_SECTION, headscaleSectionPath, isHeadscaleSection } from 'officerdev';
import { useDashboardState } from 'state/useDashboardState';
import { defaultLayout } from './defaultLayout';

// /headscale uses the Workspace/Panel system (like /soulseek and /music): the server picker
// (headscale-servers) above the section nav (headscale-nav) on the left, and the section view
// (headscale-view) on the right. All three talk to the officer-headscale sidecar through the /api/headscale
// auth proxy, which holds no Headscale credentials of its own — the registered servers and their keys live
// in the sidecar.
//
// The open section is :section in the URL, so every panel reads it with useParams instead of passing it
// between themselves over a channel. This screen backs both /headscale and /headscale/:section and is the
// single place that decides what an absent or bogus section means.

function hasAppType(node: LayoutNode, appType: string): boolean {
  if (node.type === 'panel') return node.appType === appType;
  return node.children.some((c) => hasAppType(c.node, appType));
}

export const HeadscaleScreen = () => {
  const { section } = useParams();
  const rawWorkspace = useDashboardState<LayoutNode>('screens/headscale', defaultLayout);

  // A layout saved before the server picker existed has no panel for it, and nothing else would ever add
  // one — so it is rebuilt from the default. That costs a one-time reset of any manual sizing, which is
  // cheaper than a screen permanently missing a panel. Pinning the app types is `appTypes` below; this is
  // the part the framework can't do, because it is about a panel that is *missing* rather than wrong.
  const workspace = useMemo(() => {
    if (hasAppType(rawWorkspace.value, 'headscale-servers')) return rawWorkspace;
    return { ...rawWorkspace, value: defaultLayout };
  }, [rawWorkspace]);

  useEffect(() => {
    if (rawWorkspace.isLoaded && workspace.value !== rawWorkspace.value) {
      rawWorkspace.setValue(workspace.value);
    }
  }, [rawWorkspace.isLoaded, workspace.value, rawWorkspace.value]);

  // Bare /headscale, or a section that doesn't exist, resolves to a canonical URL rather than rendering a
  // default while the address bar says something else — the nav highlight is derived from the URL, so a URL
  // that names nothing would leave nothing highlighted.
  if (!isHeadscaleSection(section)) {
    return <Navigate to={headscaleSectionPath(DEFAULT_HEADSCALE_SECTION)} replace />;
  }

  return (
    <div className="h-full w-full pt-2">
      <WorkspaceView
        workspace={workspace}
        locked
        appTypes={{
          allowed: ['headscale-servers', 'headscale-nav', 'headscale-view'],
          fallback: 'headscale-view',
        }}
      />
    </div>
  );
};
