import React, { useEffect, useRef, useState } from 'react';
import { Animated, StyleSheet, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

// ── Connectivity check ─────────────────────────────────────
//
// We avoid pulling in @react-native-community/netinfo as a hard
// dependency.  Instead, we detect offline state heuristically by
// periodically making a lightweight HEAD request to a reliable
// endpoint.  When the request fails we assume the device is offline.

const CHECK_URL = 'https://clients3.google.com/generate_204';
const CHECK_INTERVAL_MS = 30_000; // every 30 seconds

type NetStatus = 'online' | 'offline' | 'unknown';

/**
 * Lightweight network reachability check.
 *
 * Exported so callers (e.g. hooks) can query connectivity without
 * importing the component.
 */
export async function checkConnectivity(): Promise<boolean> {
  try {
    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), 5_000);
    const res = await fetch(CHECK_URL, {
      method: 'HEAD',
      signal: controller.signal,
    });
    clearTimeout(id);
    return res.ok;
  } catch {
    return false;
  }
}

// ── Hook ───────────────────────────────────────────────────

function useNetworkStatus(): NetStatus {
  const [status, setStatus] = useState<NetStatus>('unknown');
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  useEffect(() => {
    let active = true;

    const poll = async () => {
      const online = await checkConnectivity();
      if (!active) return;
      setStatus(online ? 'online' : 'offline');
    };

    // Immediate check
    poll();

    // Periodic checks
    intervalRef.current = setInterval(poll, CHECK_INTERVAL_MS);

    return () => {
      active = false;
      if (intervalRef.current) clearInterval(intervalRef.current);
    };
  }, []);

  return status;
}

// ── Component ──────────────────────────────────────────────

interface OfflineBannerProps {
  /** Override the detected network status (for testing / manual control). */
  forceOffline?: boolean;
}

export function OfflineBanner({ forceOffline }: OfflineBannerProps) {
  const detectedStatus = useNetworkStatus();
  const insets = useSafeAreaInsets();
  const slideAnim = useRef(new Animated.Value(-100)).current;

  const isOffline = forceOffline || detectedStatus === 'offline';

  useEffect(() => {
    Animated.timing(slideAnim, {
      toValue: isOffline ? 0 : -100,
      duration: 300,
      useNativeDriver: true,
    }).start();
  }, [isOffline, slideAnim]);

  if (!isOffline) return null;

  return (
    <Animated.View
      style={[
        styles.container,
        { paddingTop: insets.top + 4, transform: [{ translateY: slideAnim }] },
      ]}
      accessibilityRole="alert"
      accessibilityLiveRegion="assertive"
    >
      <View style={styles.inner}>
        <Text style={styles.icon}>📡</Text>
        <Text style={styles.text}>
          You are offline — showing cached data
        </Text>
      </View>
    </Animated.View>
  );
}

// ── Styles ─────────────────────────────────────────────────

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    zIndex: 9999,
    backgroundColor: '#f59e0b',
    paddingHorizontal: 16,
    paddingBottom: 8,
  },
  inner: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  icon: {
    fontSize: 16,
    marginRight: 8,
  },
  text: {
    color: '#1c1917',
    fontSize: 14,
    fontWeight: '600',
  },
});
