'use client';

/**
 * Toolbar — top bar for the Page Organizer admin UI.
 *
 * Left:  DeviceToggle
 * Center: Preview / Publish / Schedule / History buttons
 * Right:  Saving status pill (idle / saving / saved / error / conflict)
 */

import { useState, useEffect, lazy, Suspense } from 'react';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { Button } from '@/components/ui/primitives/Button';
import { Pill } from '@/components/ui/primitives/Pill';
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from '@/components/ui/primitives/Select/Select';

// Lazy-load dialogs/drawer — only needed after user interaction, never on first paint.
const PublishDialog = lazy(() =>
  import('./PublishDialog').then((m) => ({ default: m.PublishDialog })),
);
const ScheduleDialog = lazy(() =>
  import('./ScheduleDialog').then((m) => ({ default: m.ScheduleDialog })),
);
const HistoryDialog = lazy(() =>
  import('./HistoryDialog').then((m) => ({ default: m.HistoryDialog })),
);
const PageSettingsDrawer = lazy(() =>
  import('./PageSettingsDrawer').then((m) => ({ default: m.PageSettingsDrawer })),
);
import { useOrganizer } from './state';
import { fetchPage, fetchPages, type PageEntry } from './api';
import { useT } from '@/lib/i18n/react';
import type { LayoutBody } from '@/server/page-layout/types';
import { captureCaught } from '@/lib/observability';

export interface ToolbarProps {
  page: string;
  onPageChange: (page: string) => void;
}

type DialogState = 'publish' | 'schedule' | 'history' | null;

/** Maps saving state to Pill tone */
const SAVING_TONE = {
  idle: 'neutral',
  saving: 'neutral',
  saved: 'success',
  error: 'danger',
  conflict: 'danger',
} as const;

export function Toolbar({ page, onPageChange }: ToolbarProps) {
  const t = useT('page_organizer');
  const saving = useOrganizer((s) => s.saving);
  const body = useOrganizer((s) => s.body);
  const hydrate = useOrganizer((s) => s.hydrate);

  const [dialog, setDialog] = useState<DialogState>(null);
  const [pages, setPages] = useState<PageEntry[]>([]);
  const [showSettings, setShowSettings] = useState(false);

  useEffect(() => {
    void fetchPages()
      .then(setPages)
      .catch((err) => {
        captureCaught(err, { scope: 'features.admin-page-organizer.Toolbar', severity: 'info' });
        /* non-fatal */
      });
  }, []);

  function handlePreview() {
    window.open('/?__preview=1', '_blank', 'noopener,noreferrer');
  }

  async function handlePublished() {
    // Re-fetch from server and re-hydrate after a successful publish
    const result = await fetchPage(page);
    const latest = (result.draft?.body ?? result.liveVersion.body) as LayoutBody;
    hydrate(latest, result.draft?.updatedAt ?? null);
    setDialog(null);
  }

  function handleReverted() {
    // Re-fetch and close
    void fetchPage(page).then((result) => {
      const latest = (result.draft?.body ?? result.liveVersion.body) as LayoutBody;
      hydrate(latest, result.draft?.updatedAt ?? null);
    });
    setDialog(null);
  }

  /** Pill label per saving state */
  function savingLabel(): string {
    switch (saving) {
      case 'saving':
        return t('draft_saving');
      case 'saved':
        return t('draft_saved');
      case 'error':
        return t('saving_error');
      case 'conflict':
        return t('conflict_toast');
      case 'idle':
      default:
        return t('saving_idle');
    }
  }

  return (
    <>
      <div
        role="toolbar"
        aria-label={t('title')}
        className="bg-surface-base border-border-default flex flex-wrap items-center gap-2 rounded-md border p-2"
      >
        {/* Start: page picker + settings */}
        <div className="flex items-center gap-2">
          {pages.length > 0 && (
            <Select value={page} onValueChange={onPageChange}>
              <SelectTrigger aria-label={t('page_picker_label')} className="w-40">
                <SelectValue placeholder={t('page_picker_label')} />
              </SelectTrigger>
              <SelectContent>
                {pages.map((p) => (
                  <SelectItem key={p.slug} value={p.slug}>
                    <span data-diag="">{p.label.he}</span>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
          <Button variant="secondary" size="sm" onClick={() => setShowSettings(true)}>
            {t('btn_page_settings')}
          </Button>
        </div>

        {/* Spacer */}
        <div className="flex-1" />

        {/* Center: action buttons */}
        <Button variant="ghost" size="sm" onClick={handlePreview}>
          {t('btn_preview')}
        </Button>
        <Button variant="primary" size="sm" onClick={() => setDialog('publish')}>
          {t('btn_publish')}
        </Button>
        <Button variant="secondary" size="sm" onClick={() => setDialog('schedule')}>
          {t('btn_schedule')}
        </Button>
        <Button variant="ghost" size="sm" onClick={() => setDialog('history')}>
          {t('btn_history')}
        </Button>

        {/* Right: saving status pill */}
        {saving !== 'idle' && (
          <Pill tone={SAVING_TONE[saving]} size="sm" aria-live="polite" aria-atomic="true">
            {savingLabel()}
          </Pill>
        )}
      </div>

      {/* Dialogs — lazy chunks, loaded only on first open */}
      <Suspense fallback={<Spinner />}>
        {dialog === 'publish' && (
          <PublishDialog
            page={page}
            draft={body}
            onPublished={() => void handlePublished()}
            onClose={() => setDialog(null)}
          />
        )}
        {dialog === 'schedule' && <ScheduleDialog page={page} onClose={() => setDialog(null)} />}
        {dialog === 'history' && (
          <HistoryDialog page={page} onReverted={handleReverted} onClose={() => setDialog(null)} />
        )}
        <PageSettingsDrawer
          page={page}
          open={showSettings}
          onClose={() => setShowSettings(false)}
        />
      </Suspense>
    </>
  );
}
