import { useCallback, useEffect, useState } from 'react';

import { Pressable, StyleSheet, Text, View } from 'react-native';

import api from '../../core/api';

import { extractApiError } from '../../core/getApiBaseUrl';

import type { CaptchaState } from '../../core/captcha';

import { FormField } from '../ui/FormField';

import { AppButton } from '../ui/AppButton';

import { colors, spacing } from '../../constants/theme';



type CaptchaOption = { value: string; label: string };



type Props = {

  context: 'login' | 'register' | 'verify' | 'forgot_password' | 'customer_onboard';

  value: CaptchaState;

  onChange: (value: CaptchaState) => void;

};



export function CaptchaField({ context, value, onChange }: Props) {

  const [loading, setLoading] = useState(true);

  const [error, setError] = useState('');

  const [question, setQuestion] = useState('');

  const [hint, setHint] = useState('');

  const [options, setOptions] = useState<CaptchaOption[]>([]);

  const [answer, setAnswer] = useState('');

  const [token, setToken] = useState('');



  const syncAnswer = useCallback(

    (nextAnswer: string, nextToken: string, enabled: boolean, provider: CaptchaState['provider']) => {

      if (!enabled || provider === 'disabled') {

        onChange({ enabled: false, provider: 'disabled' });

        return;

      }

      onChange({

        enabled: true,

        provider: provider || 'local',

        captcha_token: nextToken,

        captcha_answer: nextAnswer,

      });

    },

    [onChange],

  );



  const load = useCallback(async () => {

    setLoading(true);

    setError('');

    try {

      const { data } = await api.get('/auth/captcha', {

        params: { context, provider: 'local' },

      });

      if (!data.enabled || data.provider === 'disabled') {

        syncAnswer('', '', false, 'disabled');

        return;

      }

      if (data.provider === 'recaptcha') {

        onChange({ enabled: true, provider: 'recaptcha' });

        setError('reCAPTCHA is enabled. Use the web app or ask admin to use math captcha for mobile.');

        return;

      }

      setQuestion(data.question || 'Solve the challenge');

      setHint(data.hint || '');

      setOptions(Array.isArray(data.options) ? data.options : []);

      const nextToken = data.captcha_token || '';

      setToken(nextToken);

      setAnswer('');

      syncAnswer('', nextToken, true, 'local');

    } catch (e) {

      setError(extractApiError(e));

      onChange({ enabled: false });

    } finally {

      setLoading(false);

    }

  }, [context, onChange, syncAnswer]);



  useEffect(() => {

    load();

  }, [load]);



  const selectOption = (optionValue: string) => {

    setAnswer(optionValue);

    syncAnswer(optionValue, token, true, 'local');

  };



  const onTextAnswer = (text: string) => {

    setAnswer(text);

    if (token) {

      syncAnswer(text, token, true, 'local');

    }

  };



  if (loading) {

    return <Text style={styles.muted}>Loading security check…</Text>;

  }



  if (!value.enabled || value.provider === 'disabled') {

    return null;

  }



  return (

    <View style={styles.wrap}>

      <Text style={styles.label}>Security check</Text>

      <Text style={styles.question}>{question}</Text>

      {hint ? <Text style={styles.hint}>{hint}</Text> : null}



      {options.length > 0 ? (

        <View style={styles.options} accessibilityRole="radiogroup">

          {options.map((option) => {

            const selected = answer === option.value;

            return (

              <Pressable

                key={option.value}

                style={[styles.option, selected && styles.optionSelected]}

                onPress={() => selectOption(option.value)}

              >

                <Text style={[styles.optionText, selected && styles.optionTextSelected]}>{option.label}</Text>

              </Pressable>

            );

          })}

        </View>

      ) : (

        <FormField

          field={{ key: 'captcha', label: 'Your answer', required: true }}

          value={answer}

          onChange={(v) => onTextAnswer(String(v))}

        />

      )}



      <AppButton label="New question" icon="refresh" variant="secondary" onPress={load} />

      {error ? <Text style={styles.error}>{error}</Text> : null}

    </View>

  );

}



const styles = StyleSheet.create({

  wrap: { marginBottom: spacing.md },

  label: { fontWeight: '600', color: colors.text, marginBottom: spacing.xs },

  question: { fontSize: 16, color: colors.text, marginBottom: spacing.xs },

  hint: { fontSize: 13, color: colors.textMuted, marginBottom: spacing.sm },

  options: { flexDirection: 'row', flexWrap: 'wrap', gap: spacing.sm, marginBottom: spacing.md },

  option: {

    paddingHorizontal: 14,

    paddingVertical: 10,

    borderRadius: 8,

    borderWidth: 1,

    borderColor: colors.border,

    backgroundColor: colors.surface,

  },

  optionSelected: {

    borderColor: colors.primary,

    backgroundColor: colors.primaryLight,

  },

  optionText: { color: colors.text, fontSize: 15 },

  optionTextSelected: { color: colors.primaryDark, fontWeight: '600' },

  muted: { color: colors.textMuted, marginBottom: spacing.md },

  error: { color: colors.danger, marginTop: spacing.sm },

});

