import { useState, useEffect } from 'react';
import type { ProcessorNode, ExecutionDetail, DetailTab } from './types';
import { useProcessorSnapshotById } from '../../api/queries/executions';
import { InfoTab } from './tabs/InfoTab';
import { HeadersTab } from './tabs/HeadersTab';
import { PropertiesTab } from './tabs/PropertiesTab';
import { BodyTab } from './tabs/BodyTab';
import { ErrorTab } from './tabs/ErrorTab';
import { ConfigTab } from './tabs/ConfigTab';
import { TimelineTab } from './tabs/TimelineTab';
import { LogTab } from './tabs/LogTab';
import styles from './ExecutionDiagram.module.css';

interface DetailPanelProps {
  selectedProcessor: ProcessorNode | null;
  executionDetail: ExecutionDetail;
  executionId: string;
  onSelectProcessor: (processorId: string) => void;
}

const TABS: { key: DetailTab; label: string }[] = [
  { key: 'info', label: 'Info' },
  { key: 'headers', label: 'Headers' },
  { key: 'properties', label: 'Properties' },
  { key: 'input', label: 'Input' },
  { key: 'output', label: 'Output' },
  { key: 'error', label: 'Error' },
  { key: 'config', label: 'Config' },
  { key: 'timeline', label: 'Timeline' },
  { key: 'log', label: 'Log' },
];

export function DetailPanel({
  selectedProcessor,
  executionDetail,
  executionId,
  onSelectProcessor,
}: DetailPanelProps) {
  const [activeTab, setActiveTab] = useState<DetailTab>('info');

  // When selectedProcessor changes, keep current tab unless it was a
  // processor-specific tab and now there is no processor selected.
  const prevProcessorId = selectedProcessor?.processorId;
  useEffect(() => {
    // If no processor is selected and we're on a processor-specific tab, go to info
    if (!selectedProcessor && (activeTab === 'input' || activeTab === 'output')) {
      // Input/Output at exchange level still make sense, keep them
    }
  }, [prevProcessorId]); // eslint-disable-line react-hooks/exhaustive-deps

  const hasError = selectedProcessor
    ? !!selectedProcessor.errorMessage
    : !!executionDetail.errorMessage;

  // Fetch snapshot for body/headers tabs when a processor is selected
  const snapshotQuery = useProcessorSnapshotById(
    selectedProcessor ? executionId : null,
    selectedProcessor?.processorId ?? null,
  );

  // Determine body content for Input/Output tabs
  let inputBody: string | undefined;
  let outputBody: string | undefined;
  let hasHeaders = false;
  let hasProperties = false;

  if (selectedProcessor && snapshotQuery.data) {
    inputBody = snapshotQuery.data.inputBody;
    outputBody = snapshotQuery.data.outputBody;
    hasHeaders = !!(snapshotQuery.data.inputHeaders || snapshotQuery.data.outputHeaders);
    hasProperties = !!(snapshotQuery.data.inputProperties || snapshotQuery.data.outputProperties);
  } else if (selectedProcessor && snapshotQuery.isLoading) {
    // Still loading — keep tabs enabled
    hasHeaders = true;
    hasProperties = true;
    inputBody = undefined;
    outputBody = undefined;
  } else if (!selectedProcessor) {
    inputBody = executionDetail.inputBody;
    outputBody = executionDetail.outputBody;
    hasHeaders = !!(executionDetail.inputHeaders || executionDetail.outputHeaders);
    hasProperties = !!(executionDetail.inputProperties || executionDetail.outputProperties);
  }

  const hasInput = !!inputBody;
  const hasOutput = !!outputBody;

  // If active tab becomes disabled, fall back to info
  useEffect(() => {
    if (activeTab === 'headers' && !hasHeaders) setActiveTab('info');
    if (activeTab === 'properties' && !hasProperties) setActiveTab('info');
    if (activeTab === 'input' && !hasInput) setActiveTab('info');
    if (activeTab === 'output' && !hasOutput) setActiveTab('info');
  }, [hasHeaders, hasProperties, hasInput, hasOutput, activeTab]);

  return (
    <div className={styles.detailPanel}>
      {/* Header bar */}
      <div className={styles.processorHeader}>
        <span className={styles.processorName}>{selectedProcessor ? 'Processor Details' : 'Exchange Details'}</span>
      </div>

      {/* Tab bar */}
      <div className={styles.tabBar}>
        {TABS.map((tab) => {
          const isActive = activeTab === tab.key;
          const isDisabled = tab.key === 'config'
            || (tab.key === 'headers' && !hasHeaders)
            || (tab.key === 'properties' && !hasProperties)
            || (tab.key === 'input' && !hasInput)
            || (tab.key === 'output' && !hasOutput);
          const isError = tab.key === 'error' && hasError;
          const isErrorGrayed = tab.key === 'error' && !hasError;

          let className = styles.tab;
          if (isActive) className += ` ${styles.tabActive}`;
          if (isDisabled) className += ` ${styles.tabDisabled}`;
          if (isError && !isActive) className += ` ${styles.tabError}`;
          if (isErrorGrayed && !isActive) className += ` ${styles.tabDisabled}`;

          return (
            <button
              key={tab.key}
              className={className}
              onClick={() => {
                if (!isDisabled) setActiveTab(tab.key);
              }}
              type="button"
            >
              {tab.label}
            </button>
          );
        })}
      </div>

      {/* Tab content */}
      <div className={styles.tabContent}>
        {activeTab === 'info' && (
          <InfoTab processor={selectedProcessor} executionDetail={executionDetail} />
        )}
        {activeTab === 'headers' && (
          <HeadersTab
            executionId={executionId}
            processorId={selectedProcessor?.processorId ?? null}
            exchangeInputHeaders={executionDetail.inputHeaders}
            exchangeOutputHeaders={executionDetail.outputHeaders}
          />
        )}
        {activeTab === 'properties' && (
          <PropertiesTab
            executionId={executionId}
            processorId={selectedProcessor?.processorId ?? null}
            exchangeInputProperties={executionDetail.inputProperties}
            exchangeOutputProperties={executionDetail.outputProperties}
          />
        )}
        {activeTab === 'input' && (
          <BodyTab body={inputBody} label="Input" />
        )}
        {activeTab === 'output' && (
          <BodyTab body={outputBody} label="Output" />
        )}
        {activeTab === 'error' && (
          <ErrorTab processor={selectedProcessor} executionDetail={executionDetail} />
        )}
        {activeTab === 'config' && (
          <ConfigTab />
        )}
        {activeTab === 'timeline' && (
          <TimelineTab
            executionDetail={executionDetail}
            selectedProcessorId={selectedProcessor?.processorId ?? null}
            onSelectProcessor={onSelectProcessor}
          />
        )}
        {activeTab === 'log' && (
          <LogTab
            applicationId={executionDetail.applicationId}
            exchangeId={executionDetail.exchangeId}
            processorId={selectedProcessor?.processorId ?? null}
          />
        )}
      </div>
    </div>
  );
}
