'use client';

import React, { useState, useCallback, useMemo } from 'react';
import { 
  Plus, 
  Trash2, 
  AlertTriangle,
  ChevronsUpDown,
  Check,
  MoreHorizontal
} from 'lucide-react';
import { Button } from '@/components/ui/button';

import { Label } from '@/components/ui/label';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
import { cn } from '@/lib/utils';
import { Input } from '@/components/ui/input';

export interface ConditionalStep {
  id: string;
  name: string;
  description: string;
  type: 'instruction' | 'condition' | 'parallel' | 'sequence';
  config: Record<string, any>;
  conditions?: {
    type: 'if' | 'else' | 'elseif';
    expression?: string;
  };
  children?: ConditionalStep[];
  order: number;
  enabled?: boolean;
  hasIssues?: boolean;
}

interface ConditionalWorkflowBuilderProps {
  steps: ConditionalStep[];
  onStepsChange: (steps: ConditionalStep[]) => void;
  agentTools?: {
    agentpress_tools: Array<{ name: string; description: string; icon?: string; enabled: boolean }>;
    mcp_tools: Array<{ name: string; description: string; icon?: string; server?: string }>;
  };
  isLoadingTools?: boolean;
}

const normalizeToolName = (toolName: string, toolType: 'agentpress' | 'mcp') => {
  if (toolType === 'agentpress') {
    const agentPressMapping: Record<string, string> = {
      'sb_shell_tool': 'Shell Tool',
      'sb_files_tool': 'Files Tool',
      'sb_browser_tool': 'Browser Tool',
      'sb_deploy_tool': 'Deploy Tool',
      'sb_expose_tool': 'Expose Tool',
      'web_search_tool': 'Web Search',
      'sb_vision_tool': 'Vision Tool',
      'data_providers_tool': 'Data Providers',
    };
    return agentPressMapping[toolName] || toolName;
  } else {
    return toolName
      .split('_')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
      .join(' ');
  }
};

export function ConditionalWorkflowBuilder({ 
  steps, 
  onStepsChange, 
  agentTools,
  isLoadingTools 
}: ConditionalWorkflowBuilderProps) {
  const [toolSearchOpen, setToolSearchOpen] = useState<{[key: string]: boolean}>({});
  const [activeConditionTab, setActiveConditionTab] = useState<{[key: string]: string}>({});

  steps.forEach((step, index) => {
    console.log(`Step ${index}:`, {
      name: step.name,
      type: step.type,
      hasChildren: !!step.children,
      childrenCount: step.children?.length || 0,
      children: step.children?.map(child => ({ name: child.name, type: child.type }))
    });
  });

  const generateId = () => Math.random().toString(36).substr(2, 9);

  const addStep = useCallback((parentId?: string, afterStepId?: string) => {
    const newStep: ConditionalStep = {
      id: generateId(),
      name: 'Step',
      description: '',
      type: 'instruction',
      config: {},
      order: 0,
      enabled: true,
    };
    const updateSteps = (items: ConditionalStep[]): ConditionalStep[] => {
      if (!parentId) {
        if (afterStepId) {
          const index = items.findIndex(s => s.id === afterStepId);
          return [...items.slice(0, index + 1), newStep, ...items.slice(index + 1)];
        }
        return [...items, newStep];
      }

      return items.map(step => {
        if (step.id === parentId) {
          return {
            ...step,
            children: [...(step.children || []), newStep]
          };
        }
        if (step.children) {
          return {
            ...step,
            children: updateSteps(step.children)
          };
        }
        return step;
      });
    };

    onStepsChange(updateSteps(steps));
  }, [steps, onStepsChange]);

  const addCondition = useCallback((afterStepId: string) => {
    const ifStep: ConditionalStep = {
      id: generateId(),
      name: 'If',
      description: '',
      type: 'condition',
      config: {},
      conditions: { type: 'if', expression: '' },
      children: [],
      order: 0,
      enabled: true,
      hasIssues: true
    };

    const updateSteps = (items: ConditionalStep[]): ConditionalStep[] => {
      const index = items.findIndex(s => s.id === afterStepId);
      if (index !== -1) {
        return [
          ...items.slice(0, index + 1),
          ifStep,
          ...items.slice(index + 1)
        ];
      }
      
      return items.map(step => {
        if (step.children) {
          return {
            ...step,
            children: updateSteps(step.children)
          };
        }
        return step;
      });
    };

    onStepsChange(updateSteps(steps));
  }, [steps, onStepsChange]);

  const addElseCondition = useCallback((siblingId: string) => {
    const elseIfStep: ConditionalStep = {
      id: generateId(),
      name: 'Else If',
      description: '',
      type: 'condition',
      config: {},
      conditions: { type: 'elseif', expression: '' },
      children: [],
      order: 0,
      enabled: true,
      hasIssues: true
    };

    const updateSteps = (items: ConditionalStep[]): ConditionalStep[] => {
      const index = items.findIndex(s => s.id === siblingId);
      if (index !== -1) {
        return [
          ...items.slice(0, index + 1),
          elseIfStep,
          ...items.slice(index + 1)
        ];
      }
      
      return items.map(step => {
        if (step.children) {
          return {
            ...step,
            children: updateSteps(step.children)
          };
        }
        return step;
      });
    };

    onStepsChange(updateSteps(steps));
  }, [steps, onStepsChange]);

  const addFinalElse = useCallback((siblingId: string) => {
    const elseStep: ConditionalStep = {
      id: generateId(),
      name: 'Else',
      description: '',
      type: 'condition',
      config: {},
      conditions: { type: 'else' },
      children: [],
      order: 0,
      enabled: true,
      hasIssues: false
    };

    const updateSteps = (items: ConditionalStep[]): ConditionalStep[] => {
      const index = items.findIndex(s => s.id === siblingId);
      if (index !== -1) {
        return [
          ...items.slice(0, index + 1),
          elseStep,
          ...items.slice(index + 1)
        ];
      }
      
      return items.map(step => {
        if (step.children) {
          return {
            ...step,
            children: updateSteps(step.children)
          };
        }
        return step;
      });
    };

    onStepsChange(updateSteps(steps));
  }, [steps, onStepsChange]);

  const updateStep = useCallback((stepId: string, updates: Partial<ConditionalStep>) => {
    const updateSteps = (items: ConditionalStep[]): ConditionalStep[] => {
      return items.map(step => {
        if (step.id === stepId) {
          const updatedStep = { ...step, ...updates };
          if (updatedStep.type === 'instruction' && updatedStep.name && updatedStep.name !== 'New Step') {
            updatedStep.hasIssues = false;
          } else if (updatedStep.type === 'condition' && 
                    (updatedStep.conditions?.type === 'if' || updatedStep.conditions?.type === 'elseif') && 
                    updatedStep.conditions?.expression) {
            updatedStep.hasIssues = false;
          } else if (updatedStep.type === 'condition' && updatedStep.conditions?.type === 'else') {
            updatedStep.hasIssues = false;
          }
          return updatedStep;
        }
        if (step.children) {
          return {
            ...step,
            children: updateSteps(step.children)
          };
        }
        return step;
      });
    };
    onStepsChange(updateSteps(steps));
  }, [steps, onStepsChange]);

  const removeStep = useCallback((stepId: string) => {
    const removeFromSteps = (items: ConditionalStep[]): ConditionalStep[] => {
      return items
        .filter(step => step.id !== stepId)
        .map(step => {
          if (step.children) {
            return {
              ...step,
              children: removeFromSteps(step.children)
            };
          }
          return step;
        });
    };

    onStepsChange(removeFromSteps(steps));
  }, [steps, onStepsChange]);

  const getStepNumber = useCallback((stepId: string, items: ConditionalStep[] = steps, counter = { value: 0 }): number => {
    for (const step of items) {
      counter.value++;
      if (step.id === stepId) {
        return counter.value;
      }
      if (step.children && step.children.length > 0) {
        const found = getStepNumber(stepId, step.children, counter);
        if (found > 0) return found;
      }
    }
    return 0;
  }, [steps]);

  const getConditionLetter = (index: number) => {
    return String.fromCharCode(65 + index);
  };

  const renderConditionTabs = (conditionSteps: ConditionalStep[], groupKey: string) => {
    const activeTabId = activeConditionTab[groupKey] || conditionSteps[0]?.id;
    const activeStep = conditionSteps.find(s => s.id === activeTabId) || conditionSteps[0];
    const hasElse = conditionSteps.some(step => step.conditions?.type === 'else');

    const handleKeyDown = (e: React.KeyboardEvent, step: ConditionalStep) => {
      if (e.key === 'Backspace' || e.key === 'Delete') {
        e.preventDefault();
        if (conditionSteps.length > 1 && !(conditionSteps.length === 1 && step.conditions?.type === 'if')) {
          removeStep(step.id);
          const remainingConditions = conditionSteps.filter(s => s.id !== step.id);
          if (remainingConditions.length > 0) {
            setActiveConditionTab(prev => ({ ...prev, [groupKey]: remainingConditions[0].id }));
          }
        }
      }
    };

    return (
      <div className="space-y-4">
        <div className="flex items-center gap-2">
          {conditionSteps.map((step, index) => {
            const letter = getConditionLetter(index);
            const isActive = step.id === activeTabId;
            const conditionType = step.conditions?.type === 'if' ? 'If' : 
                                step.conditions?.type === 'elseif' ? 'Else If' :
                                step.conditions?.type === 'else' ? 'Else' : 'If';
            return (
              <button
                key={step.id}
                onClick={() => setActiveConditionTab(prev => ({ ...prev, [groupKey]: step.id }))}
                onKeyDown={(e) => handleKeyDown(e, step)}
                tabIndex={0}
                className={cn(
                  "flex items-center gap-2 px-3 py-2 rounded-md border text-sm font-medium transition-all",
                  isActive 
                    ? "bg-primary text-primary-foreground border-primary shadow-sm"
                    : "bg-background border-border text-foreground hover:bg-accent hover:text-accent-foreground"
                )}
              >
                <span className="font-mono text-xs">{letter}</span>
                <span>•</span>
                <span>{conditionType}</span>
                {step.hasIssues && (
                  <AlertTriangle className="h-3 w-3 text-destructive" />
                )}
              </button>
            );
          })}
          {!hasElse && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => addElseCondition(conditionSteps[conditionSteps.length - 1].id)}
              className="h-9 px-3 border-dashed text-xs"
            >
              <Plus className="h-3 w-3 mr-1" />
              Else If
            </Button>
          )}
          {!hasElse && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => addFinalElse(conditionSteps[conditionSteps.length - 1].id)}
              className="h-9 px-3 border-dashed text-xs"
            >
              <Plus className="h-3 w-3 mr-1" />
              Else
            </Button>
          )}
        </div>
        {activeStep && (
          <div className="bg-muted/50 rounded-lg p-4 border">
            {(activeStep.conditions?.type === 'if' || activeStep.conditions?.type === 'elseif') ? (
              <div className="space-y-3">
                <Label className="text-sm font-medium">
                  {activeStep.conditions?.type === 'if' ? 'Condition' : 'Else If Condition'}
                </Label>
                <Input
                  type="text"
                  value={activeStep.conditions.expression || ''}
                  onChange={(e) => updateStep(activeStep.id, { 
                    conditions: { ...activeStep.conditions, expression: e.target.value } 
                  })}
                  placeholder="e.g., user asks about pricing"
                  className="w-full bg-transparent text-sm px-3 py-2 rounded-md"
                />
              </div>
            ) : (
              <div className="text-sm text-muted-foreground font-medium">
                Otherwise (fallback condition)
              </div>
            )}
            <div className="mt-4 space-y-3">
              {activeStep.children && activeStep.children.length > 0 && (
                <>
                  {activeStep.children.map((child, index) => renderStep(child, index + 1, true, activeStep.id))}
                </>
              )}
              <div className="flex justify-center pt-2">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => addStep(activeStep.id)}
                  className="border-dashed text-xs"
                >
                  <Plus className="h-3 w-3" />
                  Add step
                </Button>
              </div>
            </div>
          </div>
        )}
      </div>
    );
  };

  const renderStep = (step: ConditionalStep, stepNumber: number, isNested: boolean = false, parentId?: string) => {
    const isCondition = step.type === 'condition';
    const isSequence = step.type === 'sequence';

    if (isCondition) {
      return null;
    }

    return (
      <div key={step.id} className="group">
        <div className="bg-card rounded-lg border shadow-sm p-4 transition-shadow">
          <div className="flex items-start gap-4">
            <div className="flex items-center gap-2 shrink-0">
              {step.hasIssues && (
                <AlertTriangle className="h-4 w-4 text-destructive" />
              )}
              <div className="w-6 h-6 rounded-full bg-muted flex items-center justify-center text-sm font-medium text-muted-foreground">
                {stepNumber}
              </div>
            </div>

            <div className="flex-1 min-w-0">
              <div className="flex items-center justify-between mb-3">
                {isSequence ? (
                  <div className="flex items-center gap-2">
                    <div className="w-5 h-5 rounded bg-primary/10 flex items-center justify-center">
                      <div className="w-2 h-2 rounded-full bg-primary" />
                    </div>
                    <span className="text-base font-medium">{step.description}</span>
                  </div>
                ) : (
                  <input
                    type="text"
                    value={step.name + ' ' + stepNumber}
                    onChange={(e) => updateStep(step.id, { name: e.target.value })}
                    placeholder="Step name"
                    className="w-full bg-transparent border-0 outline-none text-base font-medium placeholder:text-muted-foreground"
                  />
                )}
              </div>
              {!isSequence && step.description !== undefined && (
                <input
                  type="text"
                  value={step.description}
                  onChange={(e) => updateStep(step.id, { description: e.target.value })}
                  placeholder="Add a description"
                  className="-mt-2 w-full bg-transparent border-0 outline-none text-sm text-muted-foreground placeholder:text-muted-foreground mb-3"
                />
              )}
              {!isSequence && (
                <Popover 
                  open={toolSearchOpen[step.id] || false} 
                  onOpenChange={(open) => setToolSearchOpen(prev => ({ ...prev, [step.id]: open }))}
                >
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={toolSearchOpen[step.id] || false}
                      className="h-9 w-full justify-between text-sm"
                    >
                      {step.config.tool_name ? (
                        <span className="flex items-center gap-2 text-sm">
                          {(() => {
                            const agentpressTool = agentTools?.agentpress_tools.find(t => t.name === step.config.tool_name);
                            if (agentpressTool) {
                              return (
                                <>
                                  <span>{agentpressTool.icon || '🔧'}</span>
                                  <span>{normalizeToolName(agentpressTool.name, 'agentpress')}</span>
                                </>
                              );
                            }
                            const mcpTool = agentTools?.mcp_tools.find(t => `${t.server}:${t.name}` === step.config.tool_name);
                            if (mcpTool) {
                              return (
                                <>
                                  <span>{mcpTool.icon || '🔧'}</span>
                                  <span>{normalizeToolName(mcpTool.name, 'mcp')}</span>
                                </>
                              );
                            }
                            return step.config.tool_name;
                          })()}
                        </span>
                      ) : (
                        <span className="text-muted-foreground">Select tool (optional)</span>
                      )}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-[320px] p-0" align="start">
                    <Command>
                      <CommandInput placeholder="Search tools..." className="h-9" />
                      <CommandEmpty>No tools found.</CommandEmpty>
                      <CommandList>
                        {isLoadingTools ? (
                          <CommandItem disabled>Loading tools...</CommandItem>
                        ) : agentTools ? (
                          <>
                            {agentTools.agentpress_tools.filter(tool => tool.enabled).length > 0 && (
                              <CommandGroup heading="Default Tools">
                                {agentTools.agentpress_tools.filter(tool => tool.enabled).map((tool) => (
                                  <CommandItem
                                    key={tool.name}
                                    value={`${normalizeToolName(tool.name, 'agentpress')} ${tool.name}`}
                                    onSelect={() => {
                                      updateStep(step.id, { config: { ...step.config, tool_name: tool.name } });
                                      setToolSearchOpen(prev => ({ ...prev, [step.id]: false }));
                                    }}
                                  >
                                    <div className="flex items-center gap-2">
                                      <span>{tool.icon || '🔧'}</span>
                                      <span>{normalizeToolName(tool.name, 'agentpress')}</span>
                                    </div>
                                    <Check
                                      className={cn(
                                        "ml-auto h-4 w-4",
                                        step.config.tool_name === tool.name ? "opacity-100" : "opacity-0"
                                      )}
                                    />
                                  </CommandItem>
                                ))}
                              </CommandGroup>
                            )}
                            {agentTools.mcp_tools.length > 0 && (
                              <CommandGroup heading="External Tools">
                                {agentTools.mcp_tools.map((tool) => (
                                  <CommandItem
                                    key={`${tool.server || 'default'}-${tool.name}`}
                                    value={`${normalizeToolName(tool.name, 'mcp')} ${tool.name} ${tool.server || ''}`}
                                    onSelect={() => {
                                      updateStep(step.id, { config: { ...step.config, tool_name: tool.server ? `${tool.server}:${tool.name}` : tool.name } });
                                      setToolSearchOpen(prev => ({ ...prev, [step.id]: false }));
                                    }}
                                  >
                                    <div className="flex items-center gap-2">
                                      <span>{tool.icon || '🔧'}</span>
                                      <span>{normalizeToolName(tool.name, 'mcp')}</span>
                                    </div>
                                    <Check
                                      className={cn(
                                        "ml-auto h-4 w-4",
                                        step.config.tool_name === (tool.server ? `${tool.server}:${tool.name}` : tool.name) ? "opacity-100" : "opacity-0"
                                      )}
                                    />
                                  </CommandItem>
                                ))}
                              </CommandGroup>
                            )}
                          </>
                        ) : (
                          <CommandItem disabled>Failed to load tools</CommandItem>
                        )}
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
              )}
              {step.children && step.children.length > 0 && (
                <div className="mt-4 space-y-4">
                  {step.children.map((child, index) => renderStep(child, index + 1, true, step.id))}
                </div>
              )}
            </div>
            <Popover>
              <PopoverTrigger asChild>
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0 opacity-0 group-hover:opacity-100 transition-opacity">
                  <MoreHorizontal className="h-4 w-4" />
                </Button>
              </PopoverTrigger>
              <PopoverContent className="w-48 p-1" align="end">
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => removeStep(step.id)}
                  className="w-full justify-start text-destructive hover:text-destructive hover:bg-destructive/10"
                >
                  <Trash2 className="h-4 w-4 mr-2" />
                  Delete step
                </Button>
              </PopoverContent>
            </Popover>
          </div>
        </div>
      </div>
    );
  };

  const renderSteps = () => {
    const result: React.ReactNode[] = [];
    let stepCounter = 0;
    let i = 0;

    while (i < steps.length) {
      const step = steps[i];
      if (step.type === 'condition') {
        const conditionGroup: ConditionalStep[] = [];
        while (i < steps.length && steps[i].type === 'condition') {
          conditionGroup.push(steps[i]);
          i++;
        }
        stepCounter++;
        result.push(
          <div key={conditionGroup[0].id} className="bg-card rounded-lg border shadow-sm p-4 transition-shadow">
            <div className="flex items-start gap-4">
              <div className="flex items-center gap-2 shrink-0">
                <div className="w-6 h-6 rounded-full bg-muted flex items-center justify-center text-sm font-medium text-muted-foreground">
                  {stepCounter}
                </div>
              </div>
              <div className="flex-1">
                <div className="text-base font-medium mb-4">Add rule</div>
                {renderConditionTabs(conditionGroup, conditionGroup[0].id)}
              </div>
            </div>
          </div>
        );
      } else {
        stepCounter++;
        result.push(renderStep(step, stepCounter, false));
        i++;
      }
    }

    return result;
  };

  return (
    <div className="space-y-6 max-w-4xl">
      {steps.length === 0 ? (
        <div className="text-center py-16">
          <div className="w-16 h-16 bg-muted rounded-2xl flex items-center justify-center mx-auto mb-4">
            <Plus className="h-8 w-8 text-muted-foreground" />
          </div>
          <h3 className="text-lg font-semibold mb-2">Start building your workflow</h3>
          <p className="text-muted-foreground mb-6 max-w-md mx-auto">
            Add steps and conditions to create a smart workflow that adapts to different scenarios.
          </p>
          <Button 
            onClick={() => addStep()}
          >
            <Plus className="h-4 w-4" />
            Add step
          </Button>
        </div>
      ) : (
        <div className="space-y-6">
          {renderSteps()}
          <div className="flex justify-center pt-4">
            <div className="flex gap-3">
              <Button 
                variant="outline"
                onClick={() => addStep()}
                className="border-dashed"
              >
                <Plus className="h-4 w-4" />
                Add step
              </Button>
              
              <Button 
                variant="outline"
                onClick={() => addCondition(steps[steps.length - 1]?.id || '')}
                className="border-dashed"
              >
                <Plus className="h-4 w-4" />
                Add rule
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
