import { useRef } from "react";
import { Image, StyleSheet, View } from "react-native";
import MapView, { PROVIDER_DEFAULT, type Region } from "react-native-maps";

import { icons } from "@/constants";
import { useTheme } from "@/lib/theme";

// Fine-tuning a pickup or drop-off point.
//
// The pin does NOT move — the map moves under it. Dragging a marker means
// fighting for a few pixels with the same thumb that pans the map, and on a
// phone the marker spends most of the gesture hidden under the finger holding
// it. Anchoring the pin to the centre of the screen and sliding the map
// underneath makes the target the one thing always visible, which is why every
// ride-hailing app converged on it.
//
// The component is deliberately dumb: it reports the centre when the map
// settles and nothing else. Reverse geocoding, debouncing and confirmation all
// live on the screen, so this stays reusable for the origin and the
// destination alike.

export type PinAdjusterProps = {
  initial: { latitude: number; longitude: number };
  /** Fired when the map stops moving, with the coordinate under the pin. */
  onSettled: (coords: { latitude: number; longitude: number }) => void;
  /** Fired as soon as a drag starts, to clear a now-stale address label. */
  onMoveStart?: () => void;
};

// Tight enough that the rider is choosing a doorway, not a district.
const ZOOM_DELTA = 0.004;

const styles = StyleSheet.create({
  map: StyleSheet.absoluteFillObject,
  // Sits above the map and ignores touches, so panning still reaches the map.
  pinLayer: {
    ...StyleSheet.absoluteFillObject,
    alignItems: "center",
    justifyContent: "center",
  },
  pin: {
    width: 36,
    height: 36,
    // The pin's point is at its bottom edge, but the coordinate we report is
    // the centre of the screen — so lift it by its own height to put the tip,
    // not the middle of the graphic, on the spot being chosen.
    marginBottom: 36,
  },
  // A small ground marker under the tip: without it, on a busy map, it is
  // genuinely hard to tell which pixel the pin is pointing at.
  dot: {
    position: "absolute",
    width: 8,
    height: 8,
    borderRadius: 4,
    backgroundColor: "rgba(2,134,255,0.9)",
    borderWidth: 1,
    borderColor: "#ffffff",
  },
});

export const PinAdjuster = ({
  initial,
  onSettled,
  onMoveStart,
}: PinAdjusterProps) => {
  const { isDark } = useTheme();
  const mapRef = useRef<MapView>(null);

  const region: Region = {
    latitude: initial.latitude,
    longitude: initial.longitude,
    latitudeDelta: ZOOM_DELTA,
    longitudeDelta: ZOOM_DELTA,
  };

  return (
    <View style={StyleSheet.absoluteFill}>
      <MapView
        ref={mapRef}
        provider={PROVIDER_DEFAULT}
        style={styles.map}
        initialRegion={region}
        showsUserLocation
        showsMyLocationButton={false}
        userInterfaceStyle={isDark ? "dark" : "light"}
        onPanDrag={onMoveStart}
        onRegionChangeComplete={(next) =>
          onSettled({ latitude: next.latitude, longitude: next.longitude })
        }
      />

      <View style={styles.pinLayer} pointerEvents="none">
        <Image source={icons.pin} style={styles.pin} resizeMode="contain" />
        <View style={styles.dot} />
      </View>
    </View>
  );
};
