import { useEffect, useMemo } from 'react';
import { Edge } from '@xyflow/react';
import { WorkflowReactFlowNode, WorkflowNodeData } from '../types/reactflow';
import { ActionField } from '../types/action';
import { useAvailableContext } from '../hooks/useAvailableContext';
import { useDynamicOptions } from '../hooks/useDynamicOptions';
import { useDebouncedNodeConfig } from '../hooks/useDebouncedNodeConfig';
import { useTriggers, useActions } from '../context/DataContext';
import { ConfigPanelHeader } from './config-panel/ConfigPanelHeader';
import { TriggerConfigContent } from './config-panel/TriggerConfigContent';
import { ActionConfigContent } from './config-panel/ActionConfigContent';
import { __ } from '@/lib/i18n';

/**
 * Simplified node representation for ConfigPanel.
 * Maps ReactFlow node structure to a flat object for easier config form handling.
 */
interface Node {
  id: string;
  type: 'trigger' | 'action' | 'operator';
  name: string;
  icon: string;
  x: number;
  y: number;
  status: WorkflowNodeData['status'];
  errorCount?: number;
  config?: Record<string, unknown>;
  label?: string;
  actionType?: string;
  appService?: string;
}

interface ConfigPanelProps {
  node: Node;
  /** All nodes in the workflow (for variable context) */
  nodes: WorkflowReactFlowNode[];
  /** All edges in the workflow (for variable context) */
  edges: Edge[];
  onClose: () => void;
  onUpdate: (node: Node) => void;
  onDelete?: (nodeId: string) => void;
}

export function ConfigPanel({ node, nodes, edges, onClose, onUpdate, onDelete }: ConfigPanelProps) {
  // Use shared data from context instead of local state
  const {
    triggers,
    loading: isLoadingTriggers,
    error: triggersError,
    refetch: refetchTriggers,
  } = useTriggers();
  const {
    actions,
    loading: isLoadingActions,
    error: actionsError,
    refetch: refetchActions,
  } = useActions();

  // Debounced config management - handles node switches, unmount flush, and TipTap timing issues
  const {
    actionConfig,
    triggerFilters,
    handleFieldChange,
    handleTriggerFiltersChange,
    handleClose,
    applyDefaults,
  } = useDebouncedNodeConfig({ node, onUpdate, onClose });

  // Find the current trigger from the triggers list
  const currentTrigger = useMemo(() => {
    return triggers.find((t) => {
      if (node.actionType) {
        return t.type === node.actionType;
      }
      const nodeName = node.name.toLowerCase().replace(/ /g, '_');
      return t.type === nodeName || t.label === node.name;
    });
  }, [triggers, node.actionType, node.name]);

  // Find the current action from the actions list
  const currentAction = useMemo(() => {
    return actions.find((a) => {
      if (node.actionType) {
        return a.type === node.actionType;
      }
      const nodeName = node.name.toLowerCase().replace(/ /g, '_');
      return a.type === nodeName || a.label === node.name;
    });
  }, [actions, node.actionType, node.name]);

  // Apply schema defaults when action type is first configured
  useEffect(() => {
    if (!currentAction?.schema) return;

    const defaults: Record<string, unknown> = {};
    for (const [fieldName, field] of Object.entries(currentAction.schema)) {
      if (field.default !== undefined) {
        defaults[fieldName] = field.default;
      }
    }

    if (Object.keys(defaults).length > 0) {
      applyDefaults(defaults);
    }
  }, [currentAction?.type, applyDefaults]);

  // Use extracted hook for dynamic field options
  const {
    dynamicOptions,
    loadingFields: loadingDynamicFields,
    fieldErrors: dynamicFieldErrors,
    queueFetch,
  } = useDynamicOptions();

  // Compute available context variables from preceding nodes
  const availableContext = useAvailableContext({
    nodes,
    edges,
    currentNodeId: node.id,
    triggers,
    actions,
  });

  // Get action schema fields as sorted array
  const mainFields = useMemo(() => {
    if (!currentAction?.schema) return [];

    const sortFields = (fields: [string, ActionField][]) =>
      fields.sort(([keyA, fieldA], [keyB, fieldB]) => {
        const orderA = fieldA.order ?? 999;
        const orderB = fieldB.order ?? 999;
        if (orderA !== orderB) return orderA - orderB;
        return keyA.localeCompare(keyB, undefined, { sensitivity: 'base' });
      });

    const allFields = Object.entries(currentAction.schema).filter(([, field]) => !field.hidden) as [
      string,
      ActionField,
    ][];

    const main = allFields.filter(([, field]) => field.group !== 'advanced');

    return sortFields(main);
  }, [currentAction?.schema]);

  return (
    <div
      data-testid="config-panel"
      className="w-[576px] shrink-0 border-l border-slate-200 bg-white flex flex-col h-full min-h-0 animate-slide-in-right"
    >
      <ConfigPanelHeader
        node={node}
        currentTrigger={currentTrigger}
        currentAction={currentAction}
        isLoadingTriggers={isLoadingTriggers}
        handleClose={handleClose}
        onDelete={onDelete}
      />

      {/* Operator nodes show empty state */}
      {node.type === 'operator' && (
        <div className="flex-1 flex items-center justify-center p-8">
          <div className="text-center space-y-2">
            <p className="text-sm text-slate-500">{__('Operator configuration coming soon')}</p>
            <p className="text-xs text-slate-400">
              {__('Operators will support conditional logic and data transformation')}
            </p>
          </div>
        </div>
      )}

      {/* Trigger nodes: Show filters section */}
      {node.type === 'trigger' && (
        <div className="flex-1 flex flex-col min-h-0 overflow-y-auto">
          <div className="p-4 flex-1">
            <TriggerConfigContent
              trigger={currentTrigger}
              isLoading={isLoadingTriggers}
              error={triggersError}
              onRetry={refetchTriggers}
              filters={triggerFilters}
              onFiltersChange={handleTriggerFiltersChange}
            />
          </div>
        </div>
      )}

      {/* Action nodes: Show configuration form */}
      {node.type === 'action' && (
        <div className="flex-1 flex flex-col min-h-0 overflow-y-auto">
          <div className="px-6 py-5 space-y-5">
            <ActionConfigContent
              action={currentAction}
              isLoading={isLoadingActions}
              error={actionsError}
              onRetry={refetchActions}
              actionConfig={actionConfig}
              onFieldChange={handleFieldChange}
              availableContext={availableContext}
              mainFields={mainFields}
              dynamicOptions={dynamicOptions}
              loadingDynamicFields={loadingDynamicFields}
              dynamicFieldErrors={dynamicFieldErrors}
              onQueueFetch={queueFetch}
            />
          </div>
        </div>
      )}
    </div>
  );
}
