import React, { useEffect, useMemo, useState } from 'react';
import { createThemedStyles, themedColor, themedSurface } from '../../theme';
import {
  ActivityIndicator,
  Pressable,
  Switch,
  Text,
  TextInput,
  View,
} from 'react-native';
import {
  Check,
  ChevronDown,
  Eye,
  EyeOff,
  Plus,
  Trash2,
} from 'lucide-react-native';

import { ConnectorBrandIcon, hasConnectorBrandIcon } from '../connectors/connectorBrandIcons';
import { editorShellStyles } from '../editor/editorShellStyles';
import { useAgentBi } from '../../analytics/mixpanelContext';
import { ModelPickerModal, useModelPicker } from './modelPicker';
import { getSelectableModelOptions, resolveModelOption, type ModelOption } from './modelOptions';
import {
  useSuperagentAgents,
  useSuperagentConnectors,
  useSuperagentModelActions,
  useSuperagentSecrets,
  useSuperagentShellOptions,
} from '../../runtime/runtimeContext';
import { styles as sharedStyles } from '../../styles';
import { useFeatureFlags, useSuperagentModelAccess } from '../../user/userContext';
import type {
  SuperagentAgent,
  SuperagentModelChoice,
  SuperagentSecret,
  SuperagentToolPermissionConfig,
} from '../../types';

const TOOL_OPERATIONS = [
  {
    body: 'Allow the agent to update app data without asking every time.',
    id: 'update_entities',
    title: 'Update data',
  },
  {
    body: 'Allow the agent to delete app data without asking every time.',
    id: 'delete_entities',
    title: 'Delete data',
  },
];

type PendingAction =
  | 'delete-agent'
  | 'delete-secret'
  | 'rename'
  | 'save-guards'
  | 'save-secret'
  | null;

export function AgentSettingsPanel({
  agent,
  section = 'general',
}: {
  agent: SuperagentAgent;
  // Which group of controls this modal shows. General = name/model/delete;
  // security = tool permissions/connector guards/secrets (its own menu item).
  section?: 'general' | 'security';
}) {
  const { secrets = [], isLoadingAgentSettings: isLoading, onSaveSecret, onDeleteSecret } =
    useSuperagentSecrets();
  const { onUpdateAgentModel, onUpdateAgentAutomationModel, onUpdateToolPermissions } = useSuperagentModelActions();
  const { onDeleteAgent, onRenameAgent } = useSuperagentAgents();
  const { connectedConnectors = [] } = useSuperagentConnectors();
  const bi = useAgentBi();
  const { onViewPlans } = useSuperagentShellOptions();
  const [nameDraft, setNameDraft] = useState(agent.name ?? '');
  const [guardDrafts, setGuardDrafts] = useState<Record<string, string>>({});
  const [newSecretName, setNewSecretName] = useState('');
  const [newSecretValue, setNewSecretValue] = useState('');
  const [pendingAction, setPendingAction] = useState<PendingAction>(null);
  const [deletingSecretName, setDeletingSecretName] = useState<string | null>(null);
  const [visibleSecrets, setVisibleSecrets] = useState<Set<string>>(new Set());
  const [nameError, setNameError] = useState<string | null>(null);

  const permissions = useMemo(
    () => normalizePermissions(agent.toolsPermissionConfig),
    [agent.toolsPermissionConfig],
  );
  // Optimistic override for the permission toggles: flipped immediately on
  // press, cleared when fresh server state arrives, reverted on failure.
  const [optimisticOps, setOptimisticOps] = useState<string[] | null>(null);
  const autoApprovedOps = optimisticOps ?? permissions.auto_approved_operations;
  const { getFlagVariant, hasFlag } = useFeatureFlags();
  const { canSelectBestModel } = useSuperagentModelAccess();
  const modelOptions = useMemo(
    () => getSelectableModelOptions(hasFlag, getFlagVariant),
    [hasFlag, getFlagVariant],
  );
  const activeConnectorIds = useMemo(
    () => connectedConnectors
      .filter((connector) => connector.status !== 'expired' && connector.status !== 'disconnected')
      .map((connector) => connector.id),
    [connectedConnectors],
  );
  const guardDraftsDirty = useMemo(
    () => JSON.stringify(cleanGuards(guardDrafts)) !== JSON.stringify(permissions.connector_guards),
    [guardDrafts, permissions.connector_guards],
  );

  useEffect(() => {
    // Seed guard drafts only when switching agents — not on every
    // toolsPermissionConfig change — so in-progress guard edits aren't wiped by
    // an unrelated permission toggle before "Save rules" is pressed.
    setGuardDrafts(permissions.connector_guards);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [agent.id]);

  useEffect(() => {
    // Fresh server state (or an agent switch) supersedes the optimistic flip.
    setOptimisticOps(null);
  }, [agent.id, agent.toolsPermissionConfig]);

  useEffect(() => {
    // Re-seed when the agent switches OR its name changes upstream (e.g. a rename
    // from the header modal), so General can't keep a stale draft and re-save the
    // old name. A local in-progress edit doesn't change agent.name, so typing is
    // preserved until an actual upstream change arrives.
    setNameDraft(agent.name ?? '');
    setNameError(null);
  }, [agent.id, agent.name]);

  const trimmedName = nameDraft.trim();
  const nameDirty = trimmedName.length > 0 && trimmedName !== (agent.name ?? '');
  const saveName = async () => {
    // Bail while any other action is in flight: runAction no-ops when
    // pendingAction is set, which would otherwise clear nameError and look like
    // a successful save while the rename never ran.
    if (!onRenameAgent || !nameDirty || pendingAction) {
      return;
    }

    // The host's rename handler rethrows on failure without surfacing it, so
    // show the error inline here (the panel has no other feedback) and keep the
    // draft for retry.
    setNameError(null);
    try {
      await runAction('rename', async () => {
        await onRenameAgent({ agentId: agent.id, name: trimmedName });
      });
    } catch (error) {
      setNameError(error instanceof Error && error.message ? error.message : 'Could not rename the agent. Please try again.');
    }
  };

  const runAction = async (action: Exclude<PendingAction, null>, handler: () => Promise<void> | void) => {
    if (pendingAction) {
      return;
    }

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

  const updatePermissions = async (
    nextConfig: SuperagentToolPermissionConfig,
    action: Exclude<PendingAction, null>,
  ) => {
    if (!onUpdateToolPermissions) {
      return;
    }

    try {
      await runAction(action, async () => {
        await onUpdateToolPermissions({
          agentId: agent.id,
          config: {
            auto_approved_operations: nextConfig.auto_approved_operations ?? [],
            connector_guards: cleanGuards(nextConfig.connector_guards ?? {}),
          },
        });
        // Inside the runAction handler: only fires when it actually ran (no
        // pending-action no-op) and the update resolved (rethrows on failure).
        void bi.trackEditor('Connector Rules Save');
      });
    } catch {
      // onUpdateToolPermissions already surfaced the error; guard drafts stay
      // dirty so the user can retry. (Nothing optimistic to revert on this path.)
    }
  };

  const toggleOperation = (operationId: string, enabled: boolean) => {
    if (!onUpdateToolPermissions) {
      return;
    }

    void bi.trackEditor('Tool Permission Toggle', { tool: operationId, enabled });
    const nextOps = new Set(autoApprovedOps);
    if (enabled) {
      nextOps.add(operationId);
    } else {
      nextOps.delete(operationId);
    }
    const nextList = Array.from(nextOps);

    // Optimistic: flip the switch now, sync with the server in the background,
    // and fall back to the last known server state if the update fails.
    setOptimisticOps(nextList);
    Promise.resolve(onUpdateToolPermissions({
      agentId: agent.id,
      config: {
        auto_approved_operations: nextList,
        connector_guards: cleanGuards(permissions.connector_guards),
      },
    })).catch(() => {
      // Revert only this operation, not every optimistic flip: a sibling toggle
      // the user changed in parallel may have already saved successfully, and
      // clearing all optimistic state would visually undo it until a refresh.
      setOptimisticOps((current) => {
        const reverted = new Set(current ?? permissions.auto_approved_operations);
        if (enabled) {
          reverted.delete(operationId);
        } else {
          reverted.add(operationId);
        }
        return Array.from(reverted);
      });
    });
  };

  const addSecret = async () => {
    const name = newSecretName.trim().toUpperCase();
    // Preserve the secret value byte-for-byte — PEM keys, tokens with a trailing
    // newline, and whitespace-sensitive passwords must reach the backend exactly as
    // typed (the API client sends it raw). Only require it to be non-empty.
    const value = newSecretValue;
    if (!name || !value.trim() || !onSaveSecret) {
      return;
    }

    // Only clear the inputs after a successful save; if onSaveSecret rejects it
    // already surfaced the error, and we keep the typed values so they aren't lost.
    try {
      await runAction('save-secret', async () => {
        await onSaveSecret({ agentId: agent.id, name, value });
        setNewSecretName('');
        setNewSecretValue('');
        void bi.trackEditor('Secret Add');
      });
    } catch {
      // onSaveSecret already surfaced the error; keep the form populated.
    }
  };

  const deleteSecret = async (secret: SuperagentSecret) => {
    if (!onDeleteSecret) {
      return;
    }

    setDeletingSecretName(secret.name);
    try {
      // `Secret Delete` is tracked in the runtime's onDeleteSecret success branch —
      // here it would also fire on the confirm-cancel / API-failure paths, which
      // onDeleteSecret swallows without throwing.
      await runAction('delete-secret', () => onDeleteSecret({ agentId: agent.id, name: secret.name }));
    } finally {
      setDeletingSecretName(null);
    }
  };

  return (
    <View style={editorShellStyles.settingsStack}>
      {section === 'general' ? (
      <SettingsSection
        title="Agent identity"
      >
        <Text style={localStyles.fieldLabel}>Name</Text>
        <TextInput
          editable={!!onRenameAgent && pendingAction !== 'rename'}
          onChangeText={(value) => {
            setNameDraft(value);
            if (nameError) {
              setNameError(null);
            }
          }}
          placeholder="Agent name"
          placeholderTextColor={themedColor('#71717A')}
          style={localStyles.textInput}
          value={nameDraft}
        />
        {nameError ? <Text style={localStyles.errorText}>{nameError}</Text> : null}
        {onRenameAgent ? (
          <Pressable
            accessibilityLabel="Save agent name"
            accessibilityRole="button"
            disabled={pendingAction !== null || !nameDirty}
            onPress={saveName}
            style={({ pressed }) => [
              localStyles.secondaryButton,
              (pendingAction !== null || !nameDirty) && localStyles.disabledButton,
              pressed && sharedStyles.pressed,
            ]}
          >
            {pendingAction === 'rename' ? (
              <ActivityIndicator color={themedColor('#F4F4F5')} size="small" />
            ) : (
              <Check color={themedColor('#F4F4F5')} size={16} strokeWidth={2.6} />
            )}
            <Text style={localStyles.secondaryButtonText}>Save name</Text>
          </Pressable>
        ) : null}
      </SettingsSection>
      ) : null}

      {section === 'general' ? (
      <SettingsSection
        title="AI Model"
      >
        <Text style={localStyles.fieldLabel}>Chat model</Text>
        <ModelField
          agentId={agent.id}
          canSelectBestModel={canSelectBestModel}
          modelOptions={modelOptions}
          onSelect={onUpdateAgentModel}
          onViewPlans={onViewPlans}
          selected={resolveModelOption(agent.model)}
        />
        <Text style={[localStyles.fieldLabel, localStyles.fieldLabelSpaced]}>Automation model</Text>
        <ModelField
          agentId={agent.id}
          canSelectBestModel={canSelectBestModel}
          modelOptions={modelOptions}
          onSelect={onUpdateAgentAutomationModel}
          onViewPlans={onViewPlans}
          selected={resolveModelOption(agent.automationModel)}
        />
      </SettingsSection>
      ) : null}

      {section === 'security' ? (
      <SettingsSection
        isLoading={isLoading}
        title="Secrets"
      >
        {secrets.length > 0 ? (
          <View style={localStyles.secretList}>
            {secrets.map((secret) => {
              const isVisible = visibleSecrets.has(secret.name);
              return (
                <View key={secret.name} style={localStyles.secretRow}>
                  <View style={localStyles.secretText}>
                    <Text numberOfLines={1} style={localStyles.secretName}>{secret.name}</Text>
                    <Text numberOfLines={1} style={localStyles.secretValue}>
                      {isVisible ? secret.value : '••••••••••••'}
                    </Text>
                  </View>
                  <Pressable
                    accessibilityLabel={isVisible ? 'Hide secret' : 'Show secret'}
                    accessibilityRole="button"
                    onPress={() => setVisibleSecrets((current) => toggleSecretVisibility(current, secret.name))}
                    style={({ pressed }) => [localStyles.iconButton, pressed && sharedStyles.pressed]}
                  >
                    {isVisible ? (
                      <EyeOff color={themedColor('#E4E4E7')} size={16} strokeWidth={2.4} />
                    ) : (
                      <Eye color={themedColor('#E4E4E7')} size={16} strokeWidth={2.4} />
                    )}
                  </Pressable>
                  <Pressable
                    accessibilityLabel={`Delete ${secret.name}`}
                    accessibilityRole="button"
                    disabled={!onDeleteSecret || pendingAction === 'delete-secret'}
                    onPress={() => deleteSecret(secret)}
                    style={({ pressed }) => [localStyles.iconButtonDanger, pressed && sharedStyles.pressed]}
                  >
                    {deletingSecretName === secret.name ? (
                      <ActivityIndicator color={themedColor('#FCA5A5')} size="small" />
                    ) : (
                      <Trash2 color={themedColor('#FCA5A5')} size={16} strokeWidth={2.4} />
                    )}
                  </Pressable>
                </View>
              );
            })}
          </View>
        ) : (
          <Text style={localStyles.mutedText}>No secrets yet.</Text>
        )}

        <View style={localStyles.addSecretBox}>
          <TextInput
            autoCapitalize="characters"
            onChangeText={(value) => setNewSecretName(value.toUpperCase())}
            placeholder="SECRET_NAME"
            placeholderTextColor={themedColor('#71717A')}
            style={localStyles.textInput}
            value={newSecretName}
          />
          <TextInput
            onChangeText={setNewSecretValue}
            placeholder="Value"
            placeholderTextColor={themedColor('#71717A')}
            secureTextEntry
            style={localStyles.textInput}
            value={newSecretValue}
          />
          <Pressable
            accessibilityLabel="Add secret"
            accessibilityRole="button"
            disabled={!onSaveSecret || pendingAction === 'save-secret' || !newSecretName.trim() || !newSecretValue.trim()}
            onPress={addSecret}
            style={({ pressed }) => [
              localStyles.primaryButton,
              (!onSaveSecret || !newSecretName.trim() || !newSecretValue.trim()) && localStyles.disabledButton,
              pressed && sharedStyles.pressed,
            ]}
          >
            {pendingAction === 'save-secret' ? (
              <ActivityIndicator color={themedColor('#111111')} size="small" />
            ) : (
              <Plus color={themedColor('#111111')} size={16} strokeWidth={2.6} />
            )}
            <Text style={localStyles.primaryButtonText}>Add</Text>
          </Pressable>
        </View>
      </SettingsSection>
      ) : null}

      {section === 'security' ? (
      <SettingsSection
        title="Tool Permissions"
      >
        {TOOL_OPERATIONS.map((operation) => {
          const isEnabled = autoApprovedOps.includes(operation.id);
          return (
            <View key={operation.id} style={localStyles.permissionRow}>
              <View style={localStyles.permissionText}>
                <Text style={localStyles.rowTitle}>{operation.title}</Text>
                <Text style={localStyles.rowBody}>{operation.body}</Text>
              </View>
              <Switch
                disabled={!onUpdateToolPermissions}
                ios_backgroundColor={themedSurface('#2A2A2A')}
                onValueChange={(enabled) => toggleOperation(operation.id, enabled)}
                thumbColor="#F4F4F5"
                trackColor={{ false: themedSurface('#2A2A2A'), true: '#246B43' }}
                value={isEnabled}
              />
            </View>
          );
        })}
      </SettingsSection>
      ) : null}

      {section === 'security' ? (
      <SettingsSection
        title="Connector Guards"
      >
        {activeConnectorIds.length > 0 ? (
          activeConnectorIds.map((connectorId) => {
            const connector = connectedConnectors.find((item) => item.id === connectorId);
            return (
              <View key={connectorId} style={localStyles.connectorGuard}>
                <View style={localStyles.connectorHeader}>
                  <View style={localStyles.connectorIcon}>
                    {hasConnectorBrandIcon(connectorId) ? (
                      <ConnectorBrandIcon connectorId={connectorId} size={22} />
                    ) : (
                      <Text style={localStyles.connectorFallback}>{connector?.iconFallbackLabel ?? connectorId.slice(0, 2).toUpperCase()}</Text>
                    )}
                  </View>
                  <View style={localStyles.connectorTitleWrap}>
                    <Text style={localStyles.rowTitle}>{connector?.name ?? connectorId}</Text>
                    <Text numberOfLines={1} style={localStyles.rowBody}>
                      {connector?.accountIdentifier || 'Connected'}
                    </Text>
                  </View>
                </View>
                <TextInput
                  multiline
                  onChangeText={(value) => {
                    setGuardDrafts((current) => ({
                      ...current,
                      [connectorId]: value.slice(0, 500),
                    }));
                  }}
                  placeholder="Example: ask before sending email outside my domain."
                  placeholderTextColor={themedColor('#71717A')}
                  style={[localStyles.textInput, localStyles.guardInput]}
                  value={guardDrafts[connectorId] ?? ''}
                />
              </View>
            );
          })
        ) : (
          <Text style={localStyles.mutedText}>Connect a tool to add connector-specific rules.</Text>
        )}
        {activeConnectorIds.length > 0 ? (
          <Pressable
            accessibilityLabel="Save connector guards"
            accessibilityRole="button"
            disabled={!onUpdateToolPermissions || !guardDraftsDirty || pendingAction === 'save-guards'}
            onPress={() => updatePermissions({
              // Carry the latest optimistic toggle state (autoApprovedOps), not the
              // stale server-backed list: this PUT sends the FULL config, so using
              // the server value would clobber a toggle the user just flipped but
              // whose own request hasn't synced agent.toolsPermissionConfig yet.
              auto_approved_operations: autoApprovedOps,
              connector_guards: guardDrafts,
            }, 'save-guards')}
            style={({ pressed }) => [
              localStyles.secondaryButton,
              (!guardDraftsDirty || !onUpdateToolPermissions) && localStyles.disabledButton,
              pressed && sharedStyles.pressed,
            ]}
          >
            {pendingAction === 'save-guards' ? (
              <ActivityIndicator color={themedColor('#F4F4F5')} size="small" />
            ) : (
              <Check color={themedColor('#F4F4F5')} size={16} strokeWidth={2.6} />
            )}
            <Text style={localStyles.secondaryButtonText}>Save rules</Text>
          </Pressable>
        ) : null}
      </SettingsSection>
      ) : null}

      {section === 'general' ? (
      <SettingsSection
        title="Actions"
      >
        <Text style={localStyles.rowTitle}>Delete this agent</Text>
        <Text style={localStyles.deleteDescription}>
          Permanently remove this agent and all its data, conversations, files, and integrations. This action cannot be undone.
        </Text>
        <Pressable
          accessibilityLabel="Delete this agent"
          accessibilityRole="button"
          disabled={!onDeleteAgent || pendingAction === 'delete-agent'}
          onPress={onDeleteAgent ? () => { void bi.trackEditor('Agent Delete Click'); void runAction('delete-agent', () => onDeleteAgent({ agentId: agent.id })); } : undefined}
          style={({ pressed }) => [
            localStyles.destructiveButton,
            (!onDeleteAgent || pendingAction === 'delete-agent') && localStyles.disabledButton,
            pressed && sharedStyles.pressed,
          ]}
        >
          {pendingAction === 'delete-agent' ? (
            <ActivityIndicator color={themedColor('#FCA5A5')} size="small" />
          ) : (
            <Trash2 color={themedColor('#FCA5A5')} size={16} strokeWidth={2.5} />
          )}
          <Text style={localStyles.destructiveButtonText}>Delete this agent</Text>
        </Pressable>
      </SettingsSection>
      ) : null}
    </View>
  );
}

function SettingsSection({
  children,
  isLoading,
  title,
  tone = 'default',
}: {
  children: React.ReactNode;
  isLoading?: boolean;
  title: string;
  tone?: 'default' | 'danger';
}) {
  const isDanger = tone === 'danger';
  return (
    <View style={[localStyles.sectionCard, isDanger && localStyles.dangerSectionCard]}>
      <Text style={[localStyles.sectionTitle, isDanger && localStyles.dangerText]}>{title}</Text>
      {isLoading ? (
        <View style={localStyles.loadingRow}>
          <ActivityIndicator color={themedColor('#FF5A1F')} />
          <Text style={localStyles.mutedText}>Loading...</Text>
        </View>
      ) : children}
    </View>
  );
}

function ModelField({
  agentId,
  canSelectBestModel,
  modelOptions,
  onSelect,
  onViewPlans,
  selected,
}: {
  agentId: string;
  canSelectBestModel: boolean;
  modelOptions: ModelOption[];
  onSelect?: (input: { agentId: string; model: SuperagentModelChoice | string }) => Promise<void> | void;
  onViewPlans?: () => void;
  selected: ModelOption;
}) {
  const picker = useModelPicker({ agentId, selected, options: modelOptions, onSelect, canSelectBestModel, onViewPlans });

  return (
    <>
      <Pressable
        accessibilityLabel={`Current model: ${selected.label}`}
        accessibilityRole="button"
        disabled={picker.disabled}
        onPress={picker.open}
        style={({ pressed }) => [
          localStyles.modelDropdown,
          picker.disabled && localStyles.disabledButton,
          pressed && sharedStyles.pressed,
        ]}
      >
        <Text numberOfLines={1} style={localStyles.modelDropdownValue}>{selected.label}</Text>
        <View style={localStyles.modelDropdownIcon}>
          {picker.isUpdating ? (
            <ActivityIndicator color={themedColor('#F4F4F5')} size="small" />
          ) : (
            <ChevronDown color={themedColor('#F4F4F5')} size={20} strokeWidth={2.5} />
          )}
        </View>
      </Pressable>
      <ModelPickerModal
        isVisible={picker.isOpen}
        options={modelOptions}
        selectedModelId={selected.id}
        canSelectBestModel={canSelectBestModel}
        onClose={picker.close}
        onSelect={picker.selectModel}
        onViewPlans={onViewPlans}
      />
    </>
  );
}

function normalizePermissions(config?: SuperagentToolPermissionConfig): Required<SuperagentToolPermissionConfig> {
  return {
    auto_approved_operations: config?.auto_approved_operations ?? [],
    connector_guards: config?.connector_guards ?? {},
  };
}

function cleanGuards(guards: Record<string, string>) {
  return Object.fromEntries(
    Object.entries(guards)
      .map(([key, value]) => [key, value.trim()])
      .filter(([, value]) => value),
  );
}

function toggleSecretVisibility(current: Set<string>, name: string) {
  const next = new Set(current);
  if (next.has(name)) {
    next.delete(name);
  } else {
    next.add(name);
  }
  return next;
}

const localStyles = createThemedStyles({
  addSecretBox: {
    gap: 8,
    marginTop: 11,
  },
  connectorFallback: {
    color: '#F4F4F5',
    fontSize: 10,
    fontWeight: '900',
  },
  connectorGuard: {
    marginTop: 10,
  },
  connectorHeader: {
    alignItems: 'center',
    flexDirection: 'row',
    marginBottom: 8,
  },
  connectorIcon: {
    alignItems: 'center',
    backgroundColor: '#F4F4F5',
    borderRadius: 10,
    height: 34,
    justifyContent: 'center',
    marginRight: 10,
    overflow: 'hidden',
    width: 34,
  },
  connectorTitleWrap: {
    flex: 1,
    minWidth: 0,
  },
  dangerSectionCard: {
    borderColor: '#552022',
  },
  dangerText: {
    color: '#FCA5A5',
  },
  disabledButton: {
    opacity: 0.55,
  },
  errorText: {
    color: '#FCA5A5',
    fontSize: 12,
    fontWeight: '700',
    marginTop: 8,
  },
  deleteDescription: {
    color: '#A1A1AA',
    fontSize: 13,
    fontWeight: '600',
    lineHeight: 18,
    marginBottom: 14,
    marginTop: 4,
  },
  destructiveButton: {
    alignItems: 'center',
    alignSelf: 'flex-start',
    backgroundColor: '#1C0F10',
    borderColor: '#552022',
    borderRadius: 8,
    borderWidth: 1,
    flexDirection: 'row',
    gap: 8,
    minHeight: 40,
    paddingHorizontal: 14,
    paddingVertical: 9,
  },
  destructiveButtonText: {
    color: '#FCA5A5',
    fontSize: 13,
    fontWeight: '800',
  },
  fieldLabel: {
    color: '#F4F4F5',
    fontSize: 13,
    fontWeight: '700',
    marginBottom: 8,
  },
  fieldLabelSpaced: {
    marginTop: 16,
  },
  guardInput: {
    minHeight: 74,
    paddingTop: 10,
    textAlignVertical: 'top',
  },
  iconButton: {
    alignItems: 'center',
    backgroundColor: '#242427',
    borderRadius: 10,
    height: 34,
    justifyContent: 'center',
    marginLeft: 7,
    width: 34,
  },
  iconButtonDanger: {
    alignItems: 'center',
    backgroundColor: '#351516',
    borderRadius: 10,
    height: 34,
    justifyContent: 'center',
    marginLeft: 7,
    width: 34,
  },
  loadingRow: {
    alignItems: 'center',
    flexDirection: 'row',
    gap: 9,
    paddingVertical: 12,
  },
  modelDropdown: {
    alignItems: 'center',
    backgroundColor: '#0B0B0C',
    borderColor: '#2A2A2A',
    borderRadius: 8,
    borderWidth: 1,
    flexDirection: 'row',
    minHeight: 48,
    paddingLeft: 14,
    paddingRight: 12,
    paddingVertical: 9,
  },
  modelDropdownIcon: {
    alignItems: 'center',
    justifyContent: 'center',
    marginLeft: 10,
  },
  modelDropdownValue: {
    color: '#F4F4F5',
    flex: 1,
    fontSize: 15,
    fontWeight: '700',
    minWidth: 0,
  },
  mutedText: {
    color: '#A1A1AA',
    fontSize: 12,
    fontWeight: '700',
    lineHeight: 17,
  },
  permissionRow: {
    alignItems: 'center',
    backgroundColor: '#151515',
    borderColor: '#2A2A2A',
    borderRadius: 8,
    borderWidth: 1,
    flexDirection: 'row',
    marginBottom: 9,
    minHeight: 70,
    paddingHorizontal: 12,
    paddingVertical: 10,
  },
  permissionText: {
    flex: 1,
    marginRight: 10,
    minWidth: 0,
  },
  primaryButton: {
    alignItems: 'center',
    alignSelf: 'flex-start',
    backgroundColor: '#F4F4F5',
    borderRadius: 8,
    flexDirection: 'row',
    minHeight: 38,
    paddingHorizontal: 12,
  },
  primaryButtonText: {
    color: '#111111',
    fontSize: 13,
    fontWeight: '900',
    marginLeft: 6,
  },
  rowBody: {
    color: '#A1A1AA',
    fontSize: 12,
    fontWeight: '700',
    lineHeight: 17,
    marginTop: 3,
  },
  rowTitle: {
    color: '#F4F4F5',
    fontSize: 14,
    fontWeight: '900',
  },
  secondaryButton: {
    alignItems: 'center',
    alignSelf: 'flex-start',
    backgroundColor: '#242427',
    borderColor: '#353539',
    borderRadius: 8,
    borderWidth: 1,
    flexDirection: 'row',
    marginTop: 11,
    minHeight: 38,
    paddingHorizontal: 12,
  },
  secondaryButtonText: {
    color: '#F4F4F5',
    fontSize: 13,
    fontWeight: '900',
    marginLeft: 6,
  },
  secretList: {
    gap: 8,
  },
  secretName: {
    color: '#F4F4F5',
    fontFamily: 'Courier',
    fontSize: 12,
    fontWeight: '900',
  },
  secretRow: {
    alignItems: 'center',
    backgroundColor: '#151515',
    borderColor: '#2A2A2A',
    borderRadius: 8,
    borderWidth: 1,
    flexDirection: 'row',
    minHeight: 58,
    paddingHorizontal: 11,
    paddingVertical: 9,
  },
  secretText: {
    flex: 1,
    minWidth: 0,
  },
  secretValue: {
    color: '#A1A1AA',
    fontSize: 12,
    fontWeight: '700',
    marginTop: 3,
  },
  sectionCard: {
    backgroundColor: '#0B0B0C',
    borderColor: '#242427',
    borderRadius: 8,
    borderWidth: 1,
    marginBottom: 14,
    padding: 16,
  },
  sectionTitle: {
    color: '#F4F4F5',
    fontSize: 15,
    fontWeight: '700',
    marginBottom: 12,
  },
  textInput: {
    backgroundColor: '#0B0B0C',
    borderColor: '#2A2A2A',
    borderRadius: 8,
    borderWidth: 1,
    color: '#F4F4F5',
    fontSize: 13,
    fontWeight: '700',
    minHeight: 48,
    paddingHorizontal: 11,
  },
});
