/**
 * CanvasHeader - Workflow controls, version selector, and execute result.
 */

import React, { useState, useRef, useEffect, useMemo } from 'react';
import {
  FaPlay,
  FaSpinner,
  FaCloudUploadAlt,
  FaCloudDownloadAlt,
  FaArchive,
  FaBookmark,
  FaCaretDown,
  FaSave,
  FaPlus,
  FaChevronLeft,
  FaChevronRight,
} from 'react-icons/fa';
import {
  HiOutlineMagnifyingGlassMinus,
  HiOutlineMagnifyingGlassPlus,
  HiOutlineArrowUturnLeft,
  HiOutlineArrowUturnRight,
  HiOutlineTrash,
  HiOutlineDocumentDuplicate,
  HiOutlineChatBubbleLeftEllipsis,
  HiOutlineSquares2X2,
} from 'react-icons/hi2';
import type { Automation2Workflow, ExecuteGraphResponse, AutoVersion, AutoTemplateScope } from '../../../api/workflowApi';
import styles from './Automation2FlowEditor.module.css';

import { useLanguage } from '../../../providers/language/LanguageContext';
import { getUserDataCache } from '../../../utils/userCache';
import { Button } from '../../UiComponents/Button';

const ZOOM_PRESET_PERCENTS = [25, 50, 75, 100, 125, 150, 200, 400] as const;

export interface CanvasHeaderCanvasEditProps {
  zoomPercent: number;
  selectedNodeCount: number;
  connectionSelected: boolean;
  stickyNoteSelected: boolean;
  connectionToolActive: boolean;
  canUndo: boolean;
  canRedo: boolean;
  onZoomIn: () => void;
  onZoomOut: () => void;
  onZoomPercentCommit: (percent: number) => void;
  onFitWindow: () => void;
  onResetView: () => void;
  onUndo: () => void;
  onRedo: () => void;
  onDeleteSelection: () => void;
  onDuplicateNode: () => void;
  onToggleConnectionTool: () => void;
  /** Textnotiz auf die Canvas legen (ohne Workflow-Daten). */
  onAddCanvasComment: () => void;
  /** Verschachtelte Rasterpfade (4.1 / 4.2 …); Haftnotizen unberührt. */
  onArrangeNodes: () => void;
}

interface CanvasHeaderProps {
  workflows: Automation2Workflow[];
  currentWorkflowId: string | null;
  onWorkflowSelect: (workflowId: string | null) => void;
  onNew: () => void;
  onSave: () => void;
  onExecute: () => void;
  onToggleWorkspacePanel?: () => void;
  workspacePanelOpen?: boolean;
  saving: boolean;
  executing: boolean;
  hasNodes: boolean;
  /** When set, required-field graph errors block a normal run; message is the
   *  run button tooltip. Click still fires `onExecuteBlockedClick` to focus
   *  the first offending node. */
  executeBlockedReason?: string | null;
  onExecuteBlockedClick?: () => void;
  executeResult: ExecuteGraphResponse | null;
  versions?: AutoVersion[];
  currentVersionId?: string | null;
  onVersionSelect?: (versionId: string | null) => void;
  onPublishVersion?: (versionId: string) => void;
  onUnpublishVersion?: (versionId: string) => void;
  onArchiveVersion?: (versionId: string) => void;
  onCreateDraft?: () => void;
  versionLoading?: boolean;
  onSaveAsTemplate?: (scope: AutoTemplateScope) => void;
  templateSaving?: boolean;
  onNewFromTemplate?: () => void;
  /** Sysadmin-only: when true, NodeConfigPanel renders the static
   *  "Schema (Typ-Referenz)" block and per-parameter type-badges. */
  verboseSchema?: boolean;
  onVerboseSchemaChange?: (next: boolean) => void;
  canvasEdit?: CanvasHeaderCanvasEditProps;
}

function _getStatusBadge(t: (key: string) => string): Record<string, { label: string; color: string }> {
  return {
    draft: { label: t('Entwurf'), color: 'var(--warning-color, #ffc107)' },
    published: { label: t('Veröffentlicht'), color: 'var(--success-color, #28a745)' },
    archived: { label: t('Archiviert'), color: 'var(--text-secondary, #666)' },
  };
}

const _tb = 'secondary' as const;
const _ts = 'sm' as const;

export const CanvasHeader: React.FC<CanvasHeaderProps> = ({
  workflows,
  currentWorkflowId,
  onWorkflowSelect,
  onNew,
  onSave,
  onExecute,
  onToggleWorkspacePanel,
  workspacePanelOpen,
  saving,
  executing,
  hasNodes,
  executeBlockedReason,
  onExecuteBlockedClick,
  executeResult,
  versions,
  currentVersionId,
  onVersionSelect,
  onPublishVersion,
  onUnpublishVersion,
  onArchiveVersion,
  onCreateDraft,
  versionLoading,
  onSaveAsTemplate,
  templateSaving,
  onNewFromTemplate,
  verboseSchema,
  onVerboseSchemaChange,
  canvasEdit,
}) => {
  const { t } = useLanguage();
  const _isSysAdmin = getUserDataCache()?.isSysAdmin === true;
  const statusBadge = _getStatusBadge(t);
  const currentVersion = versions?.find((v) => v.id === currentVersionId);
  const currentStatus = currentVersion?.status || 'draft';
  const badge = statusBadge[currentStatus] || statusBadge.draft;

  const [newMenuOpen, setNewMenuOpen] = useState(false);
  const newMenuRef = useRef<HTMLDivElement>(null);

  const [templateMenuOpen, setTemplateMenuOpen] = useState(false);
  const templateMenuRef = useRef<HTMLDivElement>(null);

  const [zoomMenuOpen, setZoomMenuOpen] = useState(false);
  const zoomMenuRef = useRef<HTMLDivElement>(null);
  const [zoomInputDraft, setZoomInputDraft] = useState('');

  useEffect(() => {
    const zp = canvasEdit?.zoomPercent;
    if (zp !== undefined) setZoomInputDraft(String(zp));
  }, [canvasEdit?.zoomPercent]);

  useEffect(() => {
    const _handleClickOutside = (e: MouseEvent) => {
      if (newMenuRef.current && !newMenuRef.current.contains(e.target as Node)) setNewMenuOpen(false);
      if (templateMenuRef.current && !templateMenuRef.current.contains(e.target as Node)) setTemplateMenuOpen(false);
      if (zoomMenuRef.current && !zoomMenuRef.current.contains(e.target as Node)) setZoomMenuOpen(false);
    };
    document.addEventListener('mousedown', _handleClickOutside);
    return () => document.removeEventListener('mousedown', _handleClickOutside);
  }, []);

  const scopeLabels = useMemo(
    () =>
      ({
        user: t('Meine Vorlagen'),
        instance: t('Instanz'),
        mandate: t('Mandant'),
      }) as Record<string, string>,
    [t]
  );

  const _panelOpen = workspacePanelOpen ?? false;
  const _runAriaLabel = executing
    ? t('Ausführen…')
    : executeBlockedReason
      ? t('Pflicht-Felder fehlen')
      : t('Ausführen');
  const _runTitle = executeBlockedReason ?? (hasNodes ? t('Ausführen') : t('Keine Nodes zum Ausführen.'));

  const _executeBannerSegmentClass = !executeResult
    ? ''
    : executeResult.success
      ? executeResult.warning
        ? styles.canvasHeaderExecuteBannerWarning
        : styles.canvasHeaderExecuteBannerSuccess
      : executeResult.paused
        ? styles.canvasHeaderExecuteBannerPaused
        : styles.canvasHeaderExecuteBannerError;

  const _commitZoomDraft = () => {
    if (!canvasEdit) return;
    const raw = zoomInputDraft.replace(/%/g, '').replace(',', '.').trim();
    const n = parseFloat(raw);
    if (!Number.isFinite(n)) {
      setZoomInputDraft(String(canvasEdit.zoomPercent));
      return;
    }
    canvasEdit.onZoomPercentCommit(Math.min(400, Math.max(25, Math.round(n))));
    setZoomMenuOpen(false);
  };

  const _canDeleteSelection =
    !!canvasEdit &&
    (canvasEdit.selectedNodeCount > 0 ||
      canvasEdit.connectionSelected ||
      canvasEdit.stickyNoteSelected);
  const _singleNodeOnly =
    !!canvasEdit && canvasEdit.selectedNodeCount === 1 && !canvasEdit.connectionSelected;

  return (
    <div className={styles.canvasHeader} data-suppress-flow-node-hotkeys="">
      <div
        className={styles.canvasHeaderToolbar}
        role="toolbar"
        aria-label={t('Workflow-Aktionen')}
      >
          {onToggleWorkspacePanel && (
            <Button
              type="button"
              variant={_tb}
              size={_ts}
              icon={_panelOpen ? FaChevronLeft : FaChevronRight}
              className={styles.canvasHeaderIconBtn}
              onClick={onToggleWorkspacePanel}
              title={_panelOpen ? t('Workspace-Panel ausblenden') : t('Workspace-Panel öffnen')}
              aria-label={_panelOpen ? t('Workspace-Panel ausblenden') : t('Workspace-Panel öffnen')}
            />
          )}
          <div ref={newMenuRef} className={styles.canvasHeaderNewSplit}>
            <div className={styles.canvasHeaderSplitPair}>
              <Button
                type="button"
                variant={_tb}
                size={_ts}
                icon={FaPlus}
                className={`${styles.canvasHeaderIconBtn} ${onNewFromTemplate ? styles.canvasHeaderNewSplitMain : ''}`}
                onClick={onNew}
                title={t('Neuer leerer Workflow')}
                aria-label={t('Neuer leerer Workflow')}
              />
              {onNewFromTemplate && (
                <Button
                  type="button"
                  variant={_tb}
                  size={_ts}
                  icon={FaCaretDown}
                  className={`${styles.canvasHeaderIconBtn} ${styles.canvasHeaderNewSplitMenu}`}
                  onClick={() => setNewMenuOpen((p) => !p)}
                  title={t('Aus Vorlage…')}
                  aria-label={t('Neu aus Vorlage')}
                  aria-haspopup="menu"
                  aria-expanded={newMenuOpen}
                />
              )}
            </div>
            {newMenuOpen && onNewFromTemplate && (
              <div className={styles.canvasHeaderMenuDropdown} role="menu">
                <button
                  type="button"
                  className={styles.canvasHeaderMenuItem}
                  onClick={() => {
                    onNewFromTemplate();
                    setNewMenuOpen(false);
                  }}
                  role="menuitem"
                >
                  {t('Aus Vorlage…')}
                </button>
              </div>
            )}
          </div>
          <select
            className={styles.canvasHeaderWorkflowSelect}
            value={currentWorkflowId ?? ''}
            onChange={(e) => {
              const id = e.target.value ? e.target.value : null;
              onWorkflowSelect(id);
            }}
            aria-label={t('Workflow laden')}
            title={t('Workflow laden')}
          >
            <option value="">{t('Workflow laden')}</option>
            {workflows.map((w) => (
              <option key={w.id} value={w.id}>
                {w.label}
              </option>
            ))}
          </select>
          <Button
            type="button"
            variant={_tb}
            size={_ts}
            icon={saving ? undefined : FaSave}
            className={styles.canvasHeaderIconBtn}
            loading={saving}
            disabled={saving}
            onClick={onSave}
            title={!hasNodes ? t('Workflow ist leer — Speichern legt einen leeren Workflow an.') : t('Speichern')}
            aria-label={t('Speichern')}
          />
          <Button
            type="button"
            variant={_tb}
            size={_ts}
            icon={executing ? undefined : FaPlay}
            loading={executing}
            disabled={executing || !hasNodes}
            className={`${styles.canvasHeaderIconBtn} ${executeBlockedReason ? styles.canvasHeaderRunBlocked : ''}`}
            onClick={() => {
              if (executeBlockedReason) {
                onExecuteBlockedClick?.();
                return;
              }
              onExecute();
            }}
            aria-label={_runAriaLabel}
            aria-disabled={executing || !hasNodes || !!executeBlockedReason}
            title={_runTitle}
          />
          {currentWorkflowId && onSaveAsTemplate && (
            <div ref={templateMenuRef} className={styles.canvasHeaderNewSplit}>
              <Button
                type="button"
                variant={_tb}
                size={_ts}
                icon={FaBookmark}
                loading={templateSaving}
                disabled={templateSaving}
                onClick={() => setTemplateMenuOpen((p) => !p)}
                title={t('Als Vorlage speichern')}
                aria-haspopup="menu"
                aria-expanded={templateMenuOpen}
              >
                {t('Als Vorlage')}
              </Button>
              {templateMenuOpen && (
                <div className={styles.canvasHeaderMenuDropdown} role="menu">
                  {(['user', 'instance', 'mandate'] as const).map((s) => (
                    <button
                      key={s}
                      type="button"
                      className={styles.canvasHeaderMenuItem}
                      onClick={() => {
                        onSaveAsTemplate(s);
                        setTemplateMenuOpen(false);
                      }}
                      role="menuitem"
                    >
                      {scopeLabels[s]}
                    </button>
                  ))}
                </div>
              )}
            </div>
          )}

          {_isSysAdmin && onVerboseSchemaChange && (
            <label
              className={styles.canvasHeaderSysadmin}
              title={t('Sysadmin-Ansicht: zeigt im Node-Panel das statische Typ-Schema (Eingabe/Ausgabe) und Parameter-Typ-Badges.')}
            >
              <input
                type="checkbox"
                checked={!!verboseSchema}
                onChange={(e) => onVerboseSchemaChange(e.target.checked)}
                className={styles.canvasHeaderSysadminInput}
              />
              {t('Schema-Details')}
            </label>
          )}
      </div>

      {canvasEdit && (
        <div
          className={styles.canvasHeaderEditRow}
          role="toolbar"
          aria-label={t('Canvas bearbeiten')}
        >
          <div ref={zoomMenuRef} className={styles.canvasHeaderZoomCombo}>
            <div className={styles.canvasHeaderZoomInputWrap}>
              <input
                type="text"
                inputMode="numeric"
                className={styles.canvasHeaderZoomInput}
                value={zoomInputDraft}
                onChange={(e) => setZoomInputDraft(e.target.value)}
                onBlur={_commitZoomDraft}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    e.preventDefault();
                    _commitZoomDraft();
                  }
                }}
                aria-label={t('Zoomstufe (Prozent)')}
                title={t('Zoomstufe (Prozent)')}
              />
              <span className={styles.canvasHeaderZoomSuffix} aria-hidden>
                %
              </span>
            </div>
            <button
              type="button"
              className={styles.canvasHeaderZoomChevronBtn}
              onClick={() => setZoomMenuOpen((p) => !p)}
              aria-label={t('Zoom-Voreinstellungen')}
              aria-haspopup="menu"
              aria-expanded={zoomMenuOpen}
              title={t('Zoom-Voreinstellungen')}
            >
              <FaCaretDown aria-hidden />
            </button>
            {zoomMenuOpen && (
              <div className={styles.canvasHeaderMenuDropdown} role="menu">
                <button
                  type="button"
                  className={styles.canvasHeaderMenuItem}
                  role="menuitem"
                  onClick={() => {
                    canvasEdit.onFitWindow();
                    setZoomMenuOpen(false);
                  }}
                >
                  {t('Ansicht an Fenster anpassen')}
                </button>
                <button
                  type="button"
                  className={styles.canvasHeaderMenuItem}
                  role="menuitem"
                  onClick={() => {
                    canvasEdit.onResetView();
                    setZoomMenuOpen(false);
                  }}
                >
                  {t('Ansicht zurücksetzen')}
                </button>
                {ZOOM_PRESET_PERCENTS.map((pct) => (
                  <button
                    key={pct}
                    type="button"
                    className={styles.canvasHeaderMenuItem}
                    role="menuitem"
                    onClick={() => {
                      canvasEdit.onZoomPercentCommit(pct);
                      setZoomMenuOpen(false);
                    }}
                  >
                    {pct}%
                  </button>
                ))}
              </div>
            )}
          </div>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            onClick={canvasEdit.onZoomIn}
            title={t('Vergrößern')}
            aria-label={t('Vergrößern')}
          >
            <HiOutlineMagnifyingGlassPlus size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            onClick={canvasEdit.onZoomOut}
            title={t('Verkleinern')}
            aria-label={t('Verkleinern')}
          >
            <HiOutlineMagnifyingGlassMinus size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            disabled={!canvasEdit.canUndo}
            onClick={canvasEdit.onUndo}
            title={t('Rückgängig')}
            aria-label={t('Rückgängig')}
          >
            <HiOutlineArrowUturnLeft size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            disabled={!canvasEdit.canRedo}
            onClick={canvasEdit.onRedo}
            title={t('Wiederholen')}
            aria-label={t('Wiederholen')}
          >
            <HiOutlineArrowUturnRight size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            disabled={!_canDeleteSelection}
            onClick={canvasEdit.onDeleteSelection}
            title={t('Auswahl löschen')}
            aria-label={t('Auswahl löschen')}
          >
            <HiOutlineTrash size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            disabled={!_singleNodeOnly}
            onClick={canvasEdit.onDuplicateNode}
            title={t('Knoten duplizieren')}
            aria-label={t('Knoten duplizieren')}
          >
            <HiOutlineDocumentDuplicate size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            disabled={!hasNodes}
            onClick={canvasEdit.onArrangeNodes}
            title={t('Knoten im Raster anordnen')}
            aria-label={t('Knoten im Raster anordnen')}
          >
            <HiOutlineSquares2X2 size={18} strokeWidth={2} aria-hidden />
          </button>
          <button
            type="button"
            className={styles.canvasHeaderGhostIconBtn}
            onClick={canvasEdit.onAddCanvasComment}
            title={t('Kommentar auf dem Canvas einfügen')}
            aria-label={t('Kommentar auf dem Canvas einfügen')}
          >
            <HiOutlineChatBubbleLeftEllipsis size={18} strokeWidth={2} aria-hidden />
          </button>
        </div>
      )}

      {currentWorkflowId && versions && versions.length > 0 && (
        <div className={styles.canvasHeaderVersionRow}>
          <span className={styles.canvasHeaderVersionLabel}>{t('Version:')}</span>
          <select
            className={styles.canvasHeaderVersionSelect}
            value={currentVersionId ?? ''}
            onChange={(e) => onVersionSelect?.(e.target.value || null)}
            disabled={versionLoading}
            aria-label={t('Version')}
          >
            <option value="">{t('Aktuelle')}</option>
            {versions.map((v) => (
              <option key={v.id} value={v.id}>
                v{v.versionNumber} ({statusBadge[v.status]?.label ?? v.status})
              </option>
            ))}
          </select>
          <span
            className={styles.canvasHeaderVersionBadge}
            style={
              {
                '--canvasHeaderBadgeBg': `${badge.color}22`,
                '--canvasHeaderBadgeFg': badge.color,
              } as React.CSSProperties
            }
          >
            {badge.label}
          </span>
          {currentVersion && currentStatus === 'draft' && onPublishVersion && (
            <Button
              type="button"
              variant={_tb}
              size={_ts}
              icon={FaCloudUploadAlt}
              className={styles.canvasHeaderVersionAction}
              onClick={() => onPublishVersion(currentVersion.id)}
              disabled={versionLoading}
              title={t('Version veröffentlichen')}
            >
              {t('Veröffentlichen')}
            </Button>
          )}
          {currentVersion && currentStatus === 'published' && onUnpublishVersion && (
            <Button
              type="button"
              variant={_tb}
              size={_ts}
              icon={FaCloudDownloadAlt}
              className={styles.canvasHeaderVersionAction}
              onClick={() => onUnpublishVersion(currentVersion.id)}
              disabled={versionLoading}
              title={t('Veröffentlichung zurücknehmen')}
            >
              {t('Veröffentlichung aufheben')}
            </Button>
          )}
          {currentVersion && currentStatus !== 'archived' && onArchiveVersion && (
            <Button
              type="button"
              variant={_tb}
              size={_ts}
              icon={FaArchive}
              className={styles.canvasHeaderVersionAction}
              onClick={() => onArchiveVersion(currentVersion.id)}
              disabled={versionLoading}
              title={t('Version archivieren')}
            >
              {t('Archiv')}
            </Button>
          )}
          {onCreateDraft && (
            <Button
              type="button"
              variant={_tb}
              size={_ts}
              icon={FaPlus}
              className={styles.canvasHeaderVersionAction}
              onClick={onCreateDraft}
              disabled={versionLoading}
              title={t('Neuen Entwurf erstellen')}
            >
              {t('+ Entwurf')}
            </Button>
          )}
          {versionLoading && <FaSpinner className={`${styles.spinner} ${styles.canvasHeaderVersionSpinner}`} />}
        </div>
      )}

      {executeResult && (
        <div
          className={`${styles.canvasHeaderExecuteBanner} ${_executeBannerSegmentClass}`}
        >
          {executeResult.success ? (
            executeResult.warning ? (
              <>{executeResult.warning}</>
            ) : (
              <>{t('Ausführung abgeschlossen')}</>
            )
          ) : executeResult.paused ? (
            <>
              {t('Workflow pausiert. Öffne ')}
              <strong>{t('Workflows/Tasks')}</strong>
              {t(' in der Sidebar, um den Task zu bearbeiten.')}
            </>
          ) : (
            <>{executeResult.error ?? t('Unbekannter Fehler')}</>
          )}
        </div>
      )}
    </div>
  );
};
