import { useCoreServices } from '@learnitive/context';
import { WsPath } from '@learnitive/ws-path';
import { FileCode2, X } from 'lucide-react';
import React, { useEffect, useMemo, useRef } from 'react';
import { activateEditorTab, closeEditorTab, openEditorTab, pruneEditorTabs, useEditorTabs } from '../common/editor-tabs';

function fileName(path: string): string {
  const segments = path.split('/');
  return segments.at(-1) || path;
}

export function EditorFileTabs({ workspace, currentPath, availablePaths }: { workspace: string; currentPath?: string; availablePaths: readonly string[] }) {
  const core = useCoreServices();
  const tabState = useEditorTabs(workspace);
  const scrollerRef = useRef<HTMLDivElement | null>(null);
  const availableSignature = useMemo(() => availablePaths.join('\0'), [availablePaths]);

  useEffect(() => {
    if (currentPath) openEditorTab(workspace, currentPath);
  }, [currentPath, workspace]);

  useEffect(() => {
    void availableSignature;
    pruneEditorTabs(workspace, availablePaths);
  }, [availableSignature, workspace]);

  useEffect(() => {
    if (!currentPath || !scrollerRef.current) return;
    const element = scrollerRef.current.querySelector<HTMLElement>('[data-editor-tab-active="true"]');
    element?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
  }, [currentPath, tabState.tabs]);

  useEffect(() => {
    if (!currentPath) return;
    const onKeyDown = (event: KeyboardEvent) => {
      if (!(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey || event.key.toLowerCase() !== 'w') return;
      event.preventDefault();
      const next = closeEditorTab(workspace, currentPath);
      if (next.active) core.navigation.goWsFile(WsPath.fromParts(workspace, next.active).wsPath);
      else core.navigation.goWorkspace(workspace);
    };
    window.addEventListener('keydown', onKeyDown);
    return () => window.removeEventListener('keydown', onKeyDown);
  }, [core.navigation, currentPath, workspace]);

  if (!tabState.tabs.length) return null;

  const navigate = (path: string) => {
    activateEditorTab(workspace, path);
    core.navigation.goWsFile(WsPath.fromParts(workspace, path).wsPath);
  };
  const close = (path: string) => {
    const wasActive = path === currentPath;
    const next = closeEditorTab(workspace, path);
    if (!wasActive) return;
    if (next.active) core.navigation.goWsFile(WsPath.fromParts(workspace, next.active).wsPath);
    else core.navigation.goWorkspace(workspace);
  };

  return (
    <div className="interactive-editor-file-tabs -mb-4 flex h-9 shrink-0 border-b bg-muted/30" data-testid="interactive-editor-file-tabs">
      <div ref={scrollerRef} className="flex min-w-0 flex-1 overflow-x-auto overflow-y-hidden" role="tablist" aria-label="Open files">
        {tabState.tabs.map((path) => {
          const active = path === currentPath;
          return (
            <div
              key={path}
              data-editor-tab-active={active ? 'true' : 'false'}
              className={`group flex h-9 max-w-60 shrink-0 items-center border-r text-xs ${active ? 'border-t-2 border-t-primary bg-background font-semibold text-foreground' : 'bg-muted/20 font-normal text-muted-foreground hover:bg-background/70 hover:text-foreground'}`}
              title={path}
            >
              <button
                type="button"
                role="tab"
                aria-selected={active}
                className="flex h-full min-w-0 flex-1 items-center gap-1.5 px-2.5 text-left"
                onClick={() => navigate(path)}
                onAuxClick={(event) => { if (event.button === 1) { event.preventDefault(); close(path); } }}
              >
                <FileCode2 className="size-3.5 shrink-0" aria-hidden="true" />
                <span className="min-w-0 truncate">{fileName(path)}</span>
              </button>
              <button
                type="button"
                aria-label={`Close ${fileName(path)}`}
                className="mr-1 inline-flex size-5 shrink-0 items-center justify-center rounded opacity-60 hover:bg-muted hover:opacity-100"
                onClick={() => close(path)}
              >
                <X className="size-3" />
              </button>
            </div>
          );
        })}
      </div>
    </div>
  );
}
