import { Button } from '@learnitive/ui-components';
import { Maximize2, Minimize2, Redo2, Save, Settings2, Undo2 } from 'lucide-react';
import React from 'react';
import { SOURCE_EDITOR_FONT_SIZES } from '../editor-preferences';

export type SourceEditorToolbarTestIds = {
  cursor: string;
  wordWrap: string;
  settings: string;
  fontSize: string;
  lineNumbers: string;
  spellcheck: string;
  fullscreen: string;
};

export type SourceEditorToolbarProps = {
  languageLabel?: string;
  path: string;
  cursor: { line: number; column: number };
  status: string;
  wordWrap: boolean;
  fontSize: number;
  lineNumbers: boolean;
  spellcheck: boolean;
  fullscreen: boolean;
  canUndo: boolean;
  canRedo: boolean;
  onWordWrapChange(enabled: boolean): void;
  onFontSizeChange(size: number): void;
  onLineNumbersChange(enabled: boolean): void;
  onSpellcheckChange(enabled: boolean): void;
  onFullscreen(): void | Promise<void>;
  onUndo(): void;
  onRedo(): void;
  onSave(): void;
  saveDisabled?: boolean;
  settingsExtra?: React.ReactNode;
  testIds: SourceEditorToolbarTestIds;
  undoLabel?: string;
  redoLabel?: string;
  saveLabel?: string;
};

export function SourceEditorToolbar({
  languageLabel,
  path,
  cursor,
  status,
  wordWrap,
  fontSize,
  lineNumbers,
  spellcheck,
  fullscreen,
  canUndo,
  canRedo,
  onWordWrapChange,
  onFontSizeChange,
  onLineNumbersChange,
  onSpellcheckChange,
  onFullscreen,
  onUndo,
  onRedo,
  onSave,
  saveDisabled = false,
  settingsExtra,
  testIds,
  undoLabel = t.app.sourceEditorToolbar.undo,
  redoLabel = t.app.sourceEditorToolbar.redo,
  saveLabel = t.app.sourceEditorToolbar.save,
}: SourceEditorToolbarProps) {
  return (
    <div
      className="flex shrink-0 flex-wrap items-center gap-2 border-b bg-background px-3 py-2"
      data-testid="source-editor-toolbar"
    >
      {languageLabel ? <span className="shrink-0 text-xs font-medium">{languageLabel}</span> : null}
      <span className="min-w-32 flex-1 truncate font-mono text-sm">{path}</span>
      <span
        className="text-muted-foreground text-xs tabular-nums"
        data-testid={testIds.cursor}
      >
        Ln {cursor.line}, Col {cursor.column}
      </span>
      <span className="text-muted-foreground text-xs" aria-live="polite">
        {status}
      </span>
      <Button
        size="sm"
        variant={wordWrap ? 'secondary' : 'ghost'}
        data-testid={testIds.wordWrap}
        aria-pressed={wordWrap}
        onClick={() => onWordWrapChange(!wordWrap)}
      >
        {t.app.sourceEditorToolbar.wordWrap}
      </Button>
      <details className="relative" data-testid={testIds.settings}>
        <summary className="flex h-8 cursor-pointer list-none items-center gap-1 rounded-md border px-2 text-xs hover:bg-accent">
          <Settings2 className="size-3.5" />
          {t.app.sourceEditorToolbar.editor}
        </summary>
        <div className="absolute right-0 z-50 mt-1 grid min-w-56 gap-2 rounded-md border bg-background p-3 text-xs shadow-lg">
          <label className="grid gap-1">
            <span>{t.app.sourceEditorToolbar.fontSize}</span>
            <select
              className="h-8 rounded-md border bg-background px-2"
              data-testid={testIds.fontSize}
              value={fontSize}
              onChange={(event) => onFontSizeChange(Number(event.currentTarget.value))}
            >
              {SOURCE_EDITOR_FONT_SIZES.map((size) => (
                <option key={size} value={size}>{size}px</option>
              ))}
            </select>
          </label>
          <label className="flex items-center justify-between gap-3">
            <span>{t.app.sourceEditorToolbar.lineNumbers}</span>
            <input
              data-testid={testIds.lineNumbers}
              type="checkbox"
              checked={lineNumbers}
              onChange={(event) => onLineNumbersChange(event.currentTarget.checked)}
            />
          </label>
          <label className="flex items-center justify-between gap-3">
            <span>{t.app.sourceEditorToolbar.spellcheck}</span>
            <input
              data-testid={testIds.spellcheck}
              type="checkbox"
              checked={spellcheck}
              onChange={(event) => onSpellcheckChange(event.currentTarget.checked)}
            />
          </label>
          {settingsExtra}
        </div>
      </details>
      <Button
        aria-label={fullscreen ? t.app.sourceEditorToolbar.exitFullscreen : t.app.sourceEditorToolbar.fullscreen}
        data-testid={testIds.fullscreen}
        size="icon"
        variant="ghost"
        onClick={() => void onFullscreen()}
      >
        {fullscreen ? <Minimize2 className="size-4" /> : <Maximize2 className="size-4" />}
      </Button>
      <Button
        aria-label={undoLabel}
        disabled={!canUndo}
        size="icon"
        variant="ghost"
        onClick={onUndo}
      >
        <Undo2 className="size-4" />
      </Button>
      <Button
        aria-label={redoLabel}
        disabled={!canRedo}
        size="icon"
        variant="ghost"
        onClick={onRedo}
      >
        <Redo2 className="size-4" />
      </Button>
      <Button
        aria-label={saveLabel}
        disabled={saveDisabled}
        size="icon"
        variant="ghost"
        onClick={onSave}
      >
        <Save className="size-4" />
      </Button>
    </div>
  );
}
