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

export default function AgencyJoinScreen() {
  const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>();
  const route = useRoute<RouteProp<RootStackParamList, "AgencyJoin">>();
  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 [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 resolvePreview(code: string) {
    const preview = await manager.fetchSessionPreview(code);
    if (!preview) {
      Alert.alert(t("entry.alert.sessionNotFound"));
      return null;
    }
    setJoinPreview(preview);
    setJoinStep("choice");
    return preview;
  }

  async function handleJoinPreview() {
    const normalized = joinCode.trim().toUpperCase();
    if (!normalized) {
      Alert.alert(t("entry.alert.enterCode"));
      return;
    }
    await resolvePreview(normalized);
  }

  useEffect(() => {
    const raw = route.params?.gameId;
    if (typeof raw !== "string") {
      return;
    }
    const normalized = raw.trim().toUpperCase();
    if (!normalized || handledLinkRef.current === normalized) {
      return;
    }
    handledLinkRef.current = normalized;
    setJoinCode(normalized);
    setJoinStep("code");
    setJoinPreview(null);
    setJoinName("");
    setTakeoverName("");
    setTakeoverDummyId("");
    setTakeoverToken(null);
    setTakeoverWaiting(false);
    void resolvePreview(normalized);
  }, [route.params?.gameId]);

  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);
    };
    void poll();
    return () => {
      cancelled = true;
      if (timeout) clearTimeout(timeout);
    };
  }, [joinPreview, takeoverToken, manager, navigation]);

  return (
    <ScrollView
      style={styles.scroll}
      contentContainerStyle={[
        styles.container,
        {
          paddingTop: insets.top + 16,
          paddingBottom: insets.bottom + 24,
          paddingLeft: insets.left + 20,
          paddingRight: insets.right + 20,
        },
      ]}
    >
      <View style={styles.hero}>
        <BrandLockup variant="hero" subtitle={t("entry.heroBadge")} onDark />
        <Text style={styles.heroTitle}>{t("entry.joinStepTitle")}</Text>
        <Text style={styles.heroBody}>{t("entry.joinStepSubtitle")}</Text>
      </View>

      <View style={styles.card}>
        <Text style={styles.cardTitle}>{t("entry.joinTitle")}</Text>
        <Text style={styles.cardSubtitle}>{t("entry.joinDescription")}</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);
            }
          }}
        />
        <TouchableOpacity style={styles.button} onPress={handleJoinPreview}>
          <Text style={styles.buttonText}>{t("common.continue")}</Text>
        </TouchableOpacity>
      </View>

      {joinStep === "choice" && joinPreview ? (
        <>
          <View style={styles.previewCard}>
            <Text style={styles.previewEyebrow}>{t("entry.previewLabel")}</Text>
            <Text style={styles.previewTitle}>
              {t("entry.agencyCodeValue", { code: joinPreview.code })}
            </Text>
            <Text style={styles.previewBody}>
              {t("entry.previewCustomers", { count: joinPreview.players.length })}
            </Text>
          </View>

          <View style={styles.choiceCard}>
            <Text style={styles.choiceTitle}>{t("entry.newPlayer")}</Text>
            <Text style={styles.choiceBody}>{t("entry.newCustomerDescription")}</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("entry.joinAsCustomer")}</Text>
            </TouchableOpacity>
          </View>

          <View style={styles.choiceCard}>
            <Text style={styles.choiceTitle}>{t("entry.takeoverTitle")}</Text>
            <Text style={styles.choiceBody}>{t("entry.recoverCustomerDescription")}</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>
        </>
      ) : null}

      <TouchableOpacity
        style={styles.linkButton}
        onPress={() => navigation.replace("AgencyCreate")}
      >
        <Text style={styles.linkText}>{t("entry.linkOpenNew")}</Text>
      </TouchableOpacity>
    </ScrollView>
  );
}

const createStyles = (theme: AppTheme) =>
  StyleSheet.create({
    scroll: {
      flex: 1,
      backgroundColor: theme.colors.background,
    },
    container: {
      gap: 18,
      backgroundColor: theme.colors.background,
    },
    hero: {
      borderRadius: 28,
      padding: 22,
      gap: 12,
      backgroundColor: theme.colors.brandSurface,
      borderWidth: 1,
      borderColor: theme.colors.brandSurfaceAlt,
    },
    heroTitle: {
      color: theme.colors.brandText,
      fontSize: 28,
      fontWeight: "800",
      letterSpacing: -0.8,
    },
    heroBody: {
      color: theme.colors.brandTextMuted,
      fontSize: 15,
      lineHeight: 22,
    },
    card: {
      backgroundColor: theme.colors.surface,
      borderRadius: 24,
      padding: 20,
      gap: 12,
      borderWidth: 1,
      borderColor: theme.colors.border,
    },
    cardTitle: {
      color: theme.colors.text,
      fontSize: 22,
      fontWeight: "700",
      letterSpacing: -0.4,
    },
    cardSubtitle: {
      color: theme.colors.textMuted,
      fontSize: 14,
      lineHeight: 21,
    },
    input: {
      borderWidth: 1,
      borderColor: theme.colors.border,
      backgroundColor: theme.colors.inputBackground,
      color: theme.colors.inputText,
      borderRadius: 16,
      paddingHorizontal: 14,
      paddingVertical: 13,
    },
    button: {
      backgroundColor: theme.colors.primary,
      paddingVertical: 14,
      borderRadius: 999,
      alignItems: "center",
    },
    buttonText: {
      color: theme.colors.primaryText,
      fontWeight: "700",
    },
    previewCard: {
      borderRadius: 24,
      padding: 20,
      gap: 8,
      backgroundColor: theme.colors.accentSurface,
      borderWidth: 1,
      borderColor: theme.colors.borderMuted,
    },
    previewEyebrow: {
      color: theme.colors.accent,
      fontSize: 12,
      fontWeight: "700",
      letterSpacing: 1.1,
      textTransform: "uppercase",
    },
    previewTitle: {
      color: theme.colors.text,
      fontSize: 22,
      fontWeight: "800",
      letterSpacing: -0.5,
    },
    previewBody: {
      color: theme.colors.textMuted,
    },
    choiceCard: {
      backgroundColor: theme.colors.surface,
      borderRadius: 24,
      padding: 20,
      gap: 12,
      borderWidth: 1,
      borderColor: theme.colors.border,
    },
    choiceTitle: {
      fontSize: 18,
      fontWeight: "700",
      color: theme.colors.text,
    },
    choiceBody: {
      color: theme.colors.textMuted,
      lineHeight: 20,
    },
    dropdown: {
      gap: 6,
    },
    dropdownButton: {
      borderWidth: 1,
      borderColor: theme.colors.border,
      backgroundColor: theme.colors.inputBackground,
      borderRadius: 16,
      paddingHorizontal: 14,
      paddingVertical: 13,
    },
    dropdownText: {
      color: theme.colors.inputText,
      fontWeight: "600",
    },
    dropdownList: {
      borderWidth: 1,
      borderColor: theme.colors.border,
      borderRadius: 16,
      backgroundColor: theme.colors.surface,
      overflow: "hidden",
    },
    pendingBox: {
      gap: 10,
      backgroundColor: theme.colors.surfaceAlt,
      borderRadius: 16,
      padding: 14,
      borderWidth: 1,
      borderColor: theme.colors.borderMuted,
    },
    dropdownItem: {
      paddingHorizontal: 14,
      paddingVertical: 12,
      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,
    },
    buttonSecondary: {
      backgroundColor: theme.colors.secondary,
      paddingVertical: 14,
      borderRadius: 999,
      alignItems: "center",
    },
    buttonSecondaryText: {
      color: theme.colors.secondaryText,
      fontWeight: "700",
    },
    helper: {
      fontSize: 12,
      color: theme.colors.textMuted,
    },
    linkButton: {
      paddingVertical: 12,
      alignItems: "center",
    },
    linkText: {
      color: theme.colors.textMuted,
      fontWeight: "600",
    },
  });
