import { scrollViewWebProps } from '@/lib/ui/scroll-props';
import { useState } from "react";
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TextInput,
  ScrollView,
  Platform,
  ActivityIndicator,
  Alert,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useRouter, Stack } from "expo-router";
import {
  ChevronLeft,
  CreditCard,
  Building2,
  CheckCircle2,
  DollarSign,
} from "lucide-react-native";
import Colors from "@/constants/colors";
import { trpc } from "@/lib/trpc";
import { useAuth } from "@/lib/auth-context";
import { parseMoneyInput, sanitizeMoneyInput } from "@/lib/utils/money-input";
import { toUserSafeErrorMessage } from "@/lib/utils/alert";
import { isNetworkAvailable } from "@/lib/utils/network-guard";
import { withRetry } from "@/lib/network/resilience";

const DEMO_PAYMENT_METHODS = [
  { id: "demo-card-1", type: "card" as const, label: "Visa •••• 4242", isPrimary: true, brand: "Visa", last4: "4242" },
];

const DEMO_BANK_ACCOUNTS = [
  { id: "demo-bank-1", type: "bank" as const, label: "Chase •••• 1234", isPrimary: true, bankName: "Chase", last4: "1234" },
];

export default function AddMoneyScreen() {
  const insets = useSafeAreaInsets();
  const router = useRouter();
  const { isDemoMode } = useAuth();
  const [amount, setAmount] = useState("");
  const [selectedMethod, setSelectedMethod] = useState<string | null>(null);

  const paymentMethodsQuery = trpc.paymentMethods.list.useQuery(undefined, { enabled: !isDemoMode });
  const bankAccountsQuery = trpc.banking.getAccounts.useQuery(undefined, { enabled: !isDemoMode });
  const queueDepositMutation = trpc.railways.queueDeposit.useMutation();
  const queueCardDepositMutation = trpc.railways.queueCardDeposit.useMutation();
  const [isSubmitting, setIsSubmitting] = useState(false);

  const paymentMethods = isDemoMode ? DEMO_PAYMENT_METHODS : (paymentMethodsQuery.data || []);
  const bankAccounts = isDemoMode ? DEMO_BANK_ACCOUNTS : (bankAccountsQuery.data || []);

  const allMethods = [
    ...paymentMethods.map((pm) => ({
      id: pm.id,
      type: "card" as const,
      label: `${pm.brand || "Card"} •••• ${pm.last4}`,
      isPrimary: pm.isPrimary,
    })),
    ...bankAccounts.map((ba) => ({
      id: ba.id,
      type: "bank" as const,
      label: `${ba.bankName} •••• ${ba.last4}`,
      isPrimary: ba.isPrimary,
    })),
  ];

  const handleAmountChange = (text: string) => {
    setAmount(sanitizeMoneyInput(text));
  };

  const handleAddMoney = async () => {
    if (isSubmitting) return;
    const amountNum = parseMoneyInput(amount);
    if (amountNum === null || amountNum <= 0) {
      Alert.alert("Invalid Amount", "Please enter a valid amount");
      return;
    }
    if (!selectedMethod) {
      Alert.alert("No Payment Method", "Please select a payment method");
      return;
    }

    if (isDemoMode) {
      Alert.alert("Unavailable", "Demo mode is disabled. Sign in with a real account to add funds.");
      return;
    }

    const online = await isNetworkAvailable();
    if (!online) {
      Alert.alert("Offline", "You appear to be offline. Reconnect and try again.");
      return;
    }

    const selected = allMethods.find((m) => m.id === selectedMethod);
    if (!selected) {
      Alert.alert("No Payment Method", "Please select a payment method");
      return;
    }

    setIsSubmitting(true);
    try {
      if (selected.type === "card") {
        await withRetry(
          () =>
            queueCardDepositMutation.mutateAsync({
              amount: amountNum,
              paymentMethodId: selected.id,
            }),
          { maxRetries: 2, baseDelayMs: 700, maxDelayMs: 4000 }
        );
        Alert.alert("Money Added", `$${amountNum.toFixed(2)} added to your Zendo balance.`);
      } else {
        const result = await withRetry(
          () =>
            queueDepositMutation.mutateAsync({
              amount: amountNum,
              bankAccountId: selected.id,
            }),
          { maxRetries: 2, baseDelayMs: 700, maxDelayMs: 4000 }
        );

        if (result.status === "COMPLETED") {
          Alert.alert("Money Added", `$${amountNum.toFixed(2)} added to your Zendo balance.`);
        } else {
          Alert.alert(
            "Deposit Initiated",
            `Your $${amountNum.toFixed(2)} ACH deposit is processing via Moov (typically 1–3 business days). ` +
              `Funds will appear in your balance after the transfer clears.`
          );
        }
      }

      paymentMethodsQuery.refetch();
      bankAccountsQuery.refetch();
      router.back();
    } catch (error) {
      Alert.alert("Couldn't Add Funds", toUserSafeErrorMessage(error, "Please try again."));
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <View style={[styles.container, { paddingTop: insets.top }]}>
      <Stack.Screen options={{ headerShown: false }} />

      <View style={styles.header}>
        <TouchableOpacity
          onPress={() => router.back()}
          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
        >
          <ChevronLeft color={Colors.dark.text} size={24} />
        </TouchableOpacity>
        <Text style={styles.headerTitle}>Add Money</Text>
        <View style={{ width: 24 }} />
      </View>

      <ScrollView
        style={styles.scrollView}
        contentContainerStyle={styles.scrollContent}
        showsVerticalScrollIndicator={scrollViewWebProps.showsVerticalScrollIndicator}
      >
        <View style={styles.disclosureCard}>
          <Text style={styles.disclosureTitle}>Zendo Ledger</Text>
          <Text style={styles.disclosureText}>
            Your Zendo balance is stored value tracked on Zendo&apos;s internal ledger — not a bank account. It is not
            FDIC insured. Card and bank deposits credit your balance on the ledger. P2P transfers between Zendo users are instant and free.
          </Text>
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionLabel}>Amount</Text>
          <View style={styles.amountInputContainer}>
            <DollarSign color={Colors.dark.textSecondary} size={32} />
            <TextInput
              style={styles.amountInput}
              value={amount}
              onChangeText={handleAmountChange}
              placeholder="0.00"
              placeholderTextColor={Colors.dark.textTertiary}
              keyboardType="decimal-pad"
            />
          </View>
        </View>

        <View style={styles.quickAmounts}>
          {[10, 25, 50, 100].map((amt) => (
            <TouchableOpacity
              key={amt}
              style={styles.quickAmountButton}
              onPress={() => setAmount(amt.toString())}
            >
              <Text style={styles.quickAmountText}>${amt}</Text>
            </TouchableOpacity>
          ))}
        </View>

        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text style={styles.sectionLabel}>Payment Method</Text>
            <TouchableOpacity
              onPress={() => router.push("/settings/bank-accounts")}
            >
              <Text style={styles.addNewButton}>+ Link via Moov</Text>
            </TouchableOpacity>
          </View>

          {(paymentMethodsQuery.isLoading || bankAccountsQuery.isLoading) && !isDemoMode ? (
            <ActivityIndicator size="small" color={Colors.dark.primary} />
          ) : allMethods.length > 0 ? (
            allMethods.map((method) => {
              const Icon = method.type === "card" ? CreditCard : Building2;
              return (
                <TouchableOpacity
                  key={method.id}
                  style={[
                    styles.methodCard,
                    selectedMethod === method.id && styles.methodCardSelected,
                  ]}
                  onPress={() => setSelectedMethod(method.id)}
                >
                  <View style={styles.methodIcon}>
                    <Icon color={Colors.dark.primary} size={24} />
                  </View>
                  <View style={styles.methodInfo}>
                    <Text style={styles.methodLabel}>{method.label}</Text>
                    {method.isPrimary && (
                      <Text style={styles.methodPrimary}>Default</Text>
                    )}
                  </View>
                  {selectedMethod === method.id && (
                    <CheckCircle2 color={Colors.dark.primary} size={24} />
                  )}
                </TouchableOpacity>
              );
            })
          ) : (
            <View style={styles.emptyContainer}>
              <Text style={styles.emptyText}>
                No payment methods added yet
              </Text>
              <TouchableOpacity
                style={styles.addButton}
                onPress={() => router.push("/settings/cards")}
              >
                <Text style={styles.addButtonText}>Add Payment Method</Text>
              </TouchableOpacity>
            </View>
          )}
        </View>

        <View style={styles.infoBox}>
          <Text style={styles.infoText}>
            Card deposits are credited instantly to your Zendo balance. Bank deposits typically clear in 1–3 business
            days. Standard processing fees may apply.
          </Text>
        </View>
      </ScrollView>

      <View style={[styles.footer, { paddingBottom: insets.bottom + 20 }]}>
        <TouchableOpacity
          style={[
            styles.submitButton,
            (!amount || !selectedMethod || isSubmitting) && styles.submitButtonDisabled,
          ]}
          onPress={handleAddMoney}
          disabled={!amount || !selectedMethod || isSubmitting}
        >
          {isSubmitting ? (
            <ActivityIndicator size="small" color={Colors.dark.background} />
          ) : (
            <Text style={styles.submitButtonText}>
              Add ${amount || "0.00"}
            </Text>
          )}
        </TouchableOpacity>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: Colors.dark.background,
  },
  header: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    paddingHorizontal: 20,
    paddingVertical: 16,
    borderBottomWidth: 1,
    borderBottomColor: Colors.dark.border,
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: "700" as const,
    color: Colors.dark.text,
  },
  scrollView: {
    flex: 1,
  },
  scrollContent: {
    padding: 20,
    gap: 24,
  },
  section: {
    gap: 16,
  },
  sectionHeader: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  sectionLabel: {
    fontSize: 13,
    fontWeight: "700" as const,
    color: Colors.dark.textSecondary,
    textTransform: "uppercase",
    letterSpacing: 0.5,
  },
  addNewButton: {
    fontSize: 14,
    fontWeight: "600" as const,
    color: Colors.dark.primary,
  },
  amountInputContainer: {
    flexDirection: "row",
    alignItems: "center",
    backgroundColor: Colors.dark.surface,
    padding: 24,
    borderRadius: 20,
    borderWidth: 2,
    borderColor: Colors.dark.border,
  },
  amountInput: {
    flex: 1,
    fontSize: 48,
    fontWeight: "700" as const,
    color: Colors.dark.text,
    marginLeft: 8,
    ...Platform.select({
      web: {
        outlineStyle: "none" as const,
      },
    }),
  },
  quickAmounts: {
    flexDirection: "row",
    gap: 12,
  },
  quickAmountButton: {
    flex: 1,
    backgroundColor: Colors.dark.surface,
    paddingVertical: 14,
    borderRadius: 12,
    alignItems: "center",
    borderWidth: 1,
    borderColor: Colors.dark.border,
  },
  quickAmountText: {
    fontSize: 16,
    fontWeight: "600" as const,
    color: Colors.dark.text,
  },
  methodCard: {
    flexDirection: "row",
    alignItems: "center",
    backgroundColor: Colors.dark.surface,
    padding: 16,
    borderRadius: 16,
    borderWidth: 2,
    borderColor: Colors.dark.border,
    gap: 12,
  },
  methodCardSelected: {
    borderColor: Colors.dark.primary,
  },
  methodIcon: {
    width: 48,
    height: 48,
    borderRadius: 24,
    backgroundColor: `${Colors.dark.primary}20`,
    justifyContent: "center",
    alignItems: "center",
  },
  methodInfo: {
    flex: 1,
  },
  methodLabel: {
    fontSize: 16,
    fontWeight: "600" as const,
    color: Colors.dark.text,
  },
  methodPrimary: {
    fontSize: 12,
    color: Colors.dark.textSecondary,
    marginTop: 2,
  },
  emptyContainer: {
    alignItems: "center",
    padding: 40,
    gap: 16,
  },
  emptyText: {
    fontSize: 14,
    color: Colors.dark.textSecondary,
    textAlign: "center",
  },
  addButton: {
    backgroundColor: Colors.dark.primary,
    paddingHorizontal: 24,
    paddingVertical: 12,
    borderRadius: 12,
  },
  addButtonText: {
    fontSize: 14,
    fontWeight: "600" as const,
    color: Colors.dark.background,
  },
  infoBox: {
    backgroundColor: `${Colors.dark.primary}10`,
    padding: 16,
    borderRadius: 12,
  },
  disclosureCard: {
    backgroundColor: Colors.dark.surface,
    borderWidth: 1,
    borderColor: Colors.dark.border,
    padding: 16,
    borderRadius: 12,
    marginBottom: 8,
  },
  disclosureTitle: {
    fontSize: 13,
    fontWeight: "700" as const,
    color: Colors.dark.text,
    marginBottom: 6,
  },
  disclosureText: {
    fontSize: 12,
    color: Colors.dark.textSecondary,
    lineHeight: 18,
  },
  infoText: {
    fontSize: 13,
    color: Colors.dark.textSecondary,
    lineHeight: 18,
  },
  footer: {
    paddingHorizontal: 20,
    paddingTop: 16,
    borderTopWidth: 1,
    borderTopColor: Colors.dark.border,
  },
  submitButton: {
    backgroundColor: Colors.dark.primary,
    paddingVertical: 18,
    borderRadius: 16,
    alignItems: "center",
  },
  submitButtonDisabled: {
    opacity: 0.5,
  },
  submitButtonText: {
    fontSize: 18,
    fontWeight: "700" as const,
    color: Colors.dark.background,
  },
});
