import React, { useEffect, useRef, useState, useCallback } from "react";
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  Image,
  ActivityIndicator,
  Alert,
} from "react-native";
import { WebView } from "react-native-webview";
import { useNavigation, useRoute } from "@react-navigation/native";
import { Back, AddressMarker } from "@src/utils/icons";
import { appColors } from "@src/themes";
import Images from "@utils/images";
import styles from "./styles";
import { useValues } from "@src/utils/context/index";
import { external } from "@src/styles/externalStyle";
import { useSelector } from "react-redux";
import useSmartLocation from "@src/components/helper/locationHelper";
import {
  arrayUnion,
  doc,
  getDoc,
  getFirestore,
  setDoc,
  updateDoc,
} from "firebase/firestore";
import { firebaseConfig } from "../../../../firebase";
import { initializeApp } from "@firebase/app";
import { HeaderContainer } from "@src/commonComponent";

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

export function AddressChange() {
  const { isDark, viewRTLStyle, Google_Map_Key } = useValues();
  const webViewRef = useRef<WebView>(null);
  const navigation = useNavigation();
  const route = useRoute();
  const { rideId, rideDatas } = route.params || {};
  const { currentLatitude, currentLongitude } = useSmartLocation();
  const [initialCoords, setInitialCoords] = useState<{
    latitude: number;
    longitude: number;
  } | null>(null);
  const [mapCenterCoords, setMapCenterCoords] = useState<{
    latitude: number;
    longitude: number;
  } | null>(null);
  const [currentAddress, setCurrentAddress] = useState("");
  const [loadingMap, setLoadingMap] = useState(true);
  const [fetchingAddress, setFetchingAddress] = useState(false);
  const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
  const { translateData, taxidoSettingData } = useSelector(
    (state: any) => state.setting
  );
  const mapType = taxidoSettingData?.cabbooking_values?.location?.map_provider;

  useEffect(() => {
    const lat = currentLatitude;
    const lon = currentLongitude;

    if (lat && lon) {
      const coords = { latitude: lat, longitude: lon };
      setInitialCoords(coords);
      setMapCenterCoords(coords);
      setLoadingMap(false);
    } else {
      setLoadingMap(false);
    }
  }, [currentLatitude, currentLongitude]);

  useEffect(() => {
    if (mapCenterCoords) {
      if (debounceTimerRef?.current) clearTimeout(debounceTimerRef?.current);

      debounceTimerRef.current = setTimeout(() => {
        fetchAddress(mapCenterCoords?.latitude, mapCenterCoords?.longitude);
      }, 800);
    }
    // Cleanup timer on component unmount
    return () => {
      if (debounceTimerRef?.current) clearTimeout(debounceTimerRef?.current);
    };
  }, [mapCenterCoords, fetchAddress]);

  const fetchAddress = useCallback(
    async (lat, lng) => {
      if (!Google_Map_Key) {
        setCurrentAddress("Configuration error: Missing API Key.");
        return;
      }

      setFetchingAddress(true);
      try {
        let response = await fetch(
          `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${Google_Map_Key}&result_type=street_address|route|intersection`
        );
        let json = await response.json();

        if (json.status === "OK" && json.results.length === 0) {
          response = await fetch(
            `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${Google_Map_Key}`
          );
          json = await response.json();
        }

        if (json.status === "OK" && json.results.length > 0) {
          const bestResult = json.results[0];
          const cleanedAddress = bestResult?.formatted_address;
          setCurrentAddress(cleanedAddress);
        } else {
          setCurrentAddress("Could not find address for this location.");
        }
      } catch (error) {
        setCurrentAddress("Failed to connect to address service.");
      } finally {
        setFetchingAddress(false);
      }
    },
    [Google_Map_Key]
  );

  const handleWebViewMessage = (event: any) => {
    const data = JSON.parse(event?.nativeEvent?.data);
    if (data?.type === "mapMove") {
      const { lat, lng } = data?.payload;
      setMapCenterCoords({ latitude: lat, longitude: lng });
    }
  };

  const handleConfirmLocation = async () => {
    if (!currentAddress || !mapCenterCoords || fetchingAddress) {
      Alert.alert(
        "Location Not Ready",
        "Please wait for the address to load or select a valid location."
      );
      return;
    }

    try {
      const rideRef = doc(db, "rides", rideId.toString());

      // Pickup
      const pickupCoords = rideDatas?.location_coordinates?.[0] || {
        lat: mapCenterCoords.latitude.toString(),
        lng: mapCenterCoords.longitude.toString(),
      };
      const pickupLocation = rideDatas?.locations?.[0] || "Pickup Point";

      // Driver live location
      const driverId = rideDatas?.driver?.id;
      if (!driverId) {
        Alert.alert("Error", "Driver ID not available");
        return;
      }

      const driverTrackRef = doc(db, "driverTrack", driverId.toString());
      const driverSnap = await getDoc(driverTrackRef);

      if (!driverSnap.exists()) {
        Alert.alert("Error", "Driver location not found.");
        return;
      }

      const driverData = driverSnap.data();
      const driverLat = driverData?.lat?.toString();
      const driverLng = driverData?.lng?.toString();

      if (!driverLat || !driverLng) {
        Alert.alert("Error", "Invalid driver coordinates.");
        return;
      }

      // Updated arrays
      const updatedCoords = [
        pickupCoords, // pickup
        { lat: driverLat, lng: driverLng }, // driver live
        {
          lat: mapCenterCoords.latitude.toString(),
          lng: mapCenterCoords.longitude.toString(),
        }, // destination
      ];

      const updatedLocations = [
        pickupLocation, // pickup
        "Change Point", // driver live
        currentAddress, // destination
      ];

      await updateDoc(rideRef, {
        location_coordinates: updatedCoords,
        locations: updatedLocations,
      });

      navigation.navigate("Payment", { rideId });
    } catch (error) {
      Alert.alert("Error", "Failed to update location. Please try again.");
    }
  };

  const getMapHTML = (
    coords: { latitude: number; longitude: number },
    mapType: string
  ) => {
    if (mapType === "osm") {
      const darkTileUrl =
        "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png";
      const lightTileUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
      const tileUrl = isDark ? darkTileUrl : lightTileUrl;

      return `
      <!DOCTYPE html>
      <html>
      <head>
          <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
          <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
          <style>
            body, html, #map {
              margin: 0;
              padding: 0;
              height: 100%;
              width: 100%;
              background-color: ${isDark ? "#000" : "#fff"};
            }
          </style>
      </head>
      <body>
          <div id="map"></div>
          <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
          <script>
              function initMap() {
                  const map = L.map('map', {
                      center: [${coords?.latitude}, ${coords?.longitude}],
                      zoom: 16,
                      zoomControl: false
                  });

                  L.tileLayer('${tileUrl}', {
                      attribution: '© OpenStreetMap contributors'
                  }).addTo(map);

                  map.on('moveend', function() {
                      const center = map.getCenter();
                      const message = {
                          type: 'mapMove',
                          payload: { lat: center.lat, lng: center.lng }
                      };
                      window.ReactNativeWebView.postMessage(JSON.stringify(message));
                  });
              }
              initMap();
          </script>
      </body>
      </html>
    `;
    }

    // Google Maps implementation (existing code)
    const darkTheme = [
      { elementType: "geometry", stylers: [{ color: "#212121" }] },
      { elementType: "labels.icon", stylers: [{ visibility: "off" }] },
      { elementType: "labels.text.fill", stylers: [{ color: "#757575" }] },
      { elementType: "labels.text.stroke", stylers: [{ color: "#212121" }] },
      {
        featureType: "administrative",
        elementType: "geometry",
        stylers: [{ color: "#757575" }],
      },
      {
        featureType: "poi",
        elementType: "geometry",
        stylers: [{ color: "#282828" }],
      },
      {
        featureType: "poi.park",
        elementType: "geometry",
        stylers: [{ color: "#181818" }],
      },
      {
        featureType: "road",
        elementType: "geometry.fill",
        stylers: [{ color: "#2c2c2c" }],
      },
      {
        featureType: "road",
        elementType: "labels.text.fill",
        stylers: [{ color: "#8a8a8a" }],
      },
      {
        featureType: "transit",
        elementType: "geometry",
        stylers: [{ color: "#2f2f2f" }],
      },
      {
        featureType: "water",
        elementType: "geometry",
        stylers: [{ color: "#000000" }],
      },
      {
        featureType: "water",
        elementType: "labels.text.fill",
        stylers: [{ color: "#3d3d3d" }],
      },
    ];

    const mapThemeStyles = isDark ? darkTheme : [];
    return `
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <style>
          body, html, #map {
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
            background-color: ${isDark ? "#000" : "#fff"};
          }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script>
            function initMap() {
                const map = new google.maps.Map(document.getElementById('map'), {
                    center: { lat: ${coords?.latitude}, lng: ${coords?.longitude
      } },
                    zoom: 16,
                    disableDefaultUI: true,
                    styles: ${JSON.stringify(mapThemeStyles)}
                });

                map.addListener('idle', () => {
                    const center = map.getCenter();
                    const message = {
                        type: 'mapMove',
                        payload: { lat: center.lat(), lng: center.lng() }
                    };
                    window.ReactNativeWebView.postMessage(JSON.stringify(message));
                });
            }
        </script>
        <script async defer src="https://maps.googleapis.com/maps/api/js?key=${Google_Map_Key}&callback=initMap"></script>
    </body>
    </html>
  `;
  };

  // --- RENDER ---
  return (
    <View
      style={[
        external.main,
        {
          backgroundColor: isDark
            ? appColors.solidBorder
            : appColors.whiteColor,
        },
      ]}
    >
      <HeaderContainer />

      {loadingMap ? (
        <View style={styles.loaderContainer}>
          <ActivityIndicator size="large" color={appColors.primary} />
        </View>
      ) : initialCoords ? (
        <>
          <WebView
            ref={webViewRef}
            style={styles.mapView}
            source={{ html: getMapHTML(initialCoords, mapType) }}
            onMessage={handleWebViewMessage}
            javaScriptEnabled
            domStorageEnabled
            originWhitelist={["*"]}
          />
          <View style={styles.pointerMarker} pointerEvents="none">
            <Image source={Images.pin} style={styles.pinImage} />
          </View>
        </>
      ) : (
        <View style={styles.loaderContainer}>
          <ActivityIndicator size="large" color={appColors.primary} />
        </View>
      )}

      <View
        style={[
          styles.textInputContainer,
          {
            backgroundColor: isDark
              ? appColors.darkPrimary
              : appColors.whiteColor,
            flexDirection: viewRTLStyle,
            borderColor: isDark ? appColors.darkBorder : appColors.border,
          },
        ]}
      >
        <View
          style={[
            styles.addressBtnView,
            {
              backgroundColor: isDark ? appColors.bgDark : appColors.whiteColor,
            },
          ]}
        >
          <AddressMarker />
        </View>
        <TextInput
          style={[
            styles.textInput,
            { color: isDark ? appColors.whiteColor : appColors.blackColor },
          ]}
          value={
            fetchingAddress
              ? translateData?.locating
              : currentAddress || `${translateData?.moveMap}`
          }
          editable={false}
          multiline
        />
      </View>

      <TouchableOpacity
        style={[
          styles.confirmButton,
          {
            backgroundColor: isDark
              ? appColors.whiteColor
              : appColors.blackColor,
          },
        ]}
        onPress={handleConfirmLocation}
        disabled={fetchingAddress || loadingMap || !currentAddress}
        activeOpacity={0.8}
      >
        {fetchingAddress ? (
          <ActivityIndicator size="large" color={appColors.whiteColor} />
        ) : (
          <Text
            style={[
              styles.confirmText,
              { color: isDark ? appColors.blackColor : appColors.whiteColor },
            ]}
          >
            {translateData.confirmLocation || "Confirm Location"}
          </Text>
        )}
      </TouchableOpacity>
    </View>
  );
}
