import React, { useState } from 'react';
import { createThemedStyles, themedColor } from '../../theme';
import { ActivityIndicator, Pressable, Text, View } from 'react-native';
import {
  Copy,
  ExternalLink,
  MessageCircle,
  RefreshCw,
  Unplug,
} from 'lucide-react-native';

import { ChannelBrandIcon } from './channelBrandIcons';
import { editorShellStyles } from '../editor/editorShellStyles';
import { slackWorkspaceEntries } from './slackChannelUtils';
import { useSuperagentChannels } from '../../runtime/runtimeContext';
import { styles } from '../../styles';
import type {
  SuperagentAgent,
  SuperagentChannelStatus,
  SuperagentHomeScreenViewProps,
  SuperagentSlackChannelStatus,
} from '../../types';
import {
  useCanCreateManagedTelegramBot,
  useCanManageSuperagent,
} from '../../user/userContext';

export function ChannelsPanel({ agent }: { agent: SuperagentAgent }) {
  const {
    channelStatus,
    connectingChannelId,
    disconnectingChannelId,
    onConnectSlack,
    onDisconnectSlack,
    onDisconnectTelegram,
    onDisconnectIMessage,
    onDisconnectWhatsApp,
    onGenerateIMessageCode,
    onOpenIMessage,
    onOpenTelegram,
    onOpenWhatsApp,
    onSetupTelegram,
    onShareIMessageCode,
  } = useSuperagentChannels();
  const canManage = useCanManageSuperagent(agent);
  const canSetupTelegram = useCanCreateManagedTelegramBot(agent);
  const imessage = channelStatus?.imessage;
  const telegram = channelStatus?.telegram;
  const whatsapp = channelStatus?.whatsapp;
  const slack = channelStatus?.slack;
  // LINE is hidden for now — its connection status isn't wired on native yet
  // (no runtime status route), so it would always show as disconnected.

  return (
    <View style={editorShellStyles.settingsStack}>
      <WhatsAppChannel
        agentId={agent.id}
        canManage={canManage}
        connected={!!whatsapp?.connected}
        isConnecting={connectingChannelId === 'whatsapp'}
        isDisconnecting={disconnectingChannelId === 'whatsapp'}
        onDisconnectWhatsApp={onDisconnectWhatsApp}
        onOpenWhatsApp={onOpenWhatsApp}
        userHandle={whatsapp?.userHandle ?? null}
      />
      <IMessageChannel
        agentId={agent.id}
        imessage={imessage}
        isBusy={connectingChannelId === 'imessage'}
        onDisconnectIMessage={onDisconnectIMessage}
        onGenerateIMessageCode={onGenerateIMessageCode}
        onOpenIMessage={onOpenIMessage}
        onShareIMessageCode={onShareIMessageCode}
      />
      <TelegramChannel
        agentDisplayName={agent.name}
        agentId={agent.id}
        agentProfilePhotoUrl={agent.logoUrl}
        canManage={canManage}
        canSetup={canSetupTelegram}
        isBusy={connectingChannelId === 'telegram'}
        onDisconnectTelegram={onDisconnectTelegram}
        onOpenTelegram={onOpenTelegram}
        onSetupTelegram={onSetupTelegram}
        telegram={telegram}
      />
      <SlackChannel
        agentId={agent.id}
        isConnecting={connectingChannelId === 'slack'}
        isDisconnecting={disconnectingChannelId === 'slack'}
        onConnectSlack={onConnectSlack}
        onDisconnectSlack={onDisconnectSlack}
        slack={slack}
      />
      {/* LINE hidden for now — real connection status isn't wired on native
          yet (no runtime status route). Re-add <LineChannel/> once it is. */}
    </View>
  );
}

function WhatsAppChannel({
  agentId,
  canManage,
  connected,
  isConnecting,
  isDisconnecting,
  onDisconnectWhatsApp,
  onOpenWhatsApp,
  userHandle,
}: {
  agentId: string;
  canManage: boolean;
  connected: boolean;
  isConnecting: boolean;
  isDisconnecting: boolean;
  onDisconnectWhatsApp?: SuperagentHomeScreenViewProps['onDisconnectWhatsApp'];
  onOpenWhatsApp?: SuperagentHomeScreenViewProps['onOpenWhatsApp'];
  userHandle?: string | null;
}) {
  // Any WhatsApp action in flight disables both CTAs, but each button only spins
  // for its own action so a disconnect doesn't also spin "Open WhatsApp".
  const isBusy = isConnecting || isDisconnecting;
  return (
    <ChannelCard
      connected={connected}
      detail={userHandle}
      description="Open WhatsApp with the generated activation message for this Superagent."
      icon={<ChannelBrandIcon channel="whatsapp" size={26} />}
      title="WhatsApp"
    >
      {/* The handler builds the connect URL on press, so don't gate on a preloaded
          connectUrl — it's missing before status loads even though the press works. */}
      <View style={channelStyles.actionRow}>
        <ChannelButton
          accessibilityLabel={connected ? 'Open WhatsApp' : 'Connect WhatsApp'}
          secondary
          disabled={!onOpenWhatsApp || isBusy}
          icon={connected ? <ExternalLink color={themedColor('#F4F4F5')} size={15} strokeWidth={2.4} /> : undefined}
          isBusy={isConnecting}
          label={connected ? 'Open WhatsApp' : 'Connect'}
          onPress={() => onOpenWhatsApp?.({ agentId })}
        />
        {connected ? (
          <ChannelButton
            accessibilityLabel="Disconnect WhatsApp"
            danger
            disabled={!canManage || !onDisconnectWhatsApp || isBusy}
            icon={<Unplug color={themedColor('#FCA5A5')} size={15} strokeWidth={2.4} />}
            isBusy={isDisconnecting}
            label="Disconnect"
            onPress={() => onDisconnectWhatsApp?.({ agentId })}
          />
        ) : null}
      </View>
    </ChannelCard>
  );
}

function IMessageChannel({
  agentId,
  imessage,
  isBusy,
  onDisconnectIMessage,
  onGenerateIMessageCode,
  onOpenIMessage,
  onShareIMessageCode,
}: {
  agentId: string;
  imessage?: SuperagentChannelStatus['imessage'];
  isBusy: boolean;
  onDisconnectIMessage?: SuperagentHomeScreenViewProps['onDisconnectIMessage'];
  onGenerateIMessageCode?: SuperagentHomeScreenViewProps['onGenerateIMessageCode'];
  onOpenIMessage?: SuperagentHomeScreenViewProps['onOpenIMessage'];
  onShareIMessageCode?: SuperagentHomeScreenViewProps['onShareIMessageCode'];
}) {
  const activation = imessage?.activation;
  const phoneNumber = imessage?.phoneNumber ?? activation?.phoneNumber ?? null;
  const [localError, setLocalError] = useState<string | null>(null);

  const connectIMessage = async () => {
    if (!onGenerateIMessageCode) {
      return;
    }

    setLocalError(null);
    try {
      const generated = await onGenerateIMessageCode({ agentId });
      if (generated && onOpenIMessage) {
        await onOpenIMessage({ agentId, ...generated });
      }
    } catch (error) {
      setLocalError(error instanceof Error ? error.message : 'iMessage setup failed.');
    }
  };

  return (
    <ChannelCard
      connected={imessage?.connected}
      detail={phoneNumber}
      description="Open Messages with the activation code ready to send."
      icon={<ChannelBrandIcon channel="imessage" size={26} />}
      title="iMessage"
    >
      {imessage?.connected ? (
        <View style={channelStyles.actionRow}>
          <ChannelButton
            accessibilityLabel="Disconnect iMessage"
            danger
            disabled={!onDisconnectIMessage || isBusy}
            icon={<Unplug color={themedColor('#FCA5A5')} size={15} strokeWidth={2.4} />}
            isBusy={isBusy}
            label="Disconnect"
            onPress={() => onDisconnectIMessage?.({ agentId })}
          />
        </View>
      ) : (
        <View style={channelStyles.setupStack}>
          {localError ? <Text style={channelStyles.errorText}>{localError}</Text> : null}
          {activation ? (
            <View style={channelStyles.connectedBox}>
              <Text style={channelStyles.codeLabel}>Text this activation code</Text>
              <Text selectable style={channelStyles.activationCode}>{activation.code}</Text>
              <Text selectable style={channelStyles.connectedBody}>To: {activation.phoneNumber}</Text>
              <Text style={channelStyles.expiryText}>Code expires in 30 minutes.</Text>
            </View>
          ) : null}
          <View style={channelStyles.actionRow}>
            <ChannelButton
              accessibilityLabel="Connect iMessage"
              secondary
              disabled={!onGenerateIMessageCode || isBusy}
              isBusy={isBusy}
              label="Connect"
              onPress={connectIMessage}
            />
            {activation ? (
              <>
                <ChannelButton
                  disabled={!onOpenIMessage || isBusy}
                  icon={<ExternalLink color={themedColor('#111111')} size={15} strokeWidth={2.4} />}
                  label="Open Messages"
                  onPress={() => onOpenIMessage?.({ agentId, ...activation })}
                />
                <ChannelButton
                  secondary
                  disabled={!onShareIMessageCode}
                  icon={<Copy color={themedColor('#F4F4F5')} size={15} strokeWidth={2.4} />}
                  label="Share code"
                  onPress={() => onShareIMessageCode?.({ agentId, ...activation })}
                />
              </>
            ) : null}
          </View>
        </View>
      )}
    </ChannelCard>
  );
}

function TelegramChannel({
  agentDisplayName,
  agentId,
  agentProfilePhotoUrl,
  canManage,
  canSetup,
  isBusy,
  onDisconnectTelegram,
  onOpenTelegram,
  onSetupTelegram,
  telegram,
}: {
  agentDisplayName: string;
  agentId: string;
  agentProfilePhotoUrl?: string;
  canManage: boolean;
  canSetup: boolean;
  isBusy: boolean;
  onDisconnectTelegram?: SuperagentHomeScreenViewProps['onDisconnectTelegram'];
  onOpenTelegram?: SuperagentHomeScreenViewProps['onOpenTelegram'];
  onSetupTelegram?: SuperagentHomeScreenViewProps['onSetupTelegram'];
  telegram?: SuperagentChannelStatus['telegram'];
}) {
  const botTitle = telegram?.botName || telegram?.botUsername || 'Telegram bot';

  return (
    <ChannelCard
      connected={telegram?.connected}
      detail={telegram?.botUsername ? `@${telegram.botUsername}` : botTitle}
      description="Create a Telegram bot for your agent with one click. It will be set up and ready to chat automatically."
      icon={<ChannelBrandIcon channel="telegram" size={26} />}
      title="Telegram"
    >
      {telegram?.connected ? (
        <View style={channelStyles.actionRow}>
          {telegram.botLink ? (
            <ChannelButton
              icon={<ExternalLink color={themedColor('#111111')} size={15} strokeWidth={2.4} />}
              label="Open bot"
              onPress={() => onOpenTelegram?.({ agentId, url: telegram.botLink || '' })}
            />
          ) : null}
          <ChannelButton
            accessibilityLabel="Disconnect Telegram"
            danger
            disabled={!canManage || !onDisconnectTelegram || isBusy}
            icon={<Unplug color={themedColor('#FCA5A5')} size={15} strokeWidth={2.4} />}
            isBusy={isBusy}
            label="Disconnect"
            onPress={() => onDisconnectTelegram?.({ agentId })}
          />
        </View>
      ) : canSetup ? (
        <View style={channelStyles.actionRow}>
          <ChannelButton
            accessibilityLabel="Connect Telegram"
            secondary
            disabled={!onSetupTelegram || isBusy}
            isBusy={isBusy}
            label="Connect"
            onPress={() => onSetupTelegram?.({ agentDisplayName, agentId, agentProfilePhotoUrl })}
          />
        </View>
      ) : null}
    </ChannelCard>
  );
}

function SlackChannel({
  agentId,
  isConnecting,
  isDisconnecting,
  onConnectSlack,
  onDisconnectSlack,
  slack,
}: {
  agentId: string;
  isConnecting: boolean;
  isDisconnecting: boolean;
  onConnectSlack?: SuperagentHomeScreenViewProps['onConnectSlack'];
  onDisconnectSlack?: SuperagentHomeScreenViewProps['onDisconnectSlack'];
  slack?: SuperagentSlackChannelStatus;
}) {
  // Any Slack action in flight disables both CTAs, but each button only spins
  // for its own action so a disconnect doesn't also spin "Connect".
  const isBusy = isConnecting || isDisconnecting;
  const connected = !!slack?.connected;
  const supported = slack?.supported !== false;
  const pendingCleanup = !!slack?.pendingCleanup;
  const workspaces = slackWorkspaceEntries(slack);
  const teamName = workspaces[0]?.teamName ?? slack?.teamName ?? null;
  const description = supported
    ? 'Add your agent to a Slack workspace, then mention it to start chatting.'
    : 'Slack is not available on this platform yet.';

  // Tearing down a live connection is destructive, so this stays the red danger
  // button. (The pending-cleanup retry below is a neutral recovery action.)
  const disconnectButton = (
    <ChannelButton
      accessibilityLabel="Disconnect Slack"
      danger
      disabled={!onDisconnectSlack || isBusy}
      icon={<Unplug color={themedColor('#FCA5A5')} size={15} strokeWidth={2.4} />}
      isBusy={isDisconnecting}
      label="Disconnect"
      onPress={() => onDisconnectSlack?.({ agentId })}
    />
  );
  const connectedCleanupNotice = pendingCleanup ? (
    <Text style={[channelStyles.cleanupText, channelStyles.noticeSpacing]}>Some workspaces are still being disconnected on Slack’s side.</Text>
  ) : null;
  // Not-connected states: notice + an explicit "Retry disconnect" affordance,
  // the only path left to retire a still-active external install/@handle.
  const pendingCleanupNotice = pendingCleanup ? (
    <View style={channelStyles.cleanupBox}>
      <Text style={channelStyles.cleanupText}>Some workspaces are still being disconnected on Slack’s side.</Text>
      <View style={channelStyles.actionRow}>
        <ChannelButton
          secondary
          disabled={!onDisconnectSlack || isBusy}
          icon={<RefreshCw color={themedColor('#F4F4F5')} size={15} strokeWidth={2.4} />}
          isBusy={isDisconnecting}
          label="Retry disconnect"
          onPress={() => onDisconnectSlack?.({ agentId })}
        />
      </View>
    </View>
  ) : null;

  return (
    <ChannelCard
      connected={connected}
      detail={teamName}
      description={description}
      icon={<ChannelBrandIcon channel="slack" size={26} />}
      title="Slack"
    >
      {connected ? (
        <>
          {workspaces.length > 0 ? (
            <View style={channelStyles.connectedBox}>
              {workspaces.map((workspace, index) => (
                <View key={workspace.teamId ?? workspace.usergroupHandle ?? index} style={index > 0 ? channelStyles.slackWorkspaceStacked : undefined}>
                  {/* Name each workspace only when there's more than one — otherwise
                      the single team's name already shows in the card status line. */}
                  {workspaces.length > 1 && workspace.teamName ? (
                    <Text style={channelStyles.connectedBody}>{workspace.teamName}</Text>
                  ) : null}
                  {workspace.usergroupHandle ? (
                    <>
                      <Text selectable style={channelStyles.slackHandle}>@{workspace.usergroupHandle}</Text>
                      <Text style={channelStyles.slackHint}>Mention this handle in Slack to reach the agent.</Text>
                    </>
                  ) : (
                    <Text style={channelStyles.connectedBody}>Mention the “Superagents by Base44” bot in your channel.</Text>
                  )}
                </View>
              ))}
            </View>
          ) : null}
          {connectedCleanupNotice}
          <View style={channelStyles.actionRow}>{disconnectButton}</View>
        </>
      ) : supported || pendingCleanup ? (
        <View style={channelStyles.setupStack}>
          {pendingCleanupNotice}
          {supported ? (
            <View style={channelStyles.actionRow}>
              <ChannelButton
                accessibilityLabel="Connect Slack"
                secondary
                disabled={!onConnectSlack || isBusy}
                isBusy={isConnecting}
                label="Connect"
                onPress={() => onConnectSlack?.({ agentId })}
              />
            </View>
          ) : null}
        </View>
      ) : null}
    </ChannelCard>
  );
}

function LineChannel({
  agentId,
  isBusy,
  line,
  onGenerateLineCode,
  onOpenLine,
  onShareLineCode,
}: {
  agentId: string;
  isBusy: boolean;
  line?: SuperagentChannelStatus['line'];
  onGenerateLineCode?: SuperagentHomeScreenViewProps['onGenerateLineCode'];
  onOpenLine?: SuperagentHomeScreenViewProps['onOpenLine'];
  onShareLineCode?: SuperagentHomeScreenViewProps['onShareLineCode'];
}) {
  const activation = line?.activation;

  return (
    <ChannelCard
      connected={false}
      description={activation ? 'Activation code is ready. Add the bot in LINE, then send this code.' : 'Generate a short-lived activation code for the shared LINE bot.'}
      icon={<MessageCircle color="#06C755" size={22} strokeWidth={2.45} />}
      title="LINE"
    >
      {activation ? (
        <View style={channelStyles.connectedBox}>
          <Text style={channelStyles.codeLabel}>Activation code</Text>
          <Text selectable style={channelStyles.activationCode}>{activation.code}</Text>
          <View style={channelStyles.actionRow}>
            <ChannelButton
              icon={<ExternalLink color={themedColor('#111111')} size={15} strokeWidth={2.4} />}
              label="Open LINE"
              onPress={() => onOpenLine?.({ agentId, url: activation.addFriendUrl })}
            />
            <ChannelButton
              secondary
              icon={<Copy color={themedColor('#F4F4F5')} size={15} strokeWidth={2.4} />}
              label="Share code"
              onPress={() => onShareLineCode?.({ agentId, ...activation })}
            />
          </View>
        </View>
      ) : (
        <View style={channelStyles.actionRow}>
          <ChannelButton
            secondary
            disabled={!onGenerateLineCode || isBusy}
            isBusy={isBusy}
            label="Generate code"
            onPress={() => onGenerateLineCode?.({ agentId })}
          />
        </View>
      )}
    </ChannelCard>
  );
}

function ChannelCard({
  children,
  connected,
  description,
  detail,
  icon,
  title,
}: {
  children: React.ReactNode;
  connected?: boolean;
  description?: string;
  detail?: string | null;
  icon: React.ReactNode;
  title: string;
}) {
  return (
    <View style={channelStyles.card}>
      <View style={channelStyles.cardHeader}>
        <View style={channelStyles.channelIcon}>{icon}</View>
        <View style={channelStyles.channelText}>
          <Text style={channelStyles.channelTitle}>{title}</Text>
          {connected ? (
            <View style={channelStyles.statusLine}>
              <View style={channelStyles.statusDot} />
              <Text style={channelStyles.statusConnected}>
                Connected
                {detail ? <Text style={channelStyles.statusDetail}> · {detail}</Text> : null}
              </Text>
            </View>
          ) : description ? (
            <Text numberOfLines={2} style={channelStyles.channelBody}>{description}</Text>
          ) : null}
        </View>
      </View>
      {children}
    </View>
  );
}

function ChannelButton({
  accessibilityLabel,
  danger,
  disabled,
  icon,
  isBusy,
  label,
  onPress,
  secondary,
}: {
  accessibilityLabel?: string;
  danger?: boolean;
  disabled?: boolean;
  icon?: React.ReactNode;
  isBusy?: boolean;
  label: string;
  onPress?: () => void;
  secondary?: boolean;
}) {
  return (
    <Pressable
      accessibilityLabel={accessibilityLabel}
      accessibilityRole="button"
      disabled={disabled}
      onPress={onPress}
      style={({ pressed }) => [
        channelStyles.button,
        secondary && channelStyles.buttonSecondary,
        danger && channelStyles.buttonDanger,
        disabled && channelStyles.disabled,
        pressed && styles.pressed,
      ]}
    >
      {isBusy ? <ActivityIndicator color={danger || secondary ? themedColor('#F4F4F5') : themedColor('#111111')} size="small" /> : icon}
      <Text style={[
        channelStyles.buttonText,
        secondary && channelStyles.buttonTextSecondary,
        danger && channelStyles.buttonTextDanger,
      ]}>{label}</Text>
    </Pressable>
  );
}

const channelStyles = createThemedStyles({
  actionRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 8,
    justifyContent: 'flex-end',
    marginTop: 12,
  },
  activationCode: {
    color: '#F4F4F5',
    fontFamily: 'Courier',
    fontSize: 20,
    fontWeight: '900',
    letterSpacing: 0,
    marginTop: 5,
  },
  button: {
    alignItems: 'center',
    backgroundColor: '#F4F4F5',
    borderRadius: 8,
    flexDirection: 'row',
    gap: 6,
    minHeight: 36,
    paddingHorizontal: 13,
  },
  buttonDanger: {
    backgroundColor: 'transparent',
    borderColor: '#552022',
    borderWidth: 1,
  },
  buttonSecondary: {
    backgroundColor: 'transparent',
    borderColor: '#353539',
    borderWidth: 1,
  },
  buttonText: {
    color: '#111111',
    fontSize: 12,
    fontWeight: '900',
  },
  buttonTextDanger: {
    color: '#FCA5A5',
  },
  buttonTextSecondary: {
    color: '#F4F4F5',
  },
  card: {
    backgroundColor: '#0B0B0C',
    borderColor: '#242427',
    borderRadius: 8,
    borderWidth: 1,
    marginBottom: 12,
    padding: 16,
  },
  cardHeader: {
    alignItems: 'flex-start',
    flexDirection: 'row',
  },
  channelBody: {
    color: '#D4D4D8',
    fontSize: 14,
    fontWeight: '600',
    lineHeight: 19,
    marginTop: 3,
  },
  channelIcon: {
    marginRight: 12,
    marginTop: 1,
  },
  channelText: {
    flex: 1,
    minWidth: 0,
  },
  channelTitle: {
    color: '#F4F4F5',
    fontSize: 16,
    fontWeight: '500',
  },
  cleanupBox: {
    backgroundColor: '#101012',
    borderColor: '#2A2A2A',
    borderRadius: 8,
    borderWidth: 1,
    marginTop: 12,
    padding: 11,
  },
  cleanupText: {
    color: '#A1A1AA',
    fontSize: 12,
    fontWeight: '600',
    lineHeight: 17,
  },
  codeLabel: {
    color: '#8E8E93',
    fontSize: 11,
    fontWeight: '900',
    textTransform: 'uppercase',
  },
  connectedBody: {
    color: '#A1A1AA',
    fontSize: 12,
    fontWeight: '700',
    marginTop: 4,
  },
  connectedBox: {
    backgroundColor: '#151515',
    borderColor: '#2A2A2A',
    borderRadius: 8,
    borderWidth: 1,
    marginTop: 12,
    padding: 12,
  },
  disabled: {
    opacity: 0.55,
  },
  errorText: {
    color: '#FCA5A5',
    fontSize: 12,
    fontWeight: '700',
    marginTop: 7,
  },
  expiryText: {
    color: '#71717A',
    fontSize: 11,
    fontWeight: '700',
    marginTop: 7,
  },
  helpText: {
    color: '#A1A1AA',
    fontSize: 12,
    fontWeight: '600',
    lineHeight: 17,
  },
  noticeSpacing: {
    marginTop: 12,
  },
  setupStack: {
    marginTop: 12,
  },
  slackHandle: {
    color: '#F4F4F5',
    fontFamily: 'Courier',
    fontSize: 15,
    fontWeight: '900',
    marginTop: 3,
  },
  slackHint: {
    color: '#71717A',
    fontSize: 11,
    fontWeight: '700',
    marginTop: 3,
  },
  slackWorkspaceStacked: {
    marginTop: 14,
  },
  statusConnected: {
    color: '#D4D4D8',
    fontSize: 14,
    fontWeight: '600',
  },
  statusDetail: {
    color: '#A1A1AA',
    fontSize: 14,
    fontWeight: '600',
  },
  statusDot: {
    backgroundColor: '#34D399',
    borderRadius: 4,
    height: 7,
    marginRight: 7,
    width: 7,
  },
  statusLine: {
    alignItems: 'center',
    flexDirection: 'row',
    marginTop: 4,
  },
});
