import React, { useState } from 'react';
import { ActivityIndicator, Image, Pressable, Text, View } from 'react-native';
import { AlertCircle, Info, MoreHorizontal, Plug, Unplug } from 'lucide-react-native';

import { ConnectorBrandIcon, hasConnectorBrandIcon } from './connectorBrandIcons';
import { connectorDescription, connectorSubtitle, getConnectorScopesForMode } from './connectorPanelUtils';
import { connectorPanelStyles as cStyles } from './connectorPanelStyles';
import { editorShellStyles } from '../editor/editorShellStyles';
import { useAgentBi } from '../../analytics/mixpanelContext';
import { styles as sharedStyles } from '../../styles';
import { themedColor } from '../../theme';
import type {
  SuperagentConnector,
  SuperagentConnectorAccessMode,
  SuperagentConnectorActionInput,
} from '../../types';

export function ConnectorCard({
  agentId,
  connector,
  isConnecting,
  onCancel,
  onSelect,
}: {
  agentId: string;
  connector: SuperagentConnector;
  isConnecting?: boolean;
  onCancel?: (input: { agentId: string; connectorId: string }) => void;
  onSelect: () => void;
}) {
  // While this connector is connecting, the card stays a spinner + Cancel (not a
  // pressable "Connect" chip) so backing out of the detail view during OAuth
  // still leaves the flow visible and cancelable.
  if (isConnecting) {
    return (
      <View style={[editorShellStyles.connectorCard, cStyles.cardSurface]}>
        <ConnectorIcon connector={connector} />
        <View style={editorShellStyles.connectorText}>
          <Text numberOfLines={1} style={editorShellStyles.connectorName}>{connector.name}</Text>
          <Text style={editorShellStyles.connectorSubtitle}>{connectorSubtitle(connector)}</Text>
        </View>
        <View style={editorShellStyles.connectingWrap}>
          <ActivityIndicator color={themedColor('#8B5CF6')} size="small" />
          <Pressable
            accessibilityLabel={`Cancel ${connector.name} connection`}
            accessibilityRole="button"
            onPress={() => onCancel?.({ agentId, connectorId: connector.id })}
            style={({ pressed }) => [editorShellStyles.cancelConnectButton, pressed && sharedStyles.pressed]}
          >
            <Text style={editorShellStyles.cancelConnectText}>Cancel</Text>
          </Pressable>
        </View>
      </View>
    );
  }

  return (
    <Pressable
      accessibilityLabel={`View ${connector.name}`}
      accessibilityRole="button"
      onPress={onSelect}
      style={({ pressed }) => [editorShellStyles.connectorCard, cStyles.cardSurface, pressed && sharedStyles.pressed]}
    >
      <ConnectorIcon connector={connector} />
      <View style={editorShellStyles.connectorText}>
        <Text numberOfLines={1} style={editorShellStyles.connectorName}>{connector.name}</Text>
        <Text style={editorShellStyles.connectorSubtitle}>{connectorSubtitle(connector)}</Text>
      </View>
      <View style={cStyles.connectChip}>
        <Text style={cStyles.connectChipText}>Connect</Text>
      </View>
    </Pressable>
  );
}

export function ConnectedConnectorCard({
  agentId,
  connector,
  isConnecting,
  onCancel,
  onConnect,
  onDisconnect,
  onRemove,
}: {
  agentId: string;
  connector: SuperagentConnector;
  isConnecting: boolean;
  onCancel?: (input: { agentId: string; connectorId: string }) => void;
  onConnect?: (input: SuperagentConnectorActionInput) => Promise<boolean | string | void> | boolean | string | void;
  onDisconnect?: (input: SuperagentConnectorActionInput) => Promise<void> | void;
  onRemove?: (input: SuperagentConnectorActionInput) => Promise<void> | void;
}) {
  const status = connector.status ?? 'active';
  const [menuOpen, setMenuOpen] = useState(false);
  const bi = useAgentBi();
  const hasAccessModes = !!connector.accessModes;
  const currentMode = connector.accessMode ?? null;
  const oppositeMode: SuperagentConnectorAccessMode = currentMode === 'read_only' ? 'full_access' : 'read_only';

  return (
    <View style={[editorShellStyles.connectorCard, cStyles.cardSurface, menuOpen && editorShellStyles.connectorCardMenuOpen]}>
      <ConnectorIcon connector={connector} />
      <View style={editorShellStyles.connectorText}>
        <View style={editorShellStyles.inlineTitleRow}>
          <Text numberOfLines={1} style={editorShellStyles.connectorName}>{connector.name}</Text>
          <StatusBadge status={status} />
        </View>
        <Text numberOfLines={1} style={editorShellStyles.connectorSubtitle}>
          {connector.accountIdentifier || connectorDescription(connector)}
        </Text>
      </View>
      {isConnecting ? (
        <View style={editorShellStyles.connectingWrap}>
          <ActivityIndicator color={themedColor('#8B5CF6')} size="small" />
          <Pressable
            accessibilityLabel={`Cancel ${connector.name} connection`}
            accessibilityRole="button"
            onPress={() => onCancel?.({ agentId, connectorId: connector.id })}
            style={({ pressed }) => [editorShellStyles.cancelConnectButton, pressed && sharedStyles.pressed]}
          >
            <Text style={editorShellStyles.cancelConnectText}>Cancel</Text>
          </Pressable>
        </View>
      ) : (
        <View style={editorShellStyles.connectorActions}>
          <Pressable
            accessibilityLabel={`${connector.name} actions`}
            accessibilityRole="button"
            onPress={() => setMenuOpen((open) => !open)}
            style={({ pressed }) => [editorShellStyles.moreButton, pressed && sharedStyles.pressed]}
          >
            <MoreHorizontal color={themedColor('#E4E4E7')} size={19} strokeWidth={2.4} />
          </Pressable>
        </View>
      )}
      {menuOpen ? (
        <View style={editorShellStyles.connectorMenu}>
          {hasAccessModes && onConnect && !connector.requiresConnectionConfig ? (
            <MenuAction
              label={oppositeMode === 'read_only' ? 'Switch to read only' : 'Switch to full access'}
              onPress={async () => {
                setMenuOpen(false);
                const result = await onConnect({
                  accessMode: oppositeMode,
                  agentId,
                  connectorId: connector.id,
                  forceReconnect: true,
                  scopes: getConnectorScopesForMode(connector, oppositeMode),
                });
                if (result) {
                  void bi.trackEditor('Plugin Access Mode Switch', { connector_type: connector.id, from_mode: currentMode ?? 'full_access', to_mode: oppositeMode });
                }
              }}
            />
          ) : null}
          {connector.requiresConnectionConfig ? (
            <MenuNote label="Switch account on the web app" />
          ) : (
            <MenuAction
              label={status === 'active' ? 'Switch account' : 'Reconnect'}
              onPress={async () => {
                setMenuOpen(false);
                const result = await onConnect?.({
                  accessMode: connector.accessMode ?? undefined,
                  agentId,
                  connectorId: connector.id,
                  forceReconnect: true,
                  scopes: connector.scopes?.length ? connector.scopes : getConnectorScopesForMode(connector, connector.accessMode ?? 'full_access'),
                });
                // A successful reconnect / switch-account counts as a connect too.
                if (result) {
                  void bi.trackEditor('Plugin Connect', { connector_type: connector.id, access_mode: connector.accessMode ?? 'full_access' });
                }
              }}
            />
          )}
          {status !== 'disconnected' ? (
            <MenuAction
              destructive
              label="Disconnect"
              onPress={() => {
                setMenuOpen(false);
                onDisconnect?.({ agentId, connectorId: connector.id });
              }}
            />
          ) : null}
          <MenuAction
            destructive
            label="Remove"
            onPress={() => {
              setMenuOpen(false);
              onRemove?.({ agentId, connectorId: connector.id });
            }}
          />
        </View>
      ) : null}
    </View>
  );
}

export function ConnectorIcon({ connector }: { connector: SuperagentConnector }) {
  const iconBackgroundColor = connector.iconBackgroundColor ?? '#FFFFFF';
  const hasBrandIcon = hasConnectorBrandIcon(connector.id);
  const [imageFailed, setImageFailed] = useState(false);
  const iconUrl = connector.iconUrl?.trim();

  return (
    <View style={[editorShellStyles.connectorIcon, { backgroundColor: iconBackgroundColor }]}>
      {hasBrandIcon ? (
        <ConnectorBrandIcon connectorId={connector.id} size={22} />
      ) : iconUrl && !imageFailed ? (
        <Image
          onError={() => setImageFailed(true)}
          resizeMode="contain"
          source={{ uri: iconUrl }}
          style={editorShellStyles.connectorIconImage}
        />
      ) : (
        <Plug color={themedColor('#111827')} size={20} strokeWidth={2.35} />
      )}
    </View>
  );
}

// Matches the web ConnectorStatusLabel: a small colored dot + label, no filled
// pill. Active = green dot + green text; expired = alert + danger; disconnected
// = unplug + muted.
export function StatusBadge({ status }: { status: SuperagentConnector['status'] }) {
  const isActive = status === 'active' || !status;
  const isDisconnected = status === 'disconnected';
  if (isActive) {
    return (
      <View style={cStyles.statusRow}>
        <View style={cStyles.statusDot} />
        <Text style={cStyles.statusActiveText}>Active</Text>
      </View>
    );
  }
  if (isDisconnected) {
    return (
      <View style={cStyles.statusRow}>
        <Unplug color={themedColor('#A1A1AA')} size={11} strokeWidth={2.6} />
        <Text style={cStyles.statusMutedText}>Disconnected</Text>
      </View>
    );
  }
  return (
    <View style={cStyles.statusRow}>
      <AlertCircle color={themedColor('#FCA5A5')} size={11} strokeWidth={2.6} />
      <Text style={cStyles.statusDangerText}>{status}</Text>
    </View>
  );
}

function MenuAction({ destructive, label, onPress }: { destructive?: boolean; label: string; onPress: () => void }) {
  return (
    <Pressable accessibilityRole="button" onPress={onPress} style={({ pressed }) => [
      editorShellStyles.menuAction,
      pressed && sharedStyles.pressed,
    ]}>
      <Text style={[
        editorShellStyles.menuActionText,
        destructive && editorShellStyles.menuActionTextDestructive,
      ]}>{label}</Text>
    </Pressable>
  );
}

function MenuNote({ label }: { label: string }) {
  return (
    <View style={editorShellStyles.menuNote}>
      <Info color={themedColor('#8E8E93')} size={13} strokeWidth={2.2} />
      <Text style={editorShellStyles.menuNoteText}>{label}</Text>
    </View>
  );
}
