import { Boxes, Check, Clock3, EllipsisVertical, FileText, Hammer, MessageSquareText, RefreshCw, RotateCcw, Save, Settings2, SlidersHorizontal, TriangleAlert, Trash2, Waypoints } from 'lucide-react';
import type { RefObject } from 'react';

import { ProtectedSearchInput } from '../../../components/ProtectedSearchInput';
import { LucentIconButton } from '../../../components/lucent/LucentIconButton';
import type { BotState } from '../../../types/bot';
import type { WorkspaceNode } from '../types';
import { WorkspaceEntriesList } from './WorkspaceEntriesList';
import './DashboardMenus.css';
import './RuntimePanel.css';

interface RuntimePanelLabels {
  agent: string;
  autoRefresh: string;
  base: string;
  channels: string;
  clearHistory: string;
  cronViewer: string;
  download: string;
  emptyDir: string;
  envParams: string;
  exportHistory: string;
  fileNotPreviewable: string;
  folder: string;
  goUp: string;
  goUpTitle: string;
  loadingDir: string;
  mcp: string;
  more: string;
  noPreviewFile: string;
  openingPreview: string;
  openFolderTitle: string;
  params: string;
  previewTitle: string;
  refreshHint: string;
  restart: string;
  runtime: string;
  searchAction: string;
  skills: string;
  topic: string;
  workspaceHint: string;
  workspaceOutputs: string;
  workspaceSearchNoResult: string;
  workspaceSearchPlaceholder: string;
  clearSearch: string;
}

interface RuntimePanelProps {
  selectedBot?: BotState;
  selectedBotEnabled: boolean;
  operatingBotId: string | null;
  runtimeMenuOpen: boolean;
  runtimeMenuRef: RefObject<HTMLDivElement | null>;
  displayState: string;
  workspaceError: string;
  workspacePathDisplay: string;
  workspaceLoading: boolean;
  workspaceQuery: string;
  workspaceSearchInputName: string;
  workspaceSearchLoading: boolean;
  filteredWorkspaceEntries: WorkspaceNode[];
  workspaceParentPath: string | null;
  workspaceFileLoading: boolean;
  workspaceDownloadExtensionSet: ReadonlySet<string>;
  workspaceAutoRefresh: boolean;
  hasPreviewFiles: boolean;
  isCompactHidden: boolean;
  showCompactSurface: boolean;
  emptyStateText: string;
  labels: RuntimePanelLabels;
  onRestartBot: (botId: string, dockerStatus: string) => Promise<void> | void;
  onToggleRuntimeMenu: () => void;
  onOpenBaseConfig: () => Promise<void> | void;
  onOpenParamConfig: () => Promise<void> | void;
  onOpenChannelConfig: () => Promise<void> | void;
  onOpenTopicConfig: () => Promise<void> | void;
  onOpenEnvParams: () => Promise<void> | void;
  onOpenSkills: () => Promise<void> | void;
  onOpenMcpConfig: () => Promise<void> | void;
  onOpenCronJobs: () => Promise<void> | void;
  onOpenAgentFiles: () => Promise<void> | void;
  onExportHistory: () => void;
  onClearHistory: () => Promise<void> | void;
  onRefreshWorkspace: () => Promise<void> | void;
  onWorkspaceQueryChange: (value: string) => void;
  onWorkspaceQueryClear: () => void;
  onWorkspaceQuerySearch: () => void;
  onToggleWorkspaceAutoRefresh: () => void;
  onLoadWorkspaceTree: (botId: string, path?: string) => Promise<void> | void;
  onOpenWorkspaceFilePreview: (path: string) => Promise<void> | void;
  onShowWorkspaceHoverCard: (node: WorkspaceNode, anchor: HTMLElement) => void;
  onHideWorkspaceHoverCard: () => void;
}

export function RuntimePanel({
  selectedBot,
  selectedBotEnabled,
  operatingBotId,
  runtimeMenuOpen,
  runtimeMenuRef,
  displayState,
  workspaceError,
  workspacePathDisplay,
  workspaceLoading,
  workspaceQuery,
  workspaceSearchInputName,
  workspaceSearchLoading,
  filteredWorkspaceEntries,
  workspaceParentPath,
  workspaceFileLoading,
  workspaceDownloadExtensionSet,
  workspaceAutoRefresh,
  hasPreviewFiles,
  isCompactHidden,
  showCompactSurface,
  emptyStateText,
  labels,
  onRestartBot,
  onToggleRuntimeMenu,
  onOpenBaseConfig,
  onOpenParamConfig,
  onOpenChannelConfig,
  onOpenTopicConfig,
  onOpenEnvParams,
  onOpenSkills,
  onOpenMcpConfig,
  onOpenCronJobs,
  onOpenAgentFiles,
  onExportHistory,
  onClearHistory,
  onRefreshWorkspace,
  onWorkspaceQueryChange,
  onWorkspaceQueryClear,
  onWorkspaceQuerySearch,
  onToggleWorkspaceAutoRefresh,
  onLoadWorkspaceTree,
  onOpenWorkspaceFilePreview,
  onShowWorkspaceHoverCard,
  onHideWorkspaceHoverCard,
}: RuntimePanelProps) {
  const normalizedWorkspaceQuery = workspaceQuery.trim().toLowerCase();

  return (
    <section className={`panel stack ops-runtime-panel ${isCompactHidden ? 'ops-compact-hidden' : ''} ${showCompactSurface ? 'ops-compact-bot-surface' : ''}`}>
      {selectedBot ? (
        <div className="ops-runtime-shell">
          <div className="row-between ops-runtime-head">
            <h2 style={{ fontSize: 18 }}>{labels.runtime}</h2>
            <div className="ops-panel-tools" ref={runtimeMenuRef}>
              <LucentIconButton
                className="btn btn-secondary btn-sm icon-btn"
                onClick={() => void onRestartBot(selectedBot.id, selectedBot.docker_status)}
                disabled={operatingBotId === selectedBot.id || !selectedBotEnabled}
                tooltip={labels.restart}
                aria-label={labels.restart}
              >
                <RotateCcw size={14} className={operatingBotId === selectedBot.id ? 'animate-spin' : ''} />
              </LucentIconButton>
              <LucentIconButton
                className="btn btn-secondary btn-sm icon-btn"
                onClick={onToggleRuntimeMenu}
                disabled={!selectedBotEnabled}
                tooltip={labels.more}
                aria-label={labels.more}
                aria-haspopup="menu"
                aria-expanded={runtimeMenuOpen}
              >
                <EllipsisVertical size={14} />
              </LucentIconButton>
              {runtimeMenuOpen ? (
                <div className="ops-more-menu" role="menu" aria-label={labels.more}>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenBaseConfig()}>
                    <Settings2 size={14} />
                    <span>{labels.base}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenParamConfig()}>
                    <SlidersHorizontal size={14} />
                    <span>{labels.params}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenChannelConfig()}>
                    <Waypoints size={14} />
                    <span>{labels.channels}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenTopicConfig()}>
                    <MessageSquareText size={14} />
                    <span>{labels.topic}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenEnvParams()}>
                    <Settings2 size={14} />
                    <span>{labels.envParams}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenSkills()}>
                    <Hammer size={14} />
                    <span>{labels.skills}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenMcpConfig()}>
                    <Boxes size={14} />
                    <span>{labels.mcp}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenCronJobs()}>
                    <Clock3 size={14} />
                    <span>{labels.cronViewer}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={() => void onOpenAgentFiles()}>
                    <FileText size={14} />
                    <span>{labels.agent}</span>
                  </button>
                  <button className="ops-more-item" role="menuitem" onClick={onExportHistory}>
                    <Save size={14} />
                    <span>{labels.exportHistory}</span>
                  </button>
                  <button className="ops-more-item danger" role="menuitem" onClick={() => void onClearHistory()}>
                    <Trash2 size={14} />
                    <span>{labels.clearHistory}</span>
                  </button>
                </div>
              ) : null}
            </div>
          </div>

          <div className="ops-runtime-scroll">
            <div className="card ops-runtime-card ops-runtime-state-card is-visual">
              <div className={`ops-state-stage ops-state-${String(displayState).toLowerCase()}`}>
                <div className="ops-state-model mono">{selectedBot.llm_model || '-'}</div>
                <div className="ops-state-face" aria-hidden="true">
                  <span className="ops-state-eye left" />
                  <span className="ops-state-eye right" />
                </div>
                <div className="ops-state-caption mono">{String(displayState || 'IDLE').toUpperCase()}</div>
                {displayState === 'TOOL_CALL' ? <Hammer size={18} className="ops-state-float state-tool" /> : null}
                {displayState === 'SUCCESS' ? <Check size={18} className="ops-state-float state-success" /> : null}
                {displayState === 'ERROR' ? <TriangleAlert size={18} className="ops-state-float state-error" /> : null}
              </div>
            </div>

            <div className="card ops-runtime-card">
              <div className="section-mini-title">{labels.workspaceOutputs}</div>
              {workspaceError ? <div className="ops-empty-inline">{workspaceError}</div> : null}
              <div className="workspace-toolbar">
                <div className="workspace-path-wrap">
                  <div className="workspace-path mono" title={workspacePathDisplay}>
                    {workspacePathDisplay}
                  </div>
                </div>
                <div className="workspace-toolbar-actions">
                  <LucentIconButton
                    className="workspace-refresh-icon-btn"
                    disabled={workspaceLoading}
                    onClick={() => void onRefreshWorkspace()}
                    tooltip={labels.refreshHint}
                    aria-label={labels.refreshHint}
                  >
                    <RefreshCw size={14} className={workspaceLoading ? 'animate-spin' : ''} />
                  </LucentIconButton>
                  <label className="workspace-auto-switch" title={labels.autoRefresh}>
                    <span className="workspace-auto-switch-label">{labels.autoRefresh}</span>
                    <input
                      type="checkbox"
                      checked={workspaceAutoRefresh}
                      onChange={onToggleWorkspaceAutoRefresh}
                      aria-label={labels.autoRefresh}
                    />
                    <span className="workspace-auto-switch-track" />
                  </label>
                </div>
              </div>
              <div className="workspace-search-toolbar">
                <ProtectedSearchInput
                  value={workspaceQuery}
                  onChange={onWorkspaceQueryChange}
                  onClear={onWorkspaceQueryClear}
                  onSearchAction={onWorkspaceQuerySearch}
                  debounceMs={200}
                  placeholder={labels.workspaceSearchPlaceholder}
                  ariaLabel={labels.workspaceSearchPlaceholder}
                  clearTitle={labels.clearSearch}
                  searchTitle={labels.searchAction}
                  name={workspaceSearchInputName}
                  id={workspaceSearchInputName}
                />
              </div>
              <div className="workspace-panel">
                <div className="workspace-list">
                  {workspaceLoading || workspaceSearchLoading ? (
                    <div className="ops-empty-inline">{labels.loadingDir}</div>
                  ) : filteredWorkspaceEntries.length === 0 && workspaceParentPath === null ? (
                    <div className="ops-empty-inline">{normalizedWorkspaceQuery ? labels.workspaceSearchNoResult : labels.emptyDir}</div>
                  ) : (
                    <WorkspaceEntriesList
                      nodes={filteredWorkspaceEntries}
                      workspaceParentPath={workspaceParentPath}
                      selectedBotId={selectedBot.id}
                      workspaceFileLoading={workspaceFileLoading}
                      workspaceDownloadExtensionSet={workspaceDownloadExtensionSet}
                      labels={{
                        download: labels.download,
                        fileNotPreviewable: labels.fileNotPreviewable,
                        folder: labels.folder,
                        goUp: labels.goUp,
                        goUpTitle: labels.goUpTitle,
                        openFolderTitle: labels.openFolderTitle,
                        previewTitle: labels.previewTitle,
                      }}
                      onLoadWorkspaceTree={onLoadWorkspaceTree}
                      onOpenWorkspaceFilePreview={onOpenWorkspaceFilePreview}
                      onShowWorkspaceHoverCard={onShowWorkspaceHoverCard}
                      onHideWorkspaceHoverCard={onHideWorkspaceHoverCard}
                    />
                  )}
                </div>
                <div className="workspace-hint">
                  {workspaceFileLoading ? labels.openingPreview : labels.workspaceHint}
                </div>
              </div>
              {!hasPreviewFiles ? (
                <div className="ops-empty-inline">{labels.noPreviewFile}</div>
              ) : null}
            </div>
          </div>
        </div>
      ) : (
        <div style={{ color: 'var(--muted)' }}>{emptyStateText}</div>
      )}
    </section>
  );
}
