import { Stack } from "expo-router/stack";
import { ConvexProvider, ConvexReactClient } from "convex/react";
import { useState, createContext, useContext, useEffect, useCallback, Component, type ReactNode, type ErrorInfo } from "react";
import { View, Text, Pressable, ScrollView } from "react-native";
import { ThemeProvider, useTheme } from "../components/theme";

const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!);

type AuthState = {
  token: string | null;
  userId: string | null;
  isAuthenticated: boolean;
  login: (token: string, userId: string) => Promise<void>;
  logout: () => Promise<void>;
};

const AuthContext = createContext<AuthState>({
  token: null,
  userId: null,
  isAuthenticated: false,
  login: async () => {},
  logout: async () => {},
});

export function useAuth() {
  return useContext(AuthContext);
}

const TOKEN_KEY = "mojmajstor_auth_token";
const USER_ID_KEY = "mojmajstor_auth_userId";

class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean; error: Error | null }> {
  state: { hasError: boolean; error: Error | null } = { hasError: false, error: null };

  static getDerivedStateFromError(error: Error) {
    return { hasError: true, error };
  }

  reset = () => {
    this.setState({ hasError: false, error: null });
  };

  render() {
    if (this.state.hasError) {
      return <ErrorFallback error={this.state.error!} onReset={this.reset} />;
    }
    return this.props.children;
  }
}

function ErrorFallback({ error, onReset }: { error: Error; onReset: () => void }) {
  const theme = useTheme();
  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center", padding: 24, backgroundColor: theme.colors.background }}>
      <Text style={{ fontSize: 48, marginBottom: 16 }}>⚠️</Text>
      <Text style={{ fontSize: 20, fontWeight: "700", color: theme.colors.text, marginBottom: 8, textAlign: "center" }}>
        Настана грешка
      </Text>
      <Text style={{ fontSize: 14, color: theme.colors.textSecondary, textAlign: "center", marginBottom: 8 }}>
        Приложението наиде на неочекувана грешка.
      </Text>
      {__DEV__ && error?.message ? (
        <ScrollView style={{ maxHeight: 120, marginBottom: 16 }} contentContainerStyle={{ padding: 12, backgroundColor: theme.colors.surface, borderRadius: 8 }}>
          <Text style={{ fontSize: 12, color: theme.colors.error, fontFamily: "monospace" }}>
            {error.message}
          </Text>
        </ScrollView>
      ) : null}
      <Pressable
        accessible
        accessibilityLabel="Обиди се повторно"
        accessibilityRole="button"
        onPress={onReset}
        style={{ backgroundColor: theme.colors.primary, borderRadius: 12, paddingVertical: 12, paddingHorizontal: 32 }}
      >
        <Text style={{ color: "#FFFFFF", fontWeight: "600", fontSize: 16 }}>Обиди се повторно</Text>
      </Pressable>
    </View>
  );
}

export default function RootLayout() {
  const [token, setToken] = useState<string | null>(null);
  const [userId, setUserId] = useState<string | null>(null);
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    Promise.all([
      localStorage.getItem(TOKEN_KEY),
      localStorage.getItem(USER_ID_KEY),
    ]).then(([t, u]) => {
      if (t) setToken(t);
      if (u) setUserId(u);
      setLoaded(true);
    });
  }, []);

  const login = useCallback(async (newToken: string, newUserId: string) => {
    localStorage.setItem(TOKEN_KEY, newToken);
    localStorage.setItem(USER_ID_KEY, newUserId);
    setToken(newToken);
    setUserId(newUserId);
  }, []);

  const logout = useCallback(async () => {
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(USER_ID_KEY);
    setToken(null);
    setUserId(null);
  }, []);

  if (!loaded) return null;

  return (
    <ConvexProvider client={convex}>
      <ThemeProvider>
        <AuthContext.Provider
          value={{ token, userId, isAuthenticated: !!token, login, logout }}
        >
          <ErrorBoundary>
            <Stack screenOptions={{ headerShown: false }}>
              <Stack.Screen name="(auth)" />
              <Stack.Screen name="(tabs)" />
              <Stack.Screen name="ad/[id]" options={{ presentation: "card" }} />
              <Stack.Screen name="ad/create" options={{ presentation: "modal" }} />
              <Stack.Screen name="post/[id]" options={{ presentation: "card" }} />
              <Stack.Screen name="post/create" options={{ presentation: "modal" }} />
              <Stack.Screen name="chat/[id]" options={{ presentation: "card" }} />
              <Stack.Screen name="review/create" options={{ presentation: "modal" }} />
            </Stack>
          </ErrorBoundary>
        </AuthContext.Provider>
      </ThemeProvider>
    </ConvexProvider>
  );
}