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,
  Building2,
  CheckCircle2,
  DollarSign,
  Zap,
} from "lucide-react-native";
import Colors from "@/constants/colors";
import { trpc } from "@/lib/trpc";
import { useAuth } from "@/lib/auth-context";
import { LedgerBalanceCard } from "@/components/LedgerBalanceCard";
import { useLedgerSummary } from "@/lib/hooks/use-ledger-summary";
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";
import { getInstantWithdrawalTotals } from "@/lib/utils/instant-withdrawal-fee";

const DEMO_BANK_ACCOUNTS = [
  { id: "demo-bank-1", bankName: "Chase", last4: "1234", isPrimary: true },
  { id: "demo-bank-2", bankName: "Bank of America", last4: "5678", isPrimary: false },
];

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

  const bankAccountsQuery = trpc.banking.getAccounts.useQuery(undefined, { enabled: !isDemoMode });
  const { availableBalance, pendingHolds, refetch: refetchLedger } = useLedgerSummary({ enabled: !isDemoMode });
  const queueWithdrawMutation = trpc.railways.queueWithdraw.useMutation();
  const [isInstant, setIsInstant] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const bankAccounts = isDemoMode ? DEMO_BANK_ACCOUNTS : (bankAccountsQuery.data || []);

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

  const handleCashOut = async () => {
    if (isSubmitting) return;
    const amountNum = parseMoneyInput(amount);
    if (amountNum === null || amountNum <= 0) {
      Alert.alert("Invalid Amount", "Please enter a valid amount");
      return;
    }
    const spendable = isDemoMode ? (user?.balance ?? 0) : availableBalance;
    const withdrawTotals = isInstant
      ? getInstantWithdrawalTotals(amountNum)
      : { payoutAmount: amountNum, zendoFee: 0, totalDebit: amountNum };
    const totalDue = withdrawTotals.totalDebit;
    if (totalDue > spendable) {
      const holdNote =
        !isDemoMode && pendingHolds > 0
          ? ` You have $${pendingHolds.toFixed(2)} in pending card holds reducing your available balance.`
          : "";
      Alert.alert(
        "Insufficient Balance",
        `You can withdraw up to $${spendable.toFixed(2)}.${holdNote}`
      );
      return;
    }
    if (!selectedAccount) {
      Alert.alert("No Bank Account", "Please select a bank account");
      return;
    }

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

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

    setIsSubmitting(true);
    try {
      const result = await withRetry(
        () =>
          queueWithdrawMutation.mutateAsync({
            amount: amountNum,
            bankAccountId: selectedAccount,
            isInstant,
          }),
        { maxRetries: 2, baseDelayMs: 700, maxDelayMs: 4000 }
      );

      const feeAmount = result.feeAmount ?? 0;
      const net = result.netAmount ?? amountNum - feeAmount;
      const arrival = isInstant
        ? "Instant (minutes)"
        : "Standard Moov ACH — 1–3 business days, no fee";

      Alert.alert(
        "Withdrawal Started",
        isInstant
          ? `$${payoutAmount.toFixed(2)} is on its way. Zendo instant fee: $${feeAmount.toFixed(2)} (total $${(payoutAmount + feeAmount).toFixed(2)} from balance).`
          : `${arrival}. You'll receive $${net.toFixed(2)}.`
      );
      refetchLedger();
      router.back();
    } catch (error) {
      Alert.alert("Couldn't Withdraw", toUserSafeErrorMessage(error, "Please try again."));
    } finally {
      setIsSubmitting(false);
    }
  };

  const safeAmount = parseMoneyInput(amount) ?? 0;
  const instantTotals = safeAmount > 0 ? getInstantWithdrawalTotals(safeAmount) : null;
  const instantFee = instantTotals?.zendoFee ?? 0;
  const totalDebit = instantTotals?.totalDebit ?? safeAmount;
  const payoutAmount = safeAmount;

  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}>Cash Out</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 Withdrawals</Text>
          <Text style={styles.disclosureText}>
            Withdrawals move funds to your linked bank via Zendo&apos;s payout rail. Zendo never stores
            business or user bank account numbers on its servers. Standard payouts are free;
            instant payouts include a Zendo fee (3¢ min, 1% max).
          </Text>
        </View>

        {!isDemoMode && <LedgerBalanceCard variant="compact" />}

        {isDemoMode && (
          <View style={styles.balanceCard}>
            <Text style={styles.balanceLabel}>Available Balance</Text>
            <Text style={styles.balanceAmount}>${user?.balance.toFixed(2) || "0.00"}</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}>
          {[25, 50, 100, user?.balance || 0].map((amt, idx) => (
            <TouchableOpacity
              key={idx}
              style={styles.quickAmountButton}
              onPress={() => setAmount(amt.toFixed(2))}
            >
              <Text style={styles.quickAmountText}>
                {idx === 3 ? "All" : `$${amt}`}
              </Text>
            </TouchableOpacity>
          ))}
        </View>

        <View style={styles.section}>
          <Text style={styles.sectionLabel}>Transfer Speed</Text>
          
          <TouchableOpacity
            style={[
              styles.speedCard,
              !isInstant && styles.speedCardSelected,
            ]}
            onPress={() => setIsInstant(false)}
          >
            <Building2 color={Colors.dark.primary} size={24} />
            <View style={styles.speedInfo}>
              <Text style={styles.speedTitle}>Standard (Free)</Text>
              <Text style={styles.speedDescription}>
                Arrives in 1-3 business days
              </Text>
            </View>
            {!isInstant && (
              <CheckCircle2 color={Colors.dark.primary} size={24} />
            )}
          </TouchableOpacity>

          <TouchableOpacity
            style={[
              styles.speedCard,
              isInstant && styles.speedCardSelected,
            ]}
            onPress={() => setIsInstant(true)}
          >
            <Zap color={Colors.dark.warning} size={24} />
            <View style={styles.speedInfo}>
              <Text style={styles.speedTitle}>Instant (0.5%–1.5% fee)</Text>
              <Text style={styles.speedDescription}>
                Arrives within minutes · min $0.03, max 1%
              </Text>
            </View>
            {isInstant && (
              <CheckCircle2 color={Colors.dark.primary} size={24} />
            )}
          </TouchableOpacity>
        </View>

        <View style={styles.section}>
          <View style={styles.sectionHeader}>
            <Text style={styles.sectionLabel}>Bank Account</Text>
            <TouchableOpacity
              onPress={() => router.push("/settings/bank-accounts")}
            >
              <Text style={styles.addNewButton}>+ Add New</Text>
            </TouchableOpacity>
          </View>

          {bankAccountsQuery.isLoading && !isDemoMode ? (
            <ActivityIndicator size="small" color={Colors.dark.primary} />
          ) : bankAccounts.length > 0 ? (
            bankAccounts.map((account) => (
              <TouchableOpacity
                key={account.id}
                style={[
                  styles.accountCard,
                  selectedAccount === account.id && styles.accountCardSelected,
                ]}
                onPress={() => setSelectedAccount(account.id)}
              >
                <View style={styles.accountIcon}>
                  <Building2 color={Colors.dark.primary} size={24} />
                </View>
                <View style={styles.accountInfo}>
                  <Text style={styles.accountLabel}>
                    {account.bankName} •••• {account.last4}
                  </Text>
                  {account.isPrimary && (
                    <Text style={styles.accountPrimary}>Default</Text>
                  )}
                </View>
                {selectedAccount === account.id && (
                  <CheckCircle2 color={Colors.dark.primary} size={24} />
                )}
              </TouchableOpacity>
            ))
          ) : (
            <View style={styles.emptyContainer}>
              <Text style={styles.emptyText}>
                No bank accounts added yet
              </Text>
              <TouchableOpacity
                style={styles.addButton}
                onPress={() => router.push("/settings/bank-accounts")}
              >
                <Text style={styles.addButtonText}>Add Bank Account</Text>
              </TouchableOpacity>
            </View>
          )}
        </View>

        {amount && selectedAccount && (
          <View style={styles.summaryCard}>
            <Text style={styles.summaryTitle}>Transfer Summary</Text>
            <View style={styles.summaryRow}>
              <Text style={styles.summaryLabel}>Amount to receive</Text>
              <Text style={styles.summaryValue}>${payoutAmount.toFixed(2)}</Text>
            </View>
            {isInstant && (
              <View style={styles.summaryRow}>
                <Text style={styles.summaryLabel}>Zendo instant fee (3¢ min, 1% max)</Text>
                <Text style={styles.summaryValue}>+${instantFee.toFixed(2)}</Text>
              </View>
            )}
            <View style={[styles.summaryRow, styles.summaryTotal]}>
              <Text style={styles.summaryTotalLabel}>
                {isInstant ? "Total from balance" : "You'll receive"}
              </Text>
              <Text style={styles.summaryTotalValue}>
                ${(isInstant ? totalDebit : payoutAmount).toFixed(2)}
              </Text>
            </View>
          </View>
        )}
      </ScrollView>

      <View style={[styles.footer, { paddingBottom: insets.bottom + 20 }]}>
        <TouchableOpacity
          style={[
            styles.submitButton,
            (!amount || !selectedAccount || isSubmitting) && styles.submitButtonDisabled,
          ]}
          onPress={handleCashOut}
          disabled={!amount || !selectedAccount || isSubmitting}
        >
          {isSubmitting ? (
            <ActivityIndicator size="small" color={Colors.dark.background} />
          ) : (
            <Text style={styles.submitButtonText}>
              Cash Out ${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,
  },
  balanceCard: {
    backgroundColor: `${Colors.dark.primary}15`,
    padding: 20,
    borderRadius: 16,
    alignItems: "center",
  },
  disclosureCard: {
    backgroundColor: Colors.dark.surface,
    borderWidth: 1,
    borderColor: Colors.dark.border,
    padding: 16,
    borderRadius: 12,
  },
  disclosureTitle: {
    fontSize: 13,
    fontWeight: "700" as const,
    color: Colors.dark.text,
    marginBottom: 6,
  },
  disclosureText: {
    fontSize: 12,
    color: Colors.dark.textSecondary,
    lineHeight: 18,
  },
  balanceLabel: {
    fontSize: 14,
    color: Colors.dark.textSecondary,
    marginBottom: 8,
  },
  balanceAmount: {
    fontSize: 36,
    fontWeight: "700" as const,
    color: Colors.dark.text,
  },
  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,
  },
  speedCard: {
    flexDirection: "row",
    alignItems: "center",
    backgroundColor: Colors.dark.surface,
    padding: 16,
    borderRadius: 16,
    borderWidth: 2,
    borderColor: Colors.dark.border,
    gap: 12,
  },
  speedCardSelected: {
    borderColor: Colors.dark.primary,
  },
  speedInfo: {
    flex: 1,
  },
  speedTitle: {
    fontSize: 16,
    fontWeight: "600" as const,
    color: Colors.dark.text,
  },
  speedDescription: {
    fontSize: 13,
    color: Colors.dark.textSecondary,
    marginTop: 2,
  },
  accountCard: {
    flexDirection: "row",
    alignItems: "center",
    backgroundColor: Colors.dark.surface,
    padding: 16,
    borderRadius: 16,
    borderWidth: 2,
    borderColor: Colors.dark.border,
    gap: 12,
  },
  accountCardSelected: {
    borderColor: Colors.dark.primary,
  },
  accountIcon: {
    width: 48,
    height: 48,
    borderRadius: 24,
    backgroundColor: `${Colors.dark.primary}20`,
    justifyContent: "center",
    alignItems: "center",
  },
  accountInfo: {
    flex: 1,
  },
  accountLabel: {
    fontSize: 16,
    fontWeight: "600" as const,
    color: Colors.dark.text,
  },
  accountPrimary: {
    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,
  },
  summaryCard: {
    backgroundColor: Colors.dark.surface,
    padding: 20,
    borderRadius: 16,
    borderWidth: 1,
    borderColor: Colors.dark.border,
    gap: 16,
  },
  summaryTitle: {
    fontSize: 16,
    fontWeight: "700" as const,
    color: Colors.dark.text,
    marginBottom: 4,
  },
  summaryRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  summaryLabel: {
    fontSize: 14,
    color: Colors.dark.textSecondary,
  },
  summaryValue: {
    fontSize: 14,
    fontWeight: "600" as const,
    color: Colors.dark.text,
  },
  summaryTotal: {
    paddingTop: 12,
    borderTopWidth: 1,
    borderTopColor: Colors.dark.border,
    marginTop: 4,
  },
  summaryTotalLabel: {
    fontSize: 16,
    fontWeight: "700" as const,
    color: Colors.dark.text,
  },
  summaryTotalValue: {
    fontSize: 20,
    fontWeight: "700" as const,
    color: Colors.dark.primary,
  },
  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,
  },
});
