import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { themedColor } from '../../theme';
import { ActivityIndicator, Modal, Pressable, ScrollView, Text, View } from 'react-native';
import {
  AlertCircle,
  Archive,
  ChevronDown,
  ChevronLeft,
  Coins,
  Edit3,
  FileText,
  GitBranch,
  Play,
  RefreshCw,
  RotateCcw,
  Settings,
  Timer,
  ToggleLeft,
  ToggleRight,
  Trash2,
  Webhook,
  X,
  Zap,
  type LucideIcon,
} from 'lucide-react-native';

import { AgentSettingsPanel } from '../settings/AgentSettingsPanel';
import { ChannelsPanel } from '../channels/ChannelsPanel';
import { ConnectorsPanel } from '../connectors/ConnectorsPanel';
import { SUPERAGENT_CONNECTOR_CATALOG } from '../connectors/connectorCatalog';
import { featureRefreshKeys, getEditorTabLabel } from '../settings/featureMenu';
import { editorShellStyles } from './editorShellStyles';
import { FilesPanel } from './FilesPanel';
import { SharingPanel } from '../sharing/SharingPanel';
import { useAgentBi } from '../../analytics/mixpanelContext';
import { useSuperagentAutomations, useSuperagentRuntimeContext, useSuperagentWorkflows } from '../../runtime/runtimeContext';
import { styles } from '../../styles';
import {
  describeWorkflowTrigger,
  formatWorkflowRuns,
  formatWorkflowStatus,
  isDeactivatedByFailures,
  isWorkflowActive,
  isWorkflowArchived,
  sortWorkflows,
} from './workflowUtils';
import type {
  SuperagentAgent,
  SuperagentAutomation,
  SuperagentAutomationActionInput,
  SuperagentAutomationCreditsSummary,
  SuperagentEditorTab,
  SuperagentWorkflow,
  SuperagentWorkflowActionInput,
} from '../../types';

const AUTOMATION_ICONS: Partial<Record<SuperagentAutomation['automation_type'], LucideIcon>> = {
  connector: Webhook,
  entity: Zap,
  scheduled: Timer,
};

export function EditorDrawer({
  activeTab,
  agent,
  isVisible,
  onClose,
}: {
  activeTab: SuperagentEditorTab;
  agent: SuperagentAgent;
  isVisible: boolean;
  onClose: () => void;
}) {
  // The modal always shows exactly the one feature it was opened for; each panel
  // reads its own runtime slice from context, so the drawer only routes by tab.
  const effectiveTab = activeTab === 'chat' ? 'connectors' : activeTab;
  // Generic "refresh this modal's data" header action. Which domains a tab
  // reloads is owned by featureMenu (FEATURE_TABS[].refresh); we just resolve
  // each to its runtime handler + loading flag, so any refreshable tab gets the
  // button with nothing wired panel-side.
  const runtime = useSuperagentRuntimeContext();
  const bi = useAgentBi();
  const activeRefreshers = featureRefreshKeys(effectiveTab)
    .map((key): { refresh?: (agentId: string) => Promise<void> | void; loading?: boolean } => {
      switch (key) {
        case 'channels': return { refresh: runtime.onRefreshChannels, loading: runtime.isLoadingChannels };
        case 'files': return { refresh: runtime.onRefreshFiles, loading: runtime.isLoadingFiles };
        case 'automations': return agent.workflowsEnabled
          ? { refresh: runtime.onRefreshWorkflows, loading: runtime.isLoadingWorkflows }
          : { refresh: runtime.onRefreshAutomations, loading: runtime.isLoadingAutomations };
        case 'agentSettings': return { refresh: runtime.onRefreshAgentSettings, loading: runtime.isLoadingAgentSettings };
        case 'collaborators': return { refresh: runtime.onRefreshCollaborators, loading: runtime.isLoadingCollaborators };
      }
    })
    .filter((entry): entry is { refresh: (agentId: string) => Promise<void> | void; loading?: boolean } => !!entry.refresh);
  const onRefresh = activeRefreshers.length
    ? (agentId: string) => activeRefreshers.forEach((entry) => entry.refresh(agentId))
    : undefined;
  const isRefreshing = activeRefreshers.some((entry) => entry.loading);

  // A panel with in-place sub-navigation (e.g. Connectors → connector detail)
  // registers a back handler here so the top-bar shows a ← that pops one level,
  // instead of the ✕ (which closes the whole sheet). Reset when the tab changes
  // or the sheet is hidden so reopening always starts at the panel's main view.
  const [panelBack, setPanelBack] = useState<(() => void) | null>(null);
  const registerPanelBack = useCallback((back: (() => void) | null) => setPanelBack(() => back), []);
  useEffect(() => {
    setPanelBack(null);
  }, [effectiveTab, isVisible]);

  return (
    <Modal animationType="slide" presentationStyle="pageSheet" visible={isVisible} onRequestClose={panelBack ?? onClose}>
      <View style={editorShellStyles.modalRoot}>
        <View style={editorShellStyles.modalTopBar}>
          <Pressable accessibilityLabel={panelBack ? 'Back' : 'Close settings'} accessibilityRole="button" onPress={panelBack ?? onClose} style={({ pressed }) => [
            editorShellStyles.closeButton,
            pressed && styles.pressed,
          ]}>
            {panelBack ? (
              <ChevronLeft color={themedColor('#F4F4F5')} size={24} strokeWidth={2.5} />
            ) : (
              <X color={themedColor('#F4F4F5')} size={22} strokeWidth={2.5} />
            )}
          </Pressable>
          <View style={editorShellStyles.modalTitleWrap}>
            <Text style={editorShellStyles.modalTitle}>{getEditorTabLabel(effectiveTab)}</Text>
          </View>
          {onRefresh ? (
            <Pressable
              accessibilityLabel="Refresh"
              accessibilityRole="button"
              disabled={isRefreshing}
              onPress={() => {
                void bi.trackEditor('Feature Refresh', { feature: effectiveTab });
                onRefresh(agent.id);
              }}
              style={({ pressed }) => [editorShellStyles.closeButton, pressed && styles.pressed]}
            >
              {isRefreshing ? (
                <ActivityIndicator color={themedColor('#F4F4F5')} size="small" />
              ) : (
                <RefreshCw color={themedColor('#F4F4F5')} size={19} strokeWidth={2.4} />
              )}
            </Pressable>
          ) : null}
        </View>

        <ScrollView
          contentContainerStyle={editorShellStyles.modalScrollContent}
          keyboardShouldPersistTaps="handled"
          showsVerticalScrollIndicator={false}
        >
          {effectiveTab === 'connectors' ? (
            <ConnectorsPanel agent={agent} isVisible={isVisible} onBackHandlerChange={registerPanelBack} />
          ) : effectiveTab === 'automations' ? (
            <TasksPanel agent={agent} />
          ) : effectiveTab === 'files' ? (
            <FilesPanel agent={agent} />
          ) : effectiveTab === 'channels' ? (
            <ChannelsPanel agent={agent} />
          ) : effectiveTab === 'agent_settings' ? (
            <AgentSettingsPanel agent={agent} section="general" />
          ) : effectiveTab === 'security' ? (
            <AgentSettingsPanel agent={agent} section="security" />
          ) : effectiveTab === 'sharing' ? (
            <SharingPanel agent={agent} onClose={onClose} />
          ) : (
            <PlaceholderSettingsPanel tab={effectiveTab} />
          )}
        </ScrollView>
      </View>
    </Modal>
  );
}

function TasksPanel({ agent }: { agent: SuperagentAgent }) {
  // An agent runs EITHER the workflows pipeline OR legacy automations — never
  // both. Gate on the agent flag so a workflows-enabled agent shows its
  // workflows here instead of an always-empty automations list.
  return agent.workflowsEnabled ? <WorkflowsPanel agent={agent} /> : <AutomationsPanel agent={agent} />;
}

function AutomationsPanel({ agent }: { agent: SuperagentAgent }) {
  const {
    automations = [],
    automationCredits = {},
    automationLoadError,
    isLoadingAutomations: isLoading,
    onArchiveAutomation,
    onDeleteAutomation,
    onEditAutomation,
    onRestoreAutomation,
    onRefreshAutomations,
    onRunAutomationNow,
    onToggleAutomation,
  } = useSuperagentAutomations();
  const bi = useAgentBi();
  const [viewTab, setViewTab] = useState<'active' | 'archived'>('active');
  const switchView = (view: 'active' | 'archived') => {
    if (view === viewTab) return; // no-op re-tap of the active tab
    void bi.trackEditor('Automations View Switch', { view });
    setViewTab(view);
  };
  const sortedAutomations = useMemo(
    () => [...automations].sort((a, b) => getAutomationTime(b) - getAutomationTime(a)),
    [automations],
  );
  const activeAutomations = sortedAutomations.filter((automation) => !automation.is_archived);
  const archivedAutomations = sortedAutomations.filter((automation) => automation.is_archived);

  if (isLoading && automations.length === 0) {
    return (
      <View style={editorShellStyles.loadingPanel}>
        <ActivityIndicator color={themedColor('#FF5A1F')} />
        <Text style={editorShellStyles.loadingText}>Loading automations...</Text>
      </View>
    );
  }

  const displayAutomations = viewTab === 'archived' ? archivedAutomations : activeAutomations;

  return (
    <View style={editorShellStyles.settingsStack}>
      <View style={editorShellStyles.panel}>
        <View style={editorShellStyles.panelHeader}>
          <View>
            <Text style={editorShellStyles.panelTitle}>Automations</Text>
          </View>
          <Text style={editorShellStyles.countBadge}>{displayAutomations.length}</Text>
        </View>

        {automationLoadError ? (
          <View style={editorShellStyles.automationErrorBanner}>
            <AlertCircle color={themedColor('#FCA5A5')} size={18} strokeWidth={2.3} />
            <Text style={editorShellStyles.automationErrorText}>Couldn’t load automations.</Text>
            <Pressable
              accessibilityLabel="Retry loading automations"
              accessibilityRole="button"
              onPress={() => void onRefreshAutomations?.(agent.id)}
              style={({ pressed }) => [
                editorShellStyles.automationRetryButton,
                pressed && styles.pressed,
              ]}
            >
              <RotateCcw color={themedColor('#F4F4F5')} size={14} strokeWidth={2.4} />
              <Text style={editorShellStyles.automationRetryText}>Retry</Text>
            </Pressable>
          </View>
        ) : null}

        <View style={editorShellStyles.automationTabs}>
          <Pressable
            accessibilityRole="button"
            onPress={() => switchView('active')}
            style={({ pressed }) => [
              editorShellStyles.automationTabButton,
              viewTab === 'active' && editorShellStyles.automationTabButtonActive,
              pressed && styles.pressed,
            ]}
          >
            <Text style={[
              editorShellStyles.automationTabText,
              viewTab === 'active' && editorShellStyles.automationTabTextActive,
            ]}>Active {activeAutomations.length}</Text>
          </Pressable>
          <Pressable
            accessibilityRole="button"
            onPress={() => switchView('archived')}
            style={({ pressed }) => [
              editorShellStyles.automationTabButton,
              viewTab === 'archived' && editorShellStyles.automationTabButtonActive,
              pressed && styles.pressed,
            ]}
          >
            <Text style={[
              editorShellStyles.automationTabText,
              viewTab === 'archived' && editorShellStyles.automationTabTextActive,
            ]}>Archived {archivedAutomations.length}</Text>
          </Pressable>
        </View>

        {displayAutomations.length > 0 ? (
          <View style={editorShellStyles.automationList}>
            {displayAutomations.map((automation) => (
              <AutomationCard
                agentId={agent.id}
                automation={automation}
                credits={automationCredits[automation.id]}
                key={automation.id}
                onArchiveAutomation={onArchiveAutomation}
                onDeleteAutomation={onDeleteAutomation}
                onEditAutomation={onEditAutomation}
                onRestoreAutomation={onRestoreAutomation}
                onRunAutomationNow={onRunAutomationNow}
                onToggleAutomation={onToggleAutomation}
              />
            ))}
          </View>
        ) : automationLoadError ? null : (
          <View style={editorShellStyles.emptyPanel}>
            {viewTab === 'archived' ? (
              <Archive color={themedColor('#8E8E93')} size={22} strokeWidth={2.2} />
            ) : (
              <Timer color={themedColor('#8E8E93')} size={22} strokeWidth={2.2} />
            )}
            <Text style={editorShellStyles.emptyTitle}>
              {viewTab === 'archived' ? 'No archived automations' : 'No automations yet'}
            </Text>
            <Text style={editorShellStyles.emptyBody}>
              {viewTab === 'archived'
                ? 'Automations you archive will appear here.'
                : 'Ask Superagent to create a scheduled or connector task.'}
            </Text>
          </View>
        )}
      </View>
    </View>
  );
}

type AutomationPendingAction = 'archive' | 'delete' | 'edit' | 'restore' | 'run' | 'toggle';

function AutomationCard({
  agentId,
  automation,
  credits,
  onArchiveAutomation,
  onDeleteAutomation,
  onEditAutomation,
  onRestoreAutomation,
  onRunAutomationNow,
  onToggleAutomation,
}: {
  agentId: string;
  automation: SuperagentAutomation;
  credits?: SuperagentAutomationCreditsSummary;
  onArchiveAutomation?: (input: SuperagentAutomationActionInput) => Promise<void> | void;
  onDeleteAutomation?: (input: SuperagentAutomationActionInput) => Promise<void> | void;
  onEditAutomation?: (input: SuperagentAutomationActionInput) => Promise<void> | void;
  onRestoreAutomation?: (input: SuperagentAutomationActionInput) => Promise<void> | void;
  onRunAutomationNow?: (input: SuperagentAutomationActionInput) => Promise<void> | void;
  onToggleAutomation?: (input: SuperagentAutomationActionInput) => Promise<void> | void;
}) {
  const [expanded, setExpanded] = useState(false);
  const [pendingAction, setPendingAction] = useState<AutomationPendingAction | null>(null);
  const Icon = AUTOMATION_ICONS[automation.automation_type] ?? Timer;
  const trigger = describeAutomationTrigger(automation);
  const lastRun = formatDateTime(automation.last_run_at);
  const isArchived = !!automation.is_archived;
  const isActive = !isArchived && automation.is_active !== false;
  const canRunNow = automation.automation_type === 'scheduled' && !isArchived && !!onRunAutomationNow;
  const actionInput = { agentId, automation };

  const runAction = async (
    action: AutomationPendingAction,
    handler?: (input: SuperagentAutomationActionInput) => Promise<void> | void,
  ) => {
    if (!handler || pendingAction) {
      return;
    }

    setPendingAction(action);
    try {
      await handler(actionInput);
    } finally {
      setPendingAction(null);
    }
  };

  return (
    <View style={editorShellStyles.automationCard}>
      <View style={editorShellStyles.automationIcon}>
        <Icon color={themedColor('#F4F4F5')} size={19} strokeWidth={2.35} />
      </View>
      <View style={editorShellStyles.automationText}>
        <View style={editorShellStyles.inlineTitleRow}>
          <Text numberOfLines={1} style={editorShellStyles.automationName}>{automation.name}</Text>
          <AutomationStatusBadge automation={automation} />
        </View>
        {trigger ? (
          <Text numberOfLines={2} style={editorShellStyles.automationTrigger}>{trigger}</Text>
        ) : null}
        {automation.description ? (
          <Text numberOfLines={2} style={editorShellStyles.automationDescription}>{automation.description}</Text>
        ) : null}
        <View style={editorShellStyles.automationMetaRow}>
          <Text numberOfLines={1} style={editorShellStyles.automationMeta}>
            {formatAutomationType(automation.automation_type)}
          </Text>
          {automation.function_name ? (
            <Text numberOfLines={1} style={editorShellStyles.automationMeta}>
              {automation.function_name}
            </Text>
          ) : null}
          <View style={editorShellStyles.automationCreditBadge}>
            <Coins color={themedColor('#A1A1AA')} size={11} strokeWidth={2.4} />
            <Text numberOfLines={1} style={editorShellStyles.automationCreditText}>
              {credits ? `${formatCredits(credits.total)} credits used` : 'Consumes credits'}
            </Text>
          </View>
        </View>
        <Text numberOfLines={1} style={editorShellStyles.automationRuns}>
          {formatRuns(automation)}
          {lastRun ? ` · Last run ${lastRun}` : ''}
        </Text>
        <View style={editorShellStyles.automationActionRow}>
          <AutomationActionButton
            icon={expanded ? X : ChevronDown}
            label={expanded ? 'Close' : 'Details'}
            onPress={() => setExpanded((current) => !current)}
          />
          {onEditAutomation ? (
            <AutomationActionButton
              icon={Edit3}
              isLoading={pendingAction === 'edit'}
              label="Edit"
              onPress={() => runAction('edit', onEditAutomation)}
            />
          ) : null}
          {canRunNow ? (
            <AutomationActionButton
              icon={Play}
              isLoading={pendingAction === 'run'}
              label="Run"
              onPress={() => runAction('run', onRunAutomationNow)}
            />
          ) : null}
          {!isArchived && onToggleAutomation ? (
            <AutomationActionButton
              icon={isActive ? ToggleRight : ToggleLeft}
              isLoading={pendingAction === 'toggle'}
              label={isActive ? 'Pause' : 'Activate'}
              onPress={() => runAction('toggle', onToggleAutomation)}
            />
          ) : null}
          {!isArchived && onArchiveAutomation ? (
            <AutomationActionButton
              icon={Archive}
              isLoading={pendingAction === 'archive'}
              label="Archive"
              onPress={() => runAction('archive', onArchiveAutomation)}
            />
          ) : null}
          {isArchived && onRestoreAutomation ? (
            <AutomationActionButton
              icon={RotateCcw}
              isLoading={pendingAction === 'restore'}
              label="Restore"
              onPress={() => runAction('restore', onRestoreAutomation)}
            />
          ) : null}
          {onDeleteAutomation ? (
            <AutomationActionButton
              danger
              icon={Trash2}
              isLoading={pendingAction === 'delete'}
              label="Delete"
              onPress={() => runAction('delete', onDeleteAutomation)}
            />
          ) : null}
        </View>
        {expanded ? (
          <View style={editorShellStyles.automationDetailsPanel}>
            {trigger ? (
              <AutomationDetailBlock label="Trigger" value={trigger} />
            ) : null}
            {automation.description ? (
              <AutomationDetailBlock label="Instructions" value={automation.description} />
            ) : null}
            {automation.function_name ? (
              <AutomationDetailBlock label="Task ID" monospace value={automation.function_name} />
            ) : null}
            {automation.function_args && Object.keys(automation.function_args).length > 0 ? (
              <AutomationDetailBlock label="Parameters" monospace value={JSON.stringify(automation.function_args, null, 2)} />
            ) : null}
            <View style={editorShellStyles.automationDetailStats}>
              <Text style={editorShellStyles.automationDetailStatText}>{automation.total_runs ?? 0} total</Text>
              <Text style={editorShellStyles.automationDetailSuccess}>{automation.successful_runs ?? 0} succeeded</Text>
              <Text style={editorShellStyles.automationDetailFailure}>{automation.failed_runs ?? 0} failed</Text>
            </View>
            {credits ? (
              <Text style={editorShellStyles.automationDetailMuted}>
                Total credits: {formatCredits(credits.total)}
                {credits.since ? ` · since ${formatDate(credits.since) ?? credits.since}` : ''}
              </Text>
            ) : null}
            {lastRun ? (
              <Text style={editorShellStyles.automationDetailMuted}>
                Last run: {lastRun}
                {automation.last_run_status ? ` · ${automation.last_run_status}` : ''}
              </Text>
            ) : null}
            {automation.created_date ? (
              <Text style={editorShellStyles.automationDetailMuted}>
                Created {formatDate(automation.created_date) ?? automation.created_date}
              </Text>
            ) : null}
          </View>
        ) : null}
      </View>
    </View>
  );
}

function AutomationActionButton({
  danger,
  icon: Icon,
  isLoading,
  label,
  onPress,
}: {
  danger?: boolean;
  icon: LucideIcon;
  isLoading?: boolean;
  label: string;
  onPress: () => void;
}) {
  return (
    <Pressable
      accessibilityLabel={label}
      accessibilityRole="button"
      disabled={isLoading}
      onPress={onPress}
      style={({ pressed }) => [
        editorShellStyles.automationActionButton,
        danger && editorShellStyles.automationActionButtonDanger,
        pressed && styles.pressed,
        isLoading && editorShellStyles.automationActionButtonDisabled,
      ]}
    >
      {isLoading ? (
        <ActivityIndicator color={danger ? themedColor('#FCA5A5') : themedColor('#F4F4F5')} size="small" />
      ) : (
        <Icon color={danger ? themedColor('#FCA5A5') : themedColor('#F4F4F5')} size={13} strokeWidth={2.45} />
      )}
      <Text style={[
        editorShellStyles.automationActionText,
        danger && editorShellStyles.automationActionTextDanger,
      ]}>{label}</Text>
    </Pressable>
  );
}

function AutomationDetailBlock({
  label,
  monospace,
  value,
}: {
  label: string;
  monospace?: boolean;
  value: string;
}) {
  return (
    <View style={editorShellStyles.automationDetailBlock}>
      <Text style={editorShellStyles.automationDetailLabel}>{label}</Text>
      <Text style={[
        editorShellStyles.automationDetailValue,
        monospace && editorShellStyles.automationDetailValueMono,
      ]}>{value}</Text>
    </View>
  );
}

function AutomationStatusBadge({ automation }: { automation: SuperagentAutomation }) {
  const isArchived = !!automation.is_archived;
  const isActive = !isArchived && automation.is_active !== false;
  const label = isArchived ? 'Archived' : isActive ? 'Active' : 'Paused';

  return (
    <View style={[
      editorShellStyles.automationStatusBadge,
      isActive ? editorShellStyles.automationStatusActive : editorShellStyles.automationStatusInactive,
    ]}>
      <Text style={[
        editorShellStyles.automationStatusText,
        isActive ? editorShellStyles.automationStatusTextActive : editorShellStyles.automationStatusTextInactive,
      ]}>{label}</Text>
    </View>
  );
}

const WORKFLOW_TRIGGER_ICONS: Record<string, LucideIcon> = {
  scheduled: Timer,
  connector: Webhook,
  entity: Zap,
  in_app_agent: GitBranch,
  app_user_auth: GitBranch,
};

function WorkflowsPanel({ agent }: { agent: SuperagentAgent }) {
  const {
    workflows = [],
    workflowLoadError,
    isLoadingWorkflows: isLoading,
    onArchiveWorkflow,
    onRestoreWorkflow,
    onRefreshWorkflows,
    onRunWorkflowNow,
    onToggleWorkflow,
  } = useSuperagentWorkflows();
  const bi = useAgentBi();
  const [viewTab, setViewTab] = useState<'active' | 'archived'>('active');
  const switchView = (view: 'active' | 'archived') => {
    if (view === viewTab) return; // no-op re-tap of the active tab
    void bi.trackEditor('Workflows View Switch', { view });
    setViewTab(view);
  };
  // Sort once and partition in the same pass; both partitions feed the tab
  // badges, so neither can be skipped. Recompute only when the list changes,
  // not on every Active/Archived tab toggle.
  const { activeWorkflows, archivedWorkflows } = useMemo(() => {
    const sorted = sortWorkflows(workflows);
    return {
      activeWorkflows: sorted.filter((workflow) => !isWorkflowArchived(workflow)),
      archivedWorkflows: sorted.filter((workflow) => isWorkflowArchived(workflow)),
    };
  }, [workflows]);

  if (isLoading && workflows.length === 0) {
    return (
      <View style={editorShellStyles.loadingPanel}>
        <ActivityIndicator color={themedColor('#FF5A1F')} />
        <Text style={editorShellStyles.loadingText}>Loading tasks...</Text>
      </View>
    );
  }

  const displayWorkflows = viewTab === 'archived' ? archivedWorkflows : activeWorkflows;

  return (
    <View style={editorShellStyles.settingsStack}>
      <View style={editorShellStyles.panel}>
        <View style={editorShellStyles.panelHeader}>
          <View>
            <Text style={editorShellStyles.panelTitle}>Tasks</Text>
          </View>
          <Text style={editorShellStyles.countBadge}>{displayWorkflows.length}</Text>
        </View>

        {workflowLoadError ? (
          <View style={editorShellStyles.automationErrorBanner}>
            <AlertCircle color={themedColor('#FCA5A5')} size={18} strokeWidth={2.3} />
            <Text style={editorShellStyles.automationErrorText}>Couldn’t load tasks.</Text>
            <Pressable
              accessibilityLabel="Retry loading tasks"
              accessibilityRole="button"
              onPress={() => void onRefreshWorkflows?.(agent.id)}
              style={({ pressed }) => [
                editorShellStyles.automationRetryButton,
                pressed && styles.pressed,
              ]}
            >
              <RotateCcw color={themedColor('#F4F4F5')} size={14} strokeWidth={2.4} />
              <Text style={editorShellStyles.automationRetryText}>Retry</Text>
            </Pressable>
          </View>
        ) : null}

        <View style={editorShellStyles.automationTabs}>
          <Pressable
            accessibilityRole="button"
            onPress={() => switchView('active')}
            style={({ pressed }) => [
              editorShellStyles.automationTabButton,
              viewTab === 'active' && editorShellStyles.automationTabButtonActive,
              pressed && styles.pressed,
            ]}
          >
            <Text style={[
              editorShellStyles.automationTabText,
              viewTab === 'active' && editorShellStyles.automationTabTextActive,
            ]}>Active {activeWorkflows.length}</Text>
          </Pressable>
          <Pressable
            accessibilityRole="button"
            onPress={() => switchView('archived')}
            style={({ pressed }) => [
              editorShellStyles.automationTabButton,
              viewTab === 'archived' && editorShellStyles.automationTabButtonActive,
              pressed && styles.pressed,
            ]}
          >
            <Text style={[
              editorShellStyles.automationTabText,
              viewTab === 'archived' && editorShellStyles.automationTabTextActive,
            ]}>Archived {archivedWorkflows.length}</Text>
          </Pressable>
        </View>

        {displayWorkflows.length > 0 ? (
          <View style={editorShellStyles.automationList}>
            {displayWorkflows.map((workflow) => (
              <WorkflowCard
                agentId={agent.id}
                key={workflow.id}
                onArchiveWorkflow={onArchiveWorkflow}
                onRestoreWorkflow={onRestoreWorkflow}
                onRunWorkflowNow={onRunWorkflowNow}
                onToggleWorkflow={onToggleWorkflow}
                workflow={workflow}
              />
            ))}
          </View>
        ) : workflowLoadError ? null : (
          <View style={editorShellStyles.emptyPanel}>
            {viewTab === 'archived' ? (
              <Archive color={themedColor('#8E8E93')} size={22} strokeWidth={2.2} />
            ) : (
              <Timer color={themedColor('#8E8E93')} size={22} strokeWidth={2.2} />
            )}
            <Text style={editorShellStyles.emptyTitle}>
              {viewTab === 'archived' ? 'No archived tasks' : 'No tasks yet'}
            </Text>
            <Text style={editorShellStyles.emptyBody}>
              {viewTab === 'archived'
                ? 'Tasks you archive will appear here.'
                : 'Ask Superagent to create a scheduled or triggered task.'}
            </Text>
          </View>
        )}
      </View>
    </View>
  );
}

type WorkflowPendingAction = 'archive' | 'restore' | 'run' | 'toggle';

function WorkflowCard({
  agentId,
  onArchiveWorkflow,
  onRestoreWorkflow,
  onRunWorkflowNow,
  onToggleWorkflow,
  workflow,
}: {
  agentId: string;
  onArchiveWorkflow?: (input: SuperagentWorkflowActionInput) => Promise<void> | void;
  onRestoreWorkflow?: (input: SuperagentWorkflowActionInput) => Promise<void> | void;
  onRunWorkflowNow?: (input: SuperagentWorkflowActionInput) => Promise<void> | void;
  onToggleWorkflow?: (input: SuperagentWorkflowActionInput) => Promise<void> | void;
  workflow: SuperagentWorkflow;
}) {
  const [expanded, setExpanded] = useState(false);
  const [pendingAction, setPendingAction] = useState<WorkflowPendingAction | null>(null);
  const Icon = WORKFLOW_TRIGGER_ICONS[workflow.trigger?.config?.trigger_type ?? ''] ?? Timer;
  const trigger = describeWorkflowTrigger(workflow);
  const lastRun = formatDateTime(workflow.last_run_at);
  const archived = isWorkflowArchived(workflow);
  const active = isWorkflowActive(workflow);
  const deactivatedByFailures = isDeactivatedByFailures(workflow);
  const actionInput = { agentId, workflow };

  const runAction = async (
    action: WorkflowPendingAction,
    handler?: (input: SuperagentWorkflowActionInput) => Promise<void> | void,
  ) => {
    if (!handler || pendingAction) {
      return;
    }

    setPendingAction(action);
    try {
      await handler(actionInput);
    } finally {
      setPendingAction(null);
    }
  };

  return (
    <View style={editorShellStyles.automationCard}>
      <View style={editorShellStyles.automationIcon}>
        <Icon color={themedColor('#F4F4F5')} size={19} strokeWidth={2.35} />
      </View>
      <View style={editorShellStyles.automationText}>
        <View style={editorShellStyles.inlineTitleRow}>
          <Text numberOfLines={1} style={editorShellStyles.automationName}>{workflow.name}</Text>
          <WorkflowStatusBadge workflow={workflow} />
        </View>
        {trigger ? (
          <Text numberOfLines={2} style={editorShellStyles.automationTrigger}>{trigger}</Text>
        ) : null}
        {workflow.description ? (
          <Text numberOfLines={2} style={editorShellStyles.automationDescription}>{workflow.description}</Text>
        ) : null}
        {deactivatedByFailures ? (
          <Text numberOfLines={2} style={editorShellStyles.automationDetailFailure}>
            Paused after repeated failures
          </Text>
        ) : null}
        <Text numberOfLines={1} style={editorShellStyles.automationRuns}>
          {formatWorkflowRuns(workflow)}
          {lastRun ? ` · Last run ${lastRun}` : ''}
          {workflow.last_run_status ? ` · ${workflow.last_run_status}` : ''}
        </Text>
        <View style={editorShellStyles.automationActionRow}>
          <AutomationActionButton
            icon={expanded ? X : ChevronDown}
            label={expanded ? 'Close' : 'Details'}
            onPress={() => setExpanded((current) => !current)}
          />
          {!archived && onRunWorkflowNow ? (
            <AutomationActionButton
              icon={Play}
              isLoading={pendingAction === 'run'}
              label="Run"
              onPress={() => runAction('run', onRunWorkflowNow)}
            />
          ) : null}
          {!archived && onToggleWorkflow ? (
            <AutomationActionButton
              icon={active ? ToggleRight : ToggleLeft}
              isLoading={pendingAction === 'toggle'}
              label={active ? 'Pause' : 'Activate'}
              onPress={() => runAction('toggle', onToggleWorkflow)}
            />
          ) : null}
          {!archived && onArchiveWorkflow ? (
            <AutomationActionButton
              icon={Archive}
              isLoading={pendingAction === 'archive'}
              label="Archive"
              onPress={() => runAction('archive', onArchiveWorkflow)}
            />
          ) : null}
          {archived && onRestoreWorkflow ? (
            <AutomationActionButton
              icon={RotateCcw}
              isLoading={pendingAction === 'restore'}
              label="Restore"
              onPress={() => runAction('restore', onRestoreWorkflow)}
            />
          ) : null}
        </View>
        {expanded ? (
          <View style={editorShellStyles.automationDetailsPanel}>
            {trigger ? (
              <AutomationDetailBlock label="Trigger" value={trigger} />
            ) : null}
            {workflow.description ? (
              <AutomationDetailBlock label="Instructions" value={workflow.description} />
            ) : null}
            <Text style={editorShellStyles.automationDetailMuted}>
              {formatWorkflowRuns(workflow)}
            </Text>
            {lastRun ? (
              <Text style={editorShellStyles.automationDetailMuted}>
                Last run: {lastRun}
                {workflow.last_run_status ? ` · ${workflow.last_run_status}` : ''}
              </Text>
            ) : null}
            {workflow.created_date ? (
              <Text style={editorShellStyles.automationDetailMuted}>
                Created {formatDate(workflow.created_date) ?? workflow.created_date}
              </Text>
            ) : null}
          </View>
        ) : null}
      </View>
    </View>
  );
}

function WorkflowStatusBadge({ workflow }: { workflow: SuperagentWorkflow }) {
  const active = isWorkflowActive(workflow);
  const label = formatWorkflowStatus(workflow);

  return (
    <View style={[
      editorShellStyles.automationStatusBadge,
      active ? editorShellStyles.automationStatusActive : editorShellStyles.automationStatusInactive,
    ]}>
      <Text style={[
        editorShellStyles.automationStatusText,
        active ? editorShellStyles.automationStatusTextActive : editorShellStyles.automationStatusTextInactive,
      ]}>{label}</Text>
    </View>
  );
}

const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

function describeAutomationTrigger(automation: SuperagentAutomation) {
  if (automation.automation_type === 'scheduled') {
    return describeSchedule(automation);
  }

  if (automation.automation_type === 'entity') {
    const events = automation.event_types?.length ? automation.event_types.join(', ') : 'changes';
    return automation.entity_name ? `${automation.entity_name} · ${events}` : events;
  }

  if (automation.automation_type === 'connector') {
    const connectorName = getConnectorDisplayName(automation.integration_type);
    const events = automation.events?.length ? automation.events.join(', ') : '';
    return events ? `${connectorName} · ${events}` : connectorName;
  }

  return null;
}

function describeSchedule(automation: SuperagentAutomation) {
  if (automation.schedule_mode === 'one-time' && automation.one_time_date) {
    return `One-time · ${formatDateTime(automation.one_time_date) ?? automation.one_time_date}`;
  }

  if (automation.schedule_type === 'cron' && automation.cron_expression) {
    return `Cron · ${automation.cron_expression}`;
  }

  const parts: string[] = [];
  if (automation.repeat_interval && automation.repeat_unit) {
    const unit = automation.repeat_interval === 1
      ? automation.repeat_unit.replace(/s$/, '')
      : automation.repeat_unit;
    parts.push(`Every ${automation.repeat_interval === 1 ? '' : `${automation.repeat_interval} `}${unit}`.trim());
  }
  if (automation.repeat_unit === 'weeks' && automation.repeat_on_days?.length) {
    parts.push(`on ${automation.repeat_on_days.map((day) => DAY_NAMES[day]).filter(Boolean).join(', ')}`);
  }
  if (automation.repeat_unit === 'months' && automation.repeat_on_day_of_month) {
    parts.push(`on day ${automation.repeat_on_day_of_month}`);
  }
  if (automation.start_time) {
    parts.push(`at ${automation.start_time}`);
  }
  if (automation.ends_type === 'on' && automation.ends_on_date) {
    parts.push(`until ${formatDate(automation.ends_on_date) ?? automation.ends_on_date}`);
  } else if (automation.ends_type === 'after' && automation.ends_after_count) {
    parts.push(`for ${automation.ends_after_count} runs`);
  }

  return parts.length > 0 ? parts.join(' ') : null;
}

function formatAutomationType(type: SuperagentAutomation['automation_type']) {
  if (type === 'scheduled') {
    return 'Scheduled';
  }
  if (type === 'entity') {
    return 'Entity trigger';
  }
  if (type === 'connector') {
    return 'Connector trigger';
  }
  return String(type);
}

function formatRuns(automation: SuperagentAutomation) {
  const total = automation.total_runs ?? 0;
  const successful = automation.successful_runs ?? 0;
  const failed = automation.failed_runs ?? 0;
  return `${total} runs · ${successful} succeeded · ${failed} failed`;
}

function formatCredits(value: number) {
  return Number.isInteger(value) ? String(value) : value.toFixed(1).replace(/\.0$/, '');
}

function getAutomationTime(automation: SuperagentAutomation) {
  const dateValue = automation.updated_date ?? automation.created_date ?? automation.last_run_at;
  if (!dateValue) {
    return 0;
  }

  const timestamp = Date.parse(dateValue);
  return Number.isNaN(timestamp) ? 0 : timestamp;
}

function getConnectorDisplayName(connectorId?: string) {
  if (!connectorId) {
    return 'Connector';
  }

  return SUPERAGENT_CONNECTOR_CATALOG.find((connector) => connector.id === connectorId)?.name
    ?? connectorId
      .split(/[_-]/)
      .filter(Boolean)
      .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
      .join(' ');
}

function formatDate(value?: string | null) {
  if (!value) {
    return null;
  }

  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return value;
  }

  return date.toLocaleDateString();
}

function formatDateTime(value?: string | null) {
  if (!value) {
    return null;
  }

  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return value;
  }

  return date.toLocaleString();
}

function PlaceholderSettingsPanel({ tab }: { tab: SuperagentEditorTab }) {
  const label = getEditorTabLabel(tab);
  const iconMap: Partial<Record<SuperagentEditorTab, LucideIcon>> = {
    files: FileText,
    automations: Settings,
  };
  const Icon = iconMap[tab] ?? Settings;

  return (
    <View style={editorShellStyles.placeholderPanel}>
      <View style={editorShellStyles.placeholderIcon}>
        <Icon color={themedColor('#FF5A1F')} size={24} strokeWidth={2.3} />
      </View>
      <Text style={editorShellStyles.placeholderTitle}>{label}</Text>
      <Text style={editorShellStyles.placeholderBody}>
        This section now lives in the settings modal. The next slice can replace this placeholder with the matching native controls.
      </Text>
    </View>
  );
}
