import { useState } from 'react';
import { router } from 'expo-router';
import { TextInput, View, Text, StyleSheet, Pressable } from 'react-native';
import { useTranslation } from 'react-i18next';
import { signupSchema } from '@navi/validators';
import { Screen } from '../../src/components/Screen';
import { PrimaryButton } from '../../src/components/PrimaryButton';
import { StateView } from '../../src/components/StateView';
import { NaviHeader } from '../../src/components/layout/NaviHeader';
import { api, ApiError } from '../../src/api/client';
import { clearFieldError, fieldErrorsFromIssues, summarizeFieldErrors, type FieldErrors } from '../../src/auth/formValidation';
import { useAuth } from '../../src/state/auth';
import { useLocale } from '../../src/state/locale';
import { color, radius, spacing, typography } from '../../src/theme';

type SignupField = 'fullName' | 'email' | 'phoneE164' | 'password' | 'acceptTerms';

export default function Signup() {
  const { t } = useTranslation();
  const locale = useLocale((s) => s.locale);
  const continueAsGuest = useAuth((s) => s.continueAsGuest);
  const [fullName, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [password, setPassword] = useState('');
  const [agreed, setAgreed] = useState(false);
  const [fieldErrors, setFieldErrors] = useState<FieldErrors<SignupField>>({});
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function onCreate() {
    setError(null);
    setFieldErrors({});
    const parsed = signupSchema.safeParse({
      fullName: fullName.trim(),
      email: email.trim().toLowerCase(),
      phoneE164: normalizePhone(phone),
      password,
      acceptTerms: agreed,
      locale,
    });
    if (!parsed.success) {
      const errors = fieldErrorsFromIssues<SignupField>(parsed.error.issues, {
        fullName: t('auth.fullName'),
        email: t('auth.email'),
        phoneE164: t('auth.phone'),
        password: t('auth.password'),
        acceptTerms: t('auth.terms'),
      });
      setFieldErrors(errors);
      setError(summarizeFieldErrors(errors));
      return;
    }
    setSubmitting(true);
    try {
      const signup = await api.auth.signup({
        fullName: parsed.data.fullName,
        email: parsed.data.email,
        phoneE164: parsed.data.phoneE164,
        password: parsed.data.password,
        acceptTerms: true,
        ...(parsed.data.locale ? { locale: parsed.data.locale } : {}),
      });
      const dev = signup.devCode ? `&devCode=${encodeURIComponent(signup.devCode)}` : '';
      router.replace(`/(auth)/otp/signup?email=${encodeURIComponent(parsed.data.email)}${dev}`);
    } catch (e) {
      if (e instanceof ApiError && e.status === 409) {
        setFieldErrors({ email: t('auth.emailRegistered') });
        setError(t('auth.emailRegistered'));
      }
      else if (e instanceof ApiError) setError(e.message);
      else setError(t('auth.networkError'));
    } finally {
      setSubmitting(false);
    }
  }

  async function onContinueAsGuest() {
    await continueAsGuest();
    router.replace('/(tabs)/home');
  }

  return (
    <Screen>
      <NaviHeader variant="center" title={t('auth.createAccount')} showBack onBack={() => router.replace('/(auth)/login')} />
      <Text style={styles.title}>{t('auth.createAccount')}</Text>
      <Text style={styles.subtitle}>{t('auth.enterDetails')}</Text>

      <Field
        label={t('auth.fullName')}
        value={fullName}
        onChange={(value) => {
          setName(value);
          setFieldErrors((current) => clearFieldError(current, 'fullName'));
        }}
        placeholder={t('auth.placeholderName')}
        error={fieldErrors.fullName}
      />
      <Field
        label={t('auth.email')}
        value={email}
        onChange={(value) => {
          setEmail(value);
          setFieldErrors((current) => clearFieldError(current, 'email'));
        }}
        placeholder={t('auth.placeholderEmail')}
        keyboard="email-address"
        error={fieldErrors.email}
      />
      <Field
        label={t('auth.phone')}
        value={phone}
        onChange={(value) => {
          setPhone(value);
          setFieldErrors((current) => clearFieldError(current, 'phoneE164'));
        }}
        placeholder={t('auth.placeholderPhone')}
        keyboard="phone-pad"
        error={fieldErrors.phoneE164}
      />
      <Field
        label={t('auth.password')}
        value={password}
        onChange={(value) => {
          setPassword(value);
          setFieldErrors((current) => clearFieldError(current, 'password'));
        }}
        placeholder={t('auth.placeholderPassword')}
        secure
        error={fieldErrors.password}
      />

      <Pressable
        style={styles.checkRow}
        onPress={() => {
          setAgreed((a) => !a);
          setFieldErrors((current) => clearFieldError(current, 'acceptTerms'));
        }}
        accessibilityRole="checkbox"
      >
        <View style={[styles.checkbox, agreed ? styles.checkOn : null]} />
        <Text style={styles.checkLabel}>{t('auth.agreeTerms')}</Text>
      </Pressable>
      {fieldErrors.acceptTerms ? <Text style={styles.fieldError}>{fieldErrors.acceptTerms}</Text> : null}

      {error ? <StateView tone="error" title={t('auth.createFailed')} body={error} /> : null}

      <PrimaryButton
        label={submitting ? t('states.loading') : t('auth.createAccount')}
        onPress={onCreate}
        disabled={submitting}
        rightIcon
      />
      <PrimaryButton
        label={t('actions.continueAsGuest')}
        variant="secondary"
        onPress={onContinueAsGuest}
        disabled={submitting}
      />
      <View style={styles.authRow}>
        <Text style={styles.muted}>{t('auth.haveAccount')} </Text>
        <Pressable onPress={() => router.push('/(auth)/login')} accessibilityRole="link">
          <Text style={styles.link}>{t('auth.logIn')}</Text>
        </Pressable>
      </View>
    </Screen>
  );
}

function normalizePhone(value: string): string {
  const compact = value.replace(/[^\d+]/g, '');
  return compact.startsWith('+') ? compact : `+${compact}`;
}

interface FieldProps {
  label: string;
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
  keyboard?: 'default' | 'email-address' | 'phone-pad';
  secure?: boolean;
  error?: string | undefined;
}

function Field({ label, value, onChange, placeholder, keyboard = 'default', secure, error }: FieldProps) {
  return (
    <View>
      <Text style={styles.label}>{label}</Text>
      <TextInput
        value={value}
        onChangeText={onChange}
        placeholder={placeholder}
        secureTextEntry={secure}
        keyboardType={keyboard}
        autoCapitalize="none"
        autoCorrect={false}
        style={[styles.input, error ? styles.inputError : null]}
      />
      {error ? <Text style={styles.fieldError}>{error}</Text> : null}
    </View>
  );
}

const styles = StyleSheet.create({
  title: { fontSize: typography.scale.h1.size, fontWeight: '700', color: color.ink[900] },
  subtitle: { fontSize: typography.scale.body.size, color: color.ink[500] },
  label: { fontSize: typography.scale.caption.size, color: color.ink[700], marginTop: spacing[3] },
  input: {
    height: 52,
    borderRadius: radius.md,
    borderWidth: 1,
    borderColor: color.border,
    paddingHorizontal: spacing[4],
    backgroundColor: color.bg[0],
    fontSize: typography.scale.body.size,
  },
  inputError: { borderColor: color.danger },
  fieldError: { color: color.danger, fontSize: typography.scale.caption.size, marginTop: spacing[1] },
  checkRow: { flexDirection: 'row', alignItems: 'center', gap: spacing[3], marginTop: spacing[3] },
  checkbox: { width: 22, height: 22, borderRadius: 6, borderWidth: 1, borderColor: color.border },
  checkOn: { backgroundColor: color.blue[600], borderColor: color.blue[600] },
  checkLabel: { color: color.ink[700], flex: 1, lineHeight: 20 },
  authRow: { flexDirection: 'row', justifyContent: 'center', marginTop: spacing[4] },
  muted: { color: color.ink[500] },
  link: { color: color.blue[600], fontWeight: '600' },
});
