import React, { useState, useEffect } from 'react';
import { View, Text, Alert, BackHandler } from 'react-native';
import { useAppTheme } from '@theme';
import { PrimaryButton, MapViewComponent } from '@components';
import { useAppDispatch, useAppSelector } from '@store';
import { advanceJobStatus } from '@store/commonReducers/job';
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { AppStackParamList } from '@navigation/navigationTypes';
import { RouteNames, JobStatus } from '@utils/constants';
import { getStyles } from './liveTrackingScreen.styles';
import { Coordinates } from '@app-types/index';
import {
  requestLocationPermission,
  showPermissionDeniedAlert,
  getCurrentPosition,
  getHaversineDistance,
} from '@services/locationService';
import { socketService } from '@services/socketService';
import Geolocation from 'react-native-geolocation-service';

export const LiveTrackingScreen: React.FC = () => {
  const { colors } = useAppTheme();
  const styles = getStyles(colors);
  const dispatch = useAppDispatch();
  const navigation =
    useNavigation<NativeStackNavigationProp<AppStackParamList>>();
  const route =
    useRoute<RouteProp<AppStackParamList, RouteNames.LiveTracking>>();
  const { jobId } = route.params;

  const { activeDeliveries } = useAppSelector(state => state.deliveries);
  const activeJob = activeDeliveries?.delivery;

  const [currentLocation, setCurrentLocation] = useState<Coordinates | null>(
    null,
  );
  const [distance, setDistance] = useState<number | null>(null);
  const [speed, setSpeed] = useState<number>(24); // default speed in km/h

  // Block the hardware back button — once delivery starts the partner
  // must not navigate back to the OrderPickedUp screen.
  // useEffect(() => {
  //   const onBackPress = () => true; // return true = event consumed, back suppressed
  //   const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress);
  //   return () => subscription.remove();
  // }, []);

  useEffect(() => {
    let watchId: number | null = null;

    const startTracking = async () => {
      try {
        const hasPermission = await requestLocationPermission();
        if (!hasPermission) {
          showPermissionDeniedAlert();
          return;
        }

        // Get initial current position
        const initialPos = await getCurrentPosition();
        setCurrentLocation(initialPos);

        // Send initial location update to socket
        socketService.updateLocation(initialPos);

        // Start watching position
        watchId = Geolocation.watchPosition(
          position => {
            const coords: Coordinates = {
              latitude: position.coords.latitude,
              longitude: position.coords.longitude,
            };
            setCurrentLocation(coords);

            // Emit location update via socket safely
            try {
              socketService.updateLocation(coords);
            } catch (err) {
              console.warn('Socket location update error:', err);
            }

            // Update speed if available (speed in m/s from GPS)
            if (position.coords.speed !== null && position.coords.speed > 0) {
              const speedKmH = position.coords.speed * 3.6;
              setSpeed(Math.max(speedKmH, 10)); // keep speed at least 10 km/h for a realistic ETA
            }
          },
          error => {
            console.error('watchPosition error:', error);
          },
          {
            enableHighAccuracy: true,
            distanceFilter: 10, // every 10 meters
            interval: 5000,
            fastestInterval: 2000,
          },
        );
      } catch (error) {
        console.error('Error starting location tracking:', error);
      }
    };

    startTracking();

    return () => {
      if (watchId !== null) {
        Geolocation.clearWatch(watchId);
      }
    };
  }, []);

  // Compute live distance to drop-off address
  useEffect(() => {
    if (currentLocation && activeJob?.order?.dropAddress) {
      const dropCoords = {
        latitude: activeJob.order.dropAddress.latitude,
        longitude: activeJob.order.dropAddress.longitude,
      };
      const km = getHaversineDistance(currentLocation, dropCoords);
      setDistance(km);
    }
  }, [currentLocation, activeJob?.order?.dropAddress]);

  const handleArrived = () => {
    dispatch(advanceJobStatus(JobStatus.ArrivedAtCustomer));
    navigation.navigate(RouteNames.DeliverOrder, {
      jobId: jobId,
    });
  };

  const handleContact = () => {
    Alert.alert(
      'Contact Customer',
      `Calling ${activeJob?.order?.customer?.user?.name || 'Customer'} at ${
        activeJob?.order?.customer?.user?.phone
      } `,
    );
  };

  // Calculate ETA in minutes based on distance and speed (distance / speed * 60)
  const etaMinutes =
    distance !== null ? Math.max(Math.round((distance / speed) * 60), 1) : null;

  return (
    <View style={styles.container}>
      {/* Top Floating ETA Card */}
      <View style={styles.etaCard}>
        <Text style={styles.etaTitle}>
          {etaMinutes !== null
            ? `Arriving in ${etaMinutes} mins`
            : 'Calculating ETA…'}
        </Text>
        <Text style={styles.etaSub}>
          Distance: {distance !== null ? `${distance.toFixed(2)} km` : '...'} •
          Speed: {Math.round(speed)} km/h
        </Text>
      </View>

      {/* Map Content */}
      {activeJob?.order?.dropAddress ? (
        <MapViewComponent
          currentLocation={currentLocation || undefined}
          origin={currentLocation || undefined}
          destination={activeJob.order.dropAddress}
          showRoute={!!currentLocation}
          style={styles.mapPlaceholder}
        />
      ) : (
        <View style={styles.mapPlaceholder}>
          <Text style={styles.placeholderText}>Loading Map...</Text>
        </View>
      )}

      {/* Customer Location Bottom Card */}
      <View style={styles.bottomCard}>
        <Text style={styles.cardTitle}>Deliver to</Text>
        <Text style={styles.customerName}>
          {activeJob?.order?.customer?.user?.name}
        </Text>
        <Text style={styles.customerAddress}>
          {activeJob?.order?.dropAddress
            ? `${activeJob.order.dropAddress.houseNumber}, ${activeJob.order.dropAddress.addressLine1}`
            : 'Loading address...'}
        </Text>

        <View style={styles.btnRow}>
          <PrimaryButton
            title="Call"
            onPress={handleContact}
            style={styles.contactBtn}
            textStyle={{ color: colors.text }}
          />
          <PrimaryButton
            title="Arrived at Location"
            onPress={handleArrived}
            style={styles.arrivedBtn}
          />
        </View>
      </View>
    </View>
  );
};

export default LiveTrackingScreen;
