import { useState, type ReactNode } from "react";
import {
  ActivityIndicator,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  type StyleProp,
  type ViewStyle,
} from "react-native";
import { ChevronDown, ChevronUp, Eye, EyeOff } from "lucide-react-native";

import Colors from "@/constants/colors";
import { QuietAmount } from "@/components/QuietAmount";
import { useLedgerSummary } from "@/lib/hooks/use-ledger-summary";

function formatUsd(amount: number): string {
  return amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

interface LedgerBalanceCardProps {
  style?: StyleProp<ViewStyle>;
  /** Show eye toggle for hiding amounts (e.g. privacy mode). */
  balanceVisible?: boolean;
  onToggleVisibility?: () => void;
  /** Optional row below the main balance (Add Money / Cash Out buttons). */
  actions?: ReactNode;
  /** Compact layout for secondary screens. */
  variant?: "primary" | "compact";
}

export function LedgerBalanceCard({
  style,
  balanceVisible = true,
  onToggleVisibility,
  actions,
  variant = "primary",
}: LedgerBalanceCardProps) {
  const { isLoading, isError, availableBalance, postedBalance, pendingHolds, activeHolds, refetch } =
    useLedgerSummary();
  const [detailsOpen, setDetailsOpen] = useState(false);

  const masked = "••••••";
  const hasHolds = pendingHolds > 0;

  return (
    <View style={[variant === "primary" ? styles.card : styles.cardCompact, style]}>
      <View style={styles.headerRow}>
        <Text style={styles.label}>Available Balance</Text>
        {onToggleVisibility ? (
          <TouchableOpacity
            onPress={onToggleVisibility}
            hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
          >
            {balanceVisible ? (
              <Eye color={Colors.dark.textSecondary} size={20} />
            ) : (
              <EyeOff color={Colors.dark.textSecondary} size={20} />
            )}
          </TouchableOpacity>
        ) : null}
      </View>

      {isLoading ? (
        <ActivityIndicator color={Colors.dark.primary} style={styles.loader} />
      ) : isError ? (
        <TouchableOpacity onPress={() => refetch()}>
          <Text style={styles.errorText}>Couldn&apos;t load balance. Tap to retry.</Text>
        </TouchableOpacity>
      ) : (
        <>
          <QuietAmount>
            <Text style={variant === "primary" ? styles.amountPrimary : styles.amountCompact}>
              {balanceVisible ? formatUsd(availableBalance) : masked}
            </Text>
          </QuietAmount>

          <TouchableOpacity
            style={styles.detailsToggle}
            onPress={() => setDetailsOpen((open) => !open)}
            activeOpacity={0.7}
          >
            <Text style={styles.detailsToggleText}>Balance details</Text>
            {detailsOpen ? (
              <ChevronUp color={Colors.dark.textSecondary} size={16} />
            ) : (
              <ChevronDown color={Colors.dark.textSecondary} size={16} />
            )}
          </TouchableOpacity>

          {detailsOpen && (
            <View style={styles.detailsPanel}>
              <View style={styles.detailRow}>
                <Text style={styles.detailLabel}>Posted balance</Text>
                <Text style={styles.detailValue}>
                  {balanceVisible ? `$${formatUsd(postedBalance)}` : masked}
                </Text>
              </View>
              <View style={styles.detailRow}>
                <Text style={styles.detailLabel}>Pending holds</Text>
                <Text style={[styles.detailValue, hasHolds && styles.holdsValue]}>
                  {balanceVisible ? `−$${formatUsd(pendingHolds)}` : masked}
                </Text>
              </View>
              {hasHolds && activeHolds.length > 0 && balanceVisible && (
                <View style={styles.holdsList}>
                  {activeHolds.map((hold) => (
                    <View key={hold.id} style={styles.holdItem}>
                      <Text style={styles.holdItemLabel} numberOfLines={1}>
                        {hold.merchantCategory ? hold.merchantCategory.replace(/_/g, " ") : "Card hold"}
                      </Text>
                      <Text style={styles.holdItemAmount}>${formatUsd(hold.amount)}</Text>
                    </View>
                  ))}
                </View>
              )}
              <Text style={styles.detailsFootnote}>
                Available = posted balance minus active card authorization holds.
              </Text>
            </View>
          )}
        </>
      )}

      {actions ? <View style={styles.actions}>{actions}</View> : null}
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    backgroundColor: Colors.dark.surface,
    marginHorizontal: 20,
    marginTop: 20,
    padding: 24,
    borderRadius: 20,
    borderWidth: 1,
    borderColor: Colors.dark.border,
  },
  cardCompact: {
    backgroundColor: Colors.dark.surface,
    padding: 20,
    borderRadius: 16,
    borderWidth: 1,
    borderColor: Colors.dark.border,
    marginBottom: 20,
  },
  headerRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    marginBottom: 8,
  },
  label: {
    fontSize: 14,
    color: Colors.dark.textSecondary,
    fontWeight: "500",
  },
  amountPrimary: {
    fontSize: 42,
    fontWeight: "700",
    color: Colors.dark.text,
    letterSpacing: -1,
    marginBottom: 4,
  },
  amountCompact: {
    fontSize: 32,
    fontWeight: "700",
    color: Colors.dark.text,
    letterSpacing: -0.5,
    marginBottom: 4,
  },
  loader: {
    marginVertical: 16,
    alignSelf: "flex-start",
  },
  errorText: {
    fontSize: 14,
    color: Colors.dark.warning,
    marginVertical: 12,
  },
  detailsToggle: {
    flexDirection: "row",
    alignItems: "center",
    gap: 4,
    marginTop: 8,
    marginBottom: 4,
  },
  detailsToggleText: {
    fontSize: 13,
    fontWeight: "600",
    color: Colors.dark.textSecondary,
  },
  detailsPanel: {
    marginTop: 12,
    paddingTop: 12,
    borderTopWidth: 1,
    borderTopColor: Colors.dark.border,
    gap: 10,
  },
  detailRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  detailLabel: {
    fontSize: 13,
    color: Colors.dark.textSecondary,
  },
  detailValue: {
    fontSize: 14,
    fontWeight: "600",
    color: Colors.dark.text,
  },
  holdsValue: {
    color: Colors.dark.warning,
  },
  holdsList: {
    gap: 6,
    paddingLeft: 4,
  },
  holdItem: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  holdItemLabel: {
    flex: 1,
    fontSize: 12,
    color: Colors.dark.textTertiary,
    textTransform: "capitalize",
  },
  holdItemAmount: {
    fontSize: 12,
    fontWeight: "600",
    color: Colors.dark.warning,
    marginLeft: 8,
  },
  detailsFootnote: {
    fontSize: 11,
    color: Colors.dark.textTertiary,
    lineHeight: 16,
    marginTop: 4,
  },
  actions: {
    marginTop: 24,
  },
});
