'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
  GoogleMap,
  Marker,
  useLoadScript,
} from '@react-google-maps/api';
import { MapPin } from 'lucide-react';
import { DAVAO_REGION_CENTER } from '@/lib/geocode';
import { MapPinDetail } from '@/components/map/MapPinDetail';

export interface MapMarker {
  id: string;
  type: 'job' | 'worker';
  lat: number;
  lng: number;
  title: string;
  subtitle?: string;
  href: string;
  category?: string;
  location?: string;
  budget?: string;
  serviceAreas?: string;
  rating?: number;
  /** Job-only fields */
  status?: string;
  postedAt?: string;
  dateNeeded?: string | null;
  /** Worker-only fields */
  portfolioImages?: { id: string; url: string; title?: string | null }[];
  portfolioCount?: number;
  avatarUrl?: string | null;
  firstName?: string;
  lastName?: string;
}

interface MapViewProps {
  markers: MapMarker[];
  className?: string;
  defaultCenter?: { lat: number; lng: number };
  defaultZoom?: number;
  /** Center on defaultCenter/defaultZoom instead of fitting all markers */
  focusOnRegion?: boolean;
}

const mapContainerStyle = { width: '100%', height: '100%' };

const mapOptions: google.maps.MapOptions = {
  disableDefaultUI: false,
  zoomControl: true,
  streetViewControl: false,
  mapTypeControl: false,
  fullscreenControl: true,
};

const JOB_ICON = 'http://maps.google.com/mapfiles/ms/icons/green-dot.png';
const WORKER_ICON = 'http://maps.google.com/mapfiles/ms/icons/orange-dot.png';

export function MapView({
  markers,
  className,
  defaultCenter,
  defaultZoom = 11,
  focusOnRegion = false,
}: MapViewProps) {
  const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY ?? '';
  const { isLoaded, loadError } = useLoadScript({
    googleMapsApiKey: apiKey,
    id: 'ehandyhire-google-maps',
    preventGoogleFontsLoading: true,
  });
  const [selected, setSelected] = useState<MapMarker | null>(null);
  const [authFailure, setAuthFailure] = useState(false);
  const mapRef = useRef<google.maps.Map | null>(null);

  useEffect(() => {
    const w = window as Window & { gm_authFailure?: () => void };
    const prev = w.gm_authFailure;
    w.gm_authFailure = () => setAuthFailure(true);
    return () => {
      w.gm_authFailure = prev;
    };
  }, []);

  const applyMapViewport = useCallback(
    (map: google.maps.Map) => {
      if (focusOnRegion && defaultCenter) {
        map.setCenter(defaultCenter);
        map.setZoom(defaultZoom);
        return;
      }

      if (markers.length > 1) {
        const bounds = new google.maps.LatLngBounds();
        markers.forEach((m) => bounds.extend({ lat: m.lat, lng: m.lng }));
        map.fitBounds(bounds, 48);
        return;
      }

      if (defaultCenter) {
        map.setCenter(defaultCenter);
        map.setZoom(defaultZoom);
      }
    },
    [defaultCenter, defaultZoom, focusOnRegion, markers]
  );

  useEffect(() => {
    if (!mapRef.current) return;
    applyMapViewport(mapRef.current);
  }, [applyMapViewport]);

  const onLoad = useCallback(
    (map: google.maps.Map) => {
      mapRef.current = map;
      applyMapViewport(map);
    },
    [applyMapViewport]
  );

  const center = useMemo(() => {
    if (focusOnRegion && defaultCenter) return defaultCenter;
    if (markers.length === 0) return defaultCenter ?? DAVAO_REGION_CENTER;
    const lat = markers.reduce((sum, m) => sum + m.lat, 0) / markers.length;
    const lng = markers.reduce((sum, m) => sum + m.lng, 0) / markers.length;
    return { lat, lng };
  }, [markers, defaultCenter, focusOnRegion]);

  const zoom = focusOnRegion && defaultCenter ? defaultZoom : 11;

  if (!apiKey) {
    return (
      <div className={`flex flex-col items-center justify-center rounded-lg border border-border bg-surface p-8 text-center ${className ?? ''}`}>
        <MapPin className="h-10 w-10 text-muted mb-3" />
        <p className="font-semibold text-slate-900">Google Maps API key required</p>
        <p className="text-sm text-muted mt-2 max-w-md">
          Add <code className="text-xs bg-slate-100 px-1 py-0.5 rounded">NEXT_PUBLIC_GOOGLE_MAPS_API_KEY</code> to the project root{' '}
          <code className="text-xs bg-slate-100 px-1 py-0.5 rounded">.env</code> file, then restart the dev server.
        </p>
      </div>
    );
  }

  if (loadError || authFailure) {
    const isBlocked = authFailure || loadError?.message?.includes('ApiTargetBlocked');
    return (
      <div className={`flex flex-col items-center justify-center rounded-lg border border-red-200 bg-red-50 p-8 text-center text-red-700 ${className ?? ''}`}>
        <p className="font-semibold">Google Maps could not load</p>
        {isBlocked ? (
          <div className="text-sm mt-3 max-w-md text-left space-y-2">
            <p>Your API key is blocked from using the <strong>Maps JavaScript API</strong>. Fix in Google Cloud Console:</p>
            <ol className="list-decimal list-inside space-y-1 text-xs">
              <li>Enable <strong>Maps JavaScript API</strong> (APIs &amp; Services → Library)</li>
              <li>Open your API key → <strong>API restrictions</strong></li>
              <li>Choose “Restrict key” and add <strong>Maps JavaScript API</strong>, or use “Don’t restrict key” while testing</li>
              <li>Under <strong>Application restrictions</strong>, add <code className="bg-red-100 px-1 rounded">http://localhost:3000/*</code></li>
              <li>Ensure <strong>billing</strong> is enabled on the project</li>
            </ol>
          </div>
        ) : (
          <p className="text-sm mt-2 max-w-md">
            {loadError?.message || 'Check your API key, billing, and that Maps JavaScript API is enabled.'}
          </p>
        )}
      </div>
    );
  }

  if (!isLoaded) {
    return (
      <div className={`flex flex-col items-center justify-center gap-3 rounded-lg border border-border bg-slate-50 ${className ?? ''}`}>
        <div className="loading-spinner" />
        <p className="text-sm text-muted">Loading Google Maps…</p>
      </div>
    );
  }

  return (
    <div className={`relative ${className ?? ''}`}>
      <GoogleMap
        mapContainerStyle={mapContainerStyle}
        center={center}
        zoom={zoom}
        options={mapOptions}
        onLoad={onLoad}
        onClick={() => setSelected(null)}
      >
        {markers.map((marker) => (
          <Marker
            key={`${marker.type}-${marker.id}`}
            position={{ lat: marker.lat, lng: marker.lng }}
            icon={marker.type === 'job' ? JOB_ICON : WORKER_ICON}
            onClick={() => setSelected(marker)}
          />
        ))}
      </GoogleMap>

      {selected && (
        <div className="absolute inset-x-3 bottom-3 z-10 md:inset-x-auto md:right-4 md:bottom-4 md:w-[340px] pointer-events-none">
          <div className="pointer-events-auto">
            <MapPinDetail marker={selected} onClose={() => setSelected(null)} />
          </div>
        </div>
      )}
    </div>
  );
}
