import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  ActivityIndicator,
  InteractionManager,
} from 'react-native';
import MapView, { Marker, Region } from 'react-native-maps';
import { useNavigation } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import { getStyles } from './setLocationScreen.styles';
import { PrimaryButton } from '@components';
import { useAppTheme } from '@theme';
import {
  DEFAULT_LOCATION,
  getCurrentLocationWithAddress,
  reverseGeocode,
  showPermissionDeniedAlert,
  LatLng,
} from '../../../services/locationServices';
import { useAppDispatch } from '@store';
import { setLocationData } from './reducer';
import { OnboardingStackParamList } from '@navigation/onboardingStack';

type NavProp = StackNavigationProp<
  OnboardingStackParamList,
  'SetLocationScreen'
>;

const DELTA = { latitudeDelta: 0.006, longitudeDelta: 0.006 };

export const SetLocationScreen: React.FC = () => {
  const { colors } = useAppTheme();
  const styles = getStyles(colors);
  const navigation = useNavigation<NavProp>();
  const dispatch = useAppDispatch();
  const mapRef = useRef<MapView>(null);
  // Guard: never call setState after the component has unmounted
  const isMounted = useRef(true);

  const [coords, setCoords] = useState<LatLng>(DEFAULT_LOCATION);
  const [address, setAddress] = useState('Fetching your location…');
  const [city, setCity] = useState('');
  const [state, setState] = useState('');
  const [postalCode, setPostalCode] = useState('');
  const [loading, setLoading] = useState(true);

  // ------------------------------------------------------------------
  // Fetch current location on mount
  // ------------------------------------------------------------------
  const fetchCurrentLocation = useCallback(async () => {
    if (!isMounted.current) return;
    setLoading(true);
    try {
      console.log('--------------');
      const result = await getCurrentLocationWithAddress();
      console.log('result', result);
      if (!isMounted.current) return;
      setCoords(result.coords);
      setAddress(result.address);
      setCity(result.city || '');
      setState(result.state || '');
      setPostalCode(result.postalCode || '');

      // Animate the map to the user's location
      mapRef.current?.animateToRegion({ ...result.coords, ...DELTA }, 600);
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : '';
      if (message === 'Location permission denied') {
        // Show the alert here — safe, outside the Promise chain
        showPermissionDeniedAlert();
      }
      console.log('--------error------', err);
      if (!isMounted.current) return;
      setAddress('Could not determine location');
    } finally {
      if (isMounted.current) setLoading(false);
    }
  }, []);

  useEffect(() => {
    // Wait for the screen-transition animation to fully finish before
    // calling PermissionsAndroid.request(). Calling it while the Activity
    // is still transitioning causes a native crash on Android.
    const task = InteractionManager.runAfterInteractions(() => {
      fetchCurrentLocation();
    });
    return () => {
      task.cancel();
      isMounted.current = false;
    };
  }, [fetchCurrentLocation]);

  // ------------------------------------------------------------------
  // When user drags the map, update the marker + address
  // ------------------------------------------------------------------
  const handleRegionChangeComplete = useCallback(async (region: Region) => {
    const newCoords: LatLng = {
      latitude: region.latitude,
      longitude: region.longitude,
    };
    setCoords(newCoords);
    setAddress('Fetching address…');
    setCity('');
    setState('');
    setPostalCode('');

    const geocodeResult = await reverseGeocode(newCoords);
    setAddress(geocodeResult.address);
    setCity(geocodeResult.city);
    setState(geocodeResult.state);
    setPostalCode(geocodeResult.postalCode);
  }, []);

  return (
    <View style={styles.container}>
      {/* ---------- Map ---------- */}
      <MapView
        ref={mapRef}
        style={styles.map}
        initialRegion={{ ...DEFAULT_LOCATION, ...DELTA }}
        onRegionChangeComplete={handleRegionChangeComplete}
      >
        <Marker
          coordinate={coords}
          title="Your Location"
          description={address}
        />
      </MapView>

      {/* ---------- "Locate me" floating button ---------- */}
      <TouchableOpacity
        style={styles.locateButton}
        activeOpacity={0.8}
        onPress={fetchCurrentLocation}
      >
        <Text style={styles.locateIcon}>📍</Text>
      </TouchableOpacity>

      {/* ---------- Bottom sheet ---------- */}
      <View style={styles.bottomSheet}>
        <View style={styles.sheetHandle} />

        <View style={styles.card}>
          <View style={styles.cardHeader}>
            <Text style={styles.cardIcon}>📍</Text>
            <Text style={styles.cardTitle}>My Location</Text>
          </View>

          {loading ? (
            <ActivityIndicator
              size="small"
              color={colors.primary}
              style={{ marginVertical: 12 }}
            />
          ) : (
            <Text style={styles.cardAddress} numberOfLines={2}>
              {address}
            </Text>
          )}

          <TouchableOpacity style={styles.changeLink} activeOpacity={0.7}>
            <Text style={styles.changeText}>Change</Text>
          </TouchableOpacity>
        </View>

        <PrimaryButton
          title="Confirm Location"
          onPress={() => {
            dispatch(
              setLocationData({
                latitude: coords.latitude,
                longitude: coords.longitude,
                mapAddress: address,
                city,
                state,
                postalCode,
              }),
            );
            navigation.navigate('CompleteProfileScreen');
          }}
          style={styles.confirmButton}
        />

        <TouchableOpacity
          style={styles.manualButton}
          onPress={() => navigation.navigate('CompleteProfileScreen')}
          activeOpacity={0.7}
        >
          <Text style={styles.manualButtonText}>Enter address manually</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};
