import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { useState } from "react";
import {
  Modal,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from "react-native";

import { fonts, radii, spacing } from "@/constants/theme";
import { useAccounts } from "@/contexts/AccountsContext";
import { useAuthClient, useSession } from "@/contexts/AuthContext";
import { useAppTheme } from "@/contexts/ThemeContext";
import { formatServerHost } from "@/lib/server-mode";

function initials(name: string, email: string) {
  const source = name.trim() || email.trim();
  const parts = source.split(/\s+/).filter(Boolean);
  if (parts.length >= 2) {
    return `${parts[0]![0] ?? ""}${parts[1]![0] ?? ""}`.toUpperCase();
  }
  return (source[0] ?? "?").toUpperCase();
}

function displayName(name: string, email: string) {
  const trimmed = name.trim();
  if (trimmed) return trimmed.split(/\s+/)[0] ?? trimmed;
  return email.split("@")[0] ?? email;
}

/** Header control to switch signed-in accounts or add another. */
export function AccountSwitcher() {
  const { colors } = useAppTheme();
  const authClient = useAuthClient();
  const { data: session } = useSession();
  const {
    accounts,
    activeAccount,
    activeAccountId,
    switchAccount,
    clearActiveAccount,
  } = useAccounts();
  const [open, setOpen] = useState(false);

  const label = displayName(
    activeAccount?.name ?? session?.user.name ?? "",
    activeAccount?.email ?? session?.user.email ?? "",
  );
  const avatar = initials(
    activeAccount?.name ?? session?.user.name ?? "",
    activeAccount?.email ?? session?.user.email ?? "",
  );

  async function handleAddAccount() {
    setOpen(false);
    await authClient.signOut();
    await clearActiveAccount();
    router.replace("/(auth)/sign-in");
  }

  async function handleSwitch(accountId: string) {
    if (accountId === activeAccountId) {
      setOpen(false);
      return;
    }
    setOpen(false);
    await switchAccount(accountId);
  }

  return (
    <>
      <Pressable
        accessibilityRole="button"
        accessibilityLabel="Switch account"
        hitSlop={8}
        onPress={() => setOpen(true)}
        style={styles.hit}
      >
        <View style={[styles.row, { backgroundColor: colors.muted }]}>
          <View style={[styles.avatar, { backgroundColor: colors.primary }]}>
            <Text style={[styles.avatarText, { color: colors.primaryForeground }]}>
              {avatar}
            </Text>
          </View>
          <Text
            style={[styles.name, { color: colors.foreground }]}
            numberOfLines={1}
          >
            {label}
          </Text>
          <Ionicons name="chevron-down" size={14} color={colors.mutedForeground} />
        </View>
      </Pressable>

      <Modal animationType="fade" onRequestClose={() => setOpen(false)} transparent visible={open}>
        <Pressable style={styles.backdrop} onPress={() => setOpen(false)}>
          <Pressable
            style={[styles.sheet, { backgroundColor: colors.background }]}
            onPress={(event) => event.stopPropagation()}
          >
            <View style={[styles.sheetHeader, { borderBottomColor: colors.border }]}>
              <Text style={[styles.sheetTitle, { color: colors.foreground }]}>Accounts</Text>
              <Pressable accessibilityRole="button" onPress={() => setOpen(false)}>
                <Text style={[styles.done, { color: colors.primary }]}>Done</Text>
              </Pressable>
            </View>

            <ScrollView keyboardShouldPersistTaps="handled">
              {accounts.map((account) => {
                const isActive = account.id === activeAccountId;
                return (
                  <Pressable
                    key={account.id}
                    accessibilityRole="button"
                    onPress={() => void handleSwitch(account.id)}
                    style={({ pressed }) => [
                      styles.accountRow,
                      {
                        borderBottomColor: colors.border,
                        backgroundColor: isActive ? colors.muted : "transparent",
                      },
                      pressed && styles.pressed,
                    ]}
                  >
                    <View style={[styles.avatar, { backgroundColor: colors.primary }]}>
                      <Text style={[styles.avatarText, { color: colors.primaryForeground }]}>
                        {initials(account.name, account.email)}
                      </Text>
                    </View>
                    <View style={styles.accountMeta}>
                      <Text style={[styles.accountName, { color: colors.foreground }]}>
                        {account.name || account.email}
                      </Text>
                      <Text style={[styles.accountSub, { color: colors.mutedForeground }]}>
                        {account.email}
                      </Text>
                      <Text style={[styles.accountSub, { color: colors.mutedForeground }]}>
                        {formatServerHost(account.instanceUrl)}
                      </Text>
                    </View>
                    {isActive ? (
                      <Ionicons name="checkmark" size={18} color={colors.primary} />
                    ) : null}
                  </Pressable>
                );
              })}

              <Pressable
                accessibilityRole="button"
                onPress={() => void handleAddAccount()}
                style={({ pressed }) => [
                  styles.addRow,
                  { borderTopColor: colors.border },
                  pressed && styles.pressed,
                ]}
              >
                <Ionicons name="add-circle-outline" size={22} color={colors.primary} />
                <Text style={[styles.addLabel, { color: colors.primary }]}>Add account</Text>
              </Pressable>
            </ScrollView>
          </Pressable>
        </Pressable>
      </Modal>
    </>
  );
}

const styles = StyleSheet.create({
  hit: {
    flexShrink: 1,
    maxWidth: "58%",
  },
  row: {
    flexDirection: "row",
    alignItems: "center",
    gap: 6,
    paddingLeft: 4,
    paddingRight: 8,
    minHeight: 32,
    borderRadius: radii.pill,
  },
  avatar: {
    width: 24,
    height: 24,
    borderRadius: 12,
    alignItems: "center",
    justifyContent: "center",
  },
  avatarText: {
    fontFamily: fonts.bodySemiBold,
    fontSize: 11,
  },
  name: {
    flexShrink: 1,
    fontFamily: fonts.bodyMedium,
    fontSize: 14,
    lineHeight: 18,
  },
  backdrop: {
    flex: 1,
    justifyContent: "flex-end",
    backgroundColor: "rgba(0,0,0,0.45)",
  },
  sheet: {
    borderTopLeftRadius: radii.xl,
    borderTopRightRadius: radii.xl,
    maxHeight: "70%",
  },
  sheetHeader: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    paddingHorizontal: spacing.lg,
    paddingVertical: spacing.md,
    borderBottomWidth: 1,
  },
  sheetTitle: {
    fontFamily: fonts.bodySemiBold,
    fontSize: 16,
  },
  done: {
    fontFamily: fonts.bodySemiBold,
    fontSize: 16,
  },
  accountRow: {
    flexDirection: "row",
    alignItems: "center",
    gap: spacing.md,
    paddingHorizontal: spacing.lg,
    paddingVertical: spacing.md,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  accountMeta: {
    flex: 1,
    gap: 2,
  },
  accountName: {
    fontFamily: fonts.bodyMedium,
    fontSize: 15,
  },
  accountSub: {
    fontFamily: fonts.body,
    fontSize: 12,
    lineHeight: 16,
  },
  addRow: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    gap: spacing.sm,
    paddingVertical: spacing.lg,
    borderTopWidth: StyleSheet.hairlineWidth,
  },
  addLabel: {
    fontFamily: fonts.bodySemiBold,
    fontSize: 15,
  },
  pressed: {
    opacity: 0.75,
  },
});
