import React, { useMemo, useState } from 'react';
import { Linking, Pressable, Text, TextInput, View } from 'react-native';
import { CreditCard } from 'lucide-react-native';

import { conversationStyles } from '../../features/conversation/conversationStyles';
import { themedColor } from '../../theme';
import type { SuperagentToolRendererProps } from '../../types';
import {
  configurePspCredentialsTitle,
  getPspProcessorName,
  getPspSchema,
  isSecretPspField,
  normalizePspFields,
  pspCredentialsErrorMessage,
  sanitizeHttpUrl,
  showsPspForm,
  type PspField,
} from '../interactiveWidgetUtils';
import { ApprovalCard } from '../primitives/ApprovalCard';
import { toolWidgetStyles } from '../primitives/toolWidgetStyles';
import { getWidgetStatus, parseToolArgs } from '../toolWidgetUtils';
import { useApprovalSubmit } from '../useApprovalSubmit';
import { FallbackActionCard, SelectableOptionRow, StatusRowWithError } from './interactiveWidgetParts';

/**
 * configure_psp_credentials — native port of the web ConfigurePspCredentials
 * form. Connect submits the field values as the user_input (approve), Skip
 * submits {skipped: true} (also approve — the backend resolves skip as
 * success). Secret fields (Wix type PASSWORD) are masked and autofill is
 * suppressed; credential values are never echoed anywhere else. Required-only
 * validation, matching the web (validation_pattern is model-controlled and
 * running it client-side is a ReDoS vector — the backend re-validates). The
 * form renders for waiting AND error (the backend keeps this tool submittable
 * on error for in-place retry — web showForm parity, with the failure reason
 * shown above the fields), gated on isLastAssistantMessage so a stale card
 * can't resume an old turn out of order.
 */
export function ConfigurePspCredentialsWidget({ isLastAssistantMessage, submitToolCallInput, toolCall }: SuperagentToolRendererProps) {
  const args = useMemo(() => parseToolArgs(toolCall), [toolCall]);
  const fields = useMemo(() => normalizePspFields(args), [args]);
  const status = getWidgetStatus(toolCall.status);
  const { canAct, error, isSubmitting, submit } = useApprovalSubmit(toolCall, submitToolCallInput);
  const [values, setValues] = useState<Record<string, string>>({});
  const processorName = getPspProcessorName(args);
  const resultError = status === 'error' ? pspCredentialsErrorMessage(toolCall.results, processorName) : null;

  if (showsPspForm(status, isLastAssistantMessage)) {
    if (fields.length === 0) {
      return (
        <FallbackActionCard
          buttonLabel="Continue without connecting"
          error={error}
          isSubmitting={isSubmitting}
          message={resultError ??
            (`We couldn't load the credential fields for ${processorName}. You can complete ` +
              "the connection from the Payments dashboard (the Payments button in your app's " +
              'dashboard) when you have the correct details.')}
          onPress={canAct ? () => submit(true, { skipped: true }) : undefined}
        />
      );
    }

    const schema = getPspSchema(args);
    const allFilled = fields.every((field) => (values[field.name] ?? '').trim().length > 0);

    return (
      <ApprovalCard
        approveDisabled={!allFilled}
        approveLabel="Connect"
        error={error}
        isSubmitting={isSubmitting}
        onApprove={canAct ? () => submit(true, values) : undefined}
        onReject={canAct ? () => submit(true, { skipped: true }) : undefined}
        rejectLabel="Skip for now"
        title={`Connect ${processorName}`}
      >
        <View style={toolWidgetStyles.widgetBodyGap}>
          <Text style={toolWidgetStyles.interactiveBodyText}>
            Enter your {processorName} credentials to activate payments.
          </Text>
          {resultError ? <Text style={conversationStyles.toolApprovalError}>{resultError}</Text> : null}
          {fields.map((field) => (
            <PspFieldInput
              field={field}
              isSubmitting={isSubmitting}
              key={field.name}
              onChange={(value) => setValues((current) => ({ ...current, [field.name]: value }))}
              value={values[field.name] ?? ''}
            />
          ))}
          <PspLink label={`New to ${processorName}? Create an account`} url={sanitizeHttpUrl(schema?.signup_url)} />
          <PspLink label={`Need help? Contact ${processorName} support`} url={sanitizeHttpUrl(schema?.support_url)} />
        </View>
      </ApprovalCard>
    );
  }

  return (
    <StatusRowWithError
      errorMessage={resultError}
      icon={CreditCard}
      status={status}
      title={configurePspCredentialsTitle(status, toolCall.results, processorName)}
    />
  );
}

function PspFieldInput({
  field,
  isSubmitting,
  onChange,
  value,
}: {
  field: PspField;
  isSubmitting: boolean;
  onChange: (value: string) => void;
  value: string;
}) {
  return (
    <View style={conversationStyles.toolApprovalInputGroup}>
      <Text style={conversationStyles.toolApprovalInputLabel}>{field.label} *</Text>
      {field.options.length > 0 ? (
        <View style={toolWidgetStyles.optionList}>
          {field.options.map((option) => (
            <SelectableOptionRow
              disabled={isSubmitting}
              key={option.value}
              label={option.label}
              onPress={() => onChange(option.value)}
              selected={value === option.value}
            />
          ))}
        </View>
      ) : (
        <TextInput
          autoCapitalize="none"
          autoComplete="off"
          autoCorrect={false}
          editable={!isSubmitting}
          importantForAutofill="no"
          keyboardType={field.name.toLowerCase().includes('email') ? 'email-address' : 'default'}
          onChangeText={onChange}
          placeholder={`Enter ${field.label}`}
          placeholderTextColor={themedColor('#6F6F76')}
          secureTextEntry={isSecretPspField(field)}
          style={conversationStyles.toolApprovalInput}
          value={value}
        />
      )}
    </View>
  );
}

function PspLink({ label, url }: { label: string; url: string | null }) {
  if (!url) return null;
  return (
    <Pressable accessibilityRole="link" onPress={() => { void Linking.openURL(url); }}>
      <Text style={toolWidgetStyles.linkText}>{label}</Text>
    </Pressable>
  );
}
