import React, { useEffect, useMemo, useRef, useState } from "react";
import {
  Alert,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useNavigation, useRoute } from "@react-navigation/native";
import type { RouteProp } from "@react-navigation/native";
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import type { RootStackParamList } from "../navigation/types";
import { useSession } from "../state/session-context";
import type { SessionPreview } from "../shared/types";
import { useI18n } from "../i18n";
import { useTheme } from "../theme";
import type { AppTheme } from "../theme";

export default function EntryScreen() {
  const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
  const route = useRoute<RouteProp<RootStackParamList, "Entry">>();
  const manager = useSession();
  const { t } = useI18n();
  const theme = useTheme();
  const styles = useMemo(() => createStyles(theme), [theme]);
  const placeholderColor = theme.colors.placeholder;
  const handledLinkRef = useRef<string | null>(null);
  const insets = useSafeAreaInsets();
  const contentStyle = useMemo(
    () => [
      styles.container,
      {
        paddingTop: insets.top + 20,
        paddingBottom: insets.bottom + 20,
        paddingLeft: insets.left + 20,
        paddingRight: insets.right + 20,
      },
    ],
    [styles.container, insets.top, insets.bottom, insets.left, insets.right],
  );
  const [createName, setCreateName] = useState("");
  const [joinCode, setJoinCode] = useState("");
  const [joinStep, setJoinStep] = useState<"code" | "choice">("code");
  const [joinPreview, setJoinPreview] = useState<SessionPreview | null>(null);
  const [joinName, setJoinName] = useState("");
  const [takeoverName, setTakeoverName] = useState("");
  const [takeoverDummyId, setTakeoverDummyId] = useState("");
  const [showDummyOptions, setShowDummyOptions] = useState(false);
  const [takeoverToken, setTakeoverToken] = useState<string | null>(null);
  const [takeoverWaiting, setTakeoverWaiting] = useState(false);

  const dummyOptions = useMemo(
    () => joinPreview?.players.filter((player) => player.isDummy) ?? [],
    [joinPreview],
  );
  const storedPlayer = joinPreview?.players.find((player) => player.id === manager.playerId);
  const takeoverDisabled = storedPlayer?.connected === true;

  async function handleCreate() {
    const data = await manager.createSession(createName.trim());
    if (data) {
      navigation.replace("Lobby");
    }
  }

  async function handleJoinPreview() {
    if (!joinCode.trim()) {
      Alert.alert(t("entry.alert.enterCode"));
      return;
    }
    const preview = await manager.fetchSessionPreview(joinCode.trim().toUpperCase());
    if (!preview) {
      Alert.alert(t("entry.alert.sessionNotFound"));
      return;
    }
    setJoinPreview(preview);
    setJoinStep("choice");
  }

  useEffect(() => {
    const raw = route.params?.gameId;
    if (typeof raw !== "string") return;
    const normalized = raw.trim();
    if (!normalized) {
      if (__DEV__) {
        console.log("[deep-link] invalid gameId");
      }
      return;
    }
    const code = normalized.toUpperCase();
    if (handledLinkRef.current === code) return;
    handledLinkRef.current = code;
    if (__DEV__) {
      console.log(`[deep-link] navigating to session ${code}`);
    }
    setJoinCode(code);
    setJoinStep("code");
    setJoinPreview(null);
    setJoinName("");
    setTakeoverName("");
    setTakeoverDummyId("");
    setTakeoverToken(null);
    setTakeoverWaiting(false);
    manager.fetchSessionPreview(code).then((preview) => {
      if (!preview) {
        Alert.alert(t("entry.alert.sessionNotFound"));
        return;
      }
      setJoinPreview(preview);
      setJoinStep("choice");
    });
  }, [route.params?.gameId, manager, t]);

  async function handleJoinNew() {
    if (!joinPreview) return;
    const data = await manager.joinSession(joinPreview.code, joinName.trim());
    if (data) {
      navigation.replace("Lobby");
    }
  }

  async function handleTakeover() {
    if (!joinPreview) return;
    if (!takeoverDummyId) {
      Alert.alert(t("entry.alert.selectDummy"));
      return;
    }
    setTakeoverWaiting(true);
    const selectedDummy = joinPreview.players.find((player) => player.id === takeoverDummyId);
    const fallbackName = takeoverName.trim() || selectedDummy?.name || "";
    const token = await manager.requestTakeoverToken(
      joinPreview.code,
      takeoverDummyId,
      fallbackName,
    );
    if (!token) {
      setTakeoverWaiting(false);
      if (manager.error) {
        Alert.alert(manager.error);
      }
      return;
    }
    setTakeoverToken(token);
  }

  useEffect(() => {
    if (joinStep === "code" || !joinPreview) {
      setShowDummyOptions(false);
      setTakeoverToken(null);
      setTakeoverWaiting(false);
    }
  }, [joinStep, joinPreview]);

  useEffect(() => {
    if (!takeoverToken || !joinPreview) return;
    let cancelled = false;
    let timeout: ReturnType<typeof setTimeout> | null = null;
    const poll = async () => {
      const data = await manager.claimTakeover(joinPreview.code, takeoverToken);
      if (cancelled) return;
      if (data) {
        setTakeoverWaiting(false);
        setTakeoverToken(null);
        navigation.replace("Lobby");
        return;
      }
      timeout = setTimeout(poll, 2000);
    };
    poll();
    return () => {
      cancelled = true;
      if (timeout) clearTimeout(timeout);
    };
  }, [takeoverToken, joinPreview, manager, navigation]);

  return (
    <ScrollView style={styles.scroll} contentContainerStyle={contentStyle}>
      <Text style={styles.title}>{t("app.name")}</Text>
      <Text style={styles.subtitle}>{t("entry.subtitle")}</Text>

      <View style={styles.card}>
        <Text style={styles.cardTitle}>{t("entry.joinTitle")}</Text>
        <TextInput
          style={styles.input}
          placeholder={t("entry.sessionCode")}
          placeholderTextColor={placeholderColor}
          autoCapitalize="characters"
          value={joinCode}
          onChangeText={(value) => {
            setJoinCode(value.toUpperCase());
            if (joinStep === "choice") {
              setJoinStep("code");
              setJoinPreview(null);
              setJoinName("");
              setTakeoverName("");
              setTakeoverDummyId("");
              setShowDummyOptions(false);
            }
          }}
        />

        {joinStep === "code" ? (
          <TouchableOpacity style={styles.buttonSecondary} onPress={handleJoinPreview}>
            <Text style={styles.buttonSecondaryText}>{t("common.continue")}</Text>
          </TouchableOpacity>
        ) : null}

        {joinStep === "choice" && joinPreview ? (
          <View style={styles.choiceGrid}>
            <View style={styles.choiceCard}>
              <Text style={styles.choiceTitle}>{t("entry.newPlayer")}</Text>
              <TextInput
                style={styles.input}
                placeholder={t("entry.playerName")}
                placeholderTextColor={placeholderColor}
                value={joinName}
                onChangeText={setJoinName}
              />
              <TouchableOpacity style={styles.buttonSecondary} onPress={handleJoinNew}>
                <Text style={styles.buttonSecondaryText}>{t("common.join")}</Text>
              </TouchableOpacity>
            </View>

            <View style={styles.choiceCard}>
              <Text style={styles.choiceTitle}>{t("entry.takeoverTitle")}</Text>
              {takeoverDisabled ? (
                <Text style={styles.helper}>{t("entry.alreadyConnected")}</Text>
              ) : (
                <>
                  {takeoverWaiting ? (
                    <View style={styles.pendingBox}>
                      <Text style={styles.helper}>{t("entry.takeoverPending")}</Text>
                      <TouchableOpacity
                        style={styles.buttonSecondary}
                        onPress={() => {
                          setTakeoverToken(null);
                          setTakeoverWaiting(false);
                        }}
                      >
                        <Text style={styles.buttonSecondaryText}>{t("common.cancel")}</Text>
                      </TouchableOpacity>
                    </View>
                  ) : (
                    <>
                      <View style={styles.dropdown}>
                        <TouchableOpacity
                          style={styles.dropdownButton}
                          onPress={() => {
                            if (dummyOptions.length === 0) return;
                            setShowDummyOptions((prev) => !prev);
                          }}
                        >
                          <Text style={styles.dropdownText}>
                            {dummyOptions.find((player) => player.id === takeoverDummyId)?.name
                              ? `${dummyOptions.find((player) => player.id === takeoverDummyId)?.name} · ${takeoverDummyId}`
                              : t("entry.selectDummy")}
                          </Text>
                        </TouchableOpacity>
                        {showDummyOptions && dummyOptions.length > 0 ? (
                          <View style={styles.dropdownList}>
                            {dummyOptions.map((player) => (
                              <TouchableOpacity
                                key={player.id}
                                style={[
                                  styles.dropdownItem,
                                  player.id === takeoverDummyId
                                    ? styles.dropdownItemActive
                                    : null,
                                ]}
                                onPress={() => {
                                  setTakeoverDummyId(player.id);
                                  setShowDummyOptions(false);
                                }}
                              >
                                <Text style={styles.dropdownItemText}>{player.name}</Text>
                                <Text style={styles.dropdownItemMeta}>{player.id}</Text>
                              </TouchableOpacity>
                            ))}
                          </View>
                        ) : null}
                      </View>
                      <TextInput
                        style={styles.input}
                        placeholder={t("entry.yourNameOptional")}
                        placeholderTextColor={placeholderColor}
                        value={takeoverName}
                        onChangeText={setTakeoverName}
                      />
                      <TouchableOpacity style={styles.buttonSecondary} onPress={handleTakeover}>
                        <Text style={styles.buttonSecondaryText}>
                          {t("entry.requestTakeover")}
                        </Text>
                      </TouchableOpacity>
                    </>
                  )}
                </>
              )}
              {!takeoverDisabled && dummyOptions.length === 0 ? (
                <Text style={styles.helper}>{t("entry.noDummies")}</Text>
              ) : null}
            </View>
          </View>
        ) : null}
      </View>

      <View style={styles.card}>
        <Text style={styles.cardTitle}>{t("entry.createTitle")}</Text>
        <TextInput
          style={styles.input}
          placeholder={t("entry.bankerName")}
          placeholderTextColor={placeholderColor}
          value={createName}
          onChangeText={setCreateName}
        />
        <TouchableOpacity style={styles.button} onPress={handleCreate}>
          <Text style={styles.buttonText}>{t("entry.openVault")}</Text>
        </TouchableOpacity>
      </View>
    </ScrollView>
  );
}

const createStyles = (theme: AppTheme) =>
  StyleSheet.create({
    scroll: {
      flex: 1,
      backgroundColor: theme.colors.background,
    },
    container: {
      padding: 0,
      gap: 16,
    },
    title: {
      fontSize: 28,
      fontWeight: "700",
      color: theme.colors.text,
    },
    subtitle: {
      fontSize: 16,
      color: theme.colors.textMuted,
    },
    card: {
      backgroundColor: theme.colors.surface,
      borderRadius: 16,
      padding: 16,
      shadowColor: "#000",
      shadowOpacity: theme.dark ? 0.2 : 0.08,
      shadowRadius: 12,
      shadowOffset: { width: 0, height: 6 },
    },
    cardTitle: {
      fontSize: 18,
      fontWeight: "600",
      marginBottom: 12,
      color: theme.colors.text,
    },
    input: {
      borderWidth: 1,
      borderColor: theme.colors.border,
      backgroundColor: theme.colors.inputBackground,
      color: theme.colors.inputText,
      borderRadius: 12,
      paddingHorizontal: 12,
      paddingVertical: 10,
      marginBottom: 10,
    },
    dropdown: {
      gap: 6,
      marginBottom: 10,
    },
    dropdownButton: {
      borderWidth: 1,
      borderColor: theme.colors.border,
      backgroundColor: theme.colors.inputBackground,
      borderRadius: 12,
      paddingHorizontal: 12,
      paddingVertical: 10,
    },
    dropdownText: {
      color: theme.colors.inputText,
      fontWeight: "600",
    },
    dropdownList: {
      borderWidth: 1,
      borderColor: theme.colors.border,
      borderRadius: 12,
      backgroundColor: theme.colors.surface,
      overflow: "hidden",
    },
    pendingBox: {
      gap: 10,
      backgroundColor: theme.colors.surfaceAlt,
      borderRadius: 12,
      padding: 12,
      borderWidth: 1,
      borderColor: theme.colors.borderMuted,
    },
    dropdownItem: {
      paddingHorizontal: 12,
      paddingVertical: 10,
      borderBottomWidth: 1,
      borderBottomColor: theme.colors.borderMuted,
    },
    dropdownItemActive: {
      backgroundColor: theme.colors.accentSurface,
    },
    dropdownItemText: {
      fontWeight: "600",
      color: theme.colors.text,
    },
    dropdownItemMeta: {
      color: theme.colors.textMuted,
      fontSize: 12,
    },
    button: {
      backgroundColor: theme.colors.primary,
      paddingVertical: 12,
      borderRadius: 999,
      alignItems: "center",
    },
    buttonText: {
      color: theme.colors.primaryText,
      fontWeight: "600",
    },
    buttonSecondary: {
      backgroundColor: theme.colors.secondary,
      paddingVertical: 12,
      borderRadius: 999,
      alignItems: "center",
    },
    buttonSecondaryText: {
      color: theme.colors.secondaryText,
      fontWeight: "600",
    },
    choiceGrid: {
      marginTop: 12,
      gap: 12,
    },
    choiceCard: {
      backgroundColor: theme.colors.surfaceAlt,
      borderRadius: 12,
      padding: 12,
    },
    choiceTitle: {
      fontWeight: "600",
      marginBottom: 8,
      color: theme.colors.text,
    },
    helper: {
      fontSize: 12,
      color: theme.colors.textMuted,
    },
  });
