import React, { type ReactNode } from 'react';
import { ActivityIndicator, Image, Pressable, Text, View } from 'react-native';
import { Check, type LucideIcon } from 'lucide-react-native';

import { conversationStyles } from '../../features/conversation/conversationStyles';
import { themedColor } from '../../theme';
import { ToolWidgetRow } from '../primitives/ToolWidgetRow';
import { WidgetCard } from '../primitives/WidgetCard';
import { toolWidgetStyles } from '../primitives/toolWidgetStyles';
import type { ToolWidgetStatus } from '../toolWidgetUtils';

/**
 * Shared building blocks for the interactive widgets (clarifying questions,
 * agent permissions, payments) — the option rows, buttons and fallback/status
 * surfaces they all render.
 */

/** Radio/checkbox option row (clarifying options, provider picker, PSP selects). */
export function SelectableOptionRow({
  centered = false,
  children,
  disabled,
  imageUrl,
  label,
  multi = false,
  onPress,
  selected,
  subtitle,
}: {
  /** Centers the indicator against the whole row instead of the label's first line. */
  centered?: boolean;
  children?: ReactNode;
  disabled: boolean;
  imageUrl?: string | null;
  /** Omit to let `children` (e.g. an inline input) stand in for the label instead. */
  label?: string;
  multi?: boolean;
  onPress: () => void;
  selected: boolean;
  subtitle?: string | null;
}) {
  return (
    <Pressable
      accessibilityRole={multi ? 'checkbox' : 'radio'}
      accessibilityState={multi ? { checked: selected } : { selected }}
      disabled={disabled}
      onPress={onPress}
      style={[
        toolWidgetStyles.optionRow,
        centered && toolWidgetStyles.optionRowCentered,
        selected && toolWidgetStyles.optionRowSelected,
      ]}
    >
      {multi ? (
        // approvalCheckbox's marginTop is tuned for EntityApprovalBatchCard's rows;
        // here the 20px box already lines up with the 18px label line, so drop it.
        <View style={[toolWidgetStyles.approvalCheckbox, { marginTop: 0 }, selected && toolWidgetStyles.approvalCheckboxChecked]}>
          {selected ? <Check color={themedColor('#111111')} size={14} strokeWidth={3} /> : null}
        </View>
      ) : (
        <View style={[toolWidgetStyles.radioOuter, selected && toolWidgetStyles.radioOuterSelected]}>
          {selected ? <View style={toolWidgetStyles.radioInner} /> : null}
        </View>
      )}
      <View style={toolWidgetStyles.optionBody}>
        {label ? <Text style={toolWidgetStyles.optionLabel}>{label}</Text> : null}
        {subtitle ? <Text style={toolWidgetStyles.optionSubtitle}>{subtitle}</Text> : null}
        {imageUrl ? <Image resizeMode="cover" source={{ uri: imageUrl }} style={toolWidgetStyles.optionImage} /> : null}
        {children}
      </View>
    </Pressable>
  );
}

export function WidgetActionButton({
  disabled,
  isSubmitting,
  label,
  onPress,
  primary = false,
  small = false,
}: {
  disabled: boolean;
  isSubmitting: boolean;
  label: string;
  onPress: () => void;
  primary?: boolean;
  /** DS Button size="sm" instead of the default taller approval-card button. */
  small?: boolean;
}) {
  return (
    <Pressable
      accessibilityRole="button"
      disabled={disabled}
      onPress={onPress}
      style={[
        primary ? conversationStyles.toolApprovalPrimaryButton : conversationStyles.toolApprovalSecondaryButton,
        small && toolWidgetStyles.widgetButtonSmall,
        disabled && conversationStyles.toolApprovalButtonDisabled,
      ]}
    >
      {isSubmitting ? <ActivityIndicator color={themedColor(primary ? '#111111' : '#F4F4F5')} size="small" /> : null}
      <Text
        style={[
          primary ? conversationStyles.toolApprovalPrimaryText : conversationStyles.toolApprovalSecondaryText,
          small && toolWidgetStyles.widgetButtonSmallLabel,
        ]}
      >
        {label}
      </Text>
    </Pressable>
  );
}

/**
 * Card with a message and a single action — the web's amber fallback panels
 * (choices/fields failed to load) and the clarifying "couldn't generate
 * questions" state.
 */
export function FallbackActionCard({
  buttonLabel,
  error,
  isSubmitting,
  message,
  onPress,
}: {
  buttonLabel: string;
  error?: string | null;
  isSubmitting: boolean;
  message: string;
  onPress?: () => void;
}) {
  return (
    <WidgetCard>
      <Text style={toolWidgetStyles.interactiveBodyText}>{message}</Text>
      <View style={toolWidgetStyles.wizardNavRow}>
        <View />
        <WidgetActionButton
          disabled={!onPress || isSubmitting}
          isSubmitting={isSubmitting}
          label={buttonLabel}
          onPress={onPress ?? (() => {})}
        />
      </View>
      {error ? <Text style={conversationStyles.toolApprovalError}>{error}</Text> : null}
    </WidgetCard>
  );
}

/** Resolved-state row with the tool's error message underneath (PSP widgets). */
export function StatusRowWithError({
  errorMessage,
  icon,
  status,
  title,
}: {
  errorMessage: string | null;
  icon: LucideIcon;
  status: ToolWidgetStatus;
  title: string;
}) {
  return (
    <View>
      <ToolWidgetRow icon={icon} status={status} title={title} />
      {errorMessage ? <Text style={conversationStyles.toolApprovalError}>{errorMessage}</Text> : null}
    </View>
  );
}

/** DS tiny ghost icon button (pager chevrons, the clarifying card's minimize toggle). */
export function TinyIconButton({
  accessibilityLabel,
  disabled,
  icon: Icon,
  onPress,
}: {
  accessibilityLabel: string;
  disabled: boolean;
  icon: LucideIcon;
  onPress: () => void;
}) {
  return (
    <Pressable
      accessibilityLabel={accessibilityLabel}
      accessibilityRole="button"
      accessibilityState={{ disabled }}
      disabled={disabled}
      hitSlop={10} // the DS tiny 24px control is under the mobile touch-target minimum
      onPress={onPress}
      style={[toolWidgetStyles.widgetIconButtonTiny, disabled && conversationStyles.toolApprovalButtonDisabled]}
    >
      <Icon color={themedColor('#D4D4D8')} size={18} />
    </Pressable>
  );
}
