'use client';

import { Panel, StatusBadge } from '@chego/ui';
import { io, type Socket } from 'socket.io-client';
import { useEffect, useRef, useState } from 'react';
import { publicApiBase, readOrderState } from '../lib/public-order-store';
import { PublicFlowNav } from '../public-flow-nav';

declare global {
  interface Window {
    google?: {
      maps?: any;
    };
  }
}

type TrackingPayload = {
  orderId: string;
  status: string;
  trackingStatusLabel: string;
  restaurant: { name: string; latitude?: number | string | null; longitude?: number | string | null };
  customer: { name: string; latitude?: number | string | null; longitude?: number | string | null };
  driver: { name: string; rating?: number | null; vehiclePlate?: string | null; vehicleModel?: string | null } | null;
  delivery: { status: string; etaMinutes?: number | null } | null;
  route: {
    estimatedPickupTime?: number | null;
    estimatedDeliveryTime?: number | null;
    status?: string;
    encodedPolylineToRestaurant?: string | null;
    encodedPolylineToCustomer?: string | null;
  } | null;
  latestLocation: { latitude: number | string; longitude: number | string; createdAt?: string } | null;
};

const wsUrl = process.env.NEXT_PUBLIC_WS_URL ?? 'http://localhost:3001';
const googleMapsKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY ?? '';
let mapsLoader: Promise<NonNullable<Window['google']>> | null = null;

function toneFromStatus(status?: string | null) {
  if (status === 'DELIVERED') return 'emerald';
  if (status === 'DRIVER_ACCEPTED' || status === 'ON_THE_WAY' || status === 'PICKED_UP') return 'amber';
  if (status === 'CANCELLED') return 'rose';
  return 'sky';
}

function toCoordinate(latitude?: number | string | null, longitude?: number | string | null) {
  const lat = latitude === null || latitude === undefined || latitude === '' ? NaN : Number(latitude);
  const lng = longitude === null || longitude === undefined || longitude === '' ? NaN : Number(longitude);
  if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
    return null;
  }
  return { lat, lng };
}

async function loadGoogleMaps(apiKey: string) {
  if (!apiKey) {
    throw new Error('NEXT_PUBLIC_GOOGLE_MAPS_API_KEY nao configurada.');
  }
  if (window.google?.maps) {
    return window.google;
  }
  if (!mapsLoader) {
    mapsLoader = new Promise((resolve, reject) => {
      const existing = document.querySelector<HTMLScriptElement>('script[data-google-maps-public="1"]');
      if (existing) {
        existing.addEventListener('load', () => {
          if (window.google?.maps) resolve(window.google);
        });
        existing.addEventListener('error', () => reject(new Error('Falha ao carregar Google Maps.')));
        return;
      }

      const script = document.createElement('script');
      script.src = `https://maps.googleapis.com/maps/api/js?key=${encodeURIComponent(apiKey)}&libraries=geometry`;
      script.async = true;
      script.defer = true;
      script.dataset.googleMapsPublic = '1';
      script.onload = () => {
        if (window.google?.maps) {
          resolve(window.google);
          return;
        }
        reject(new Error('Google Maps nao inicializado.'));
      };
      script.onerror = () => reject(new Error('Falha ao carregar Google Maps.'));
      document.head.appendChild(script);
    });
  }
  return mapsLoader;
}

export default function PublicOrderTrackingPage() {
  const mapRef = useRef<HTMLDivElement | null>(null);
  const [tracking, setTracking] = useState<TrackingPayload | null>(null);
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(true);
  const [mapError, setMapError] = useState('');

  useEffect(() => {
    const state = readOrderState();
    const orderId = state.lastOrder?.id;
    const phone = state.checkout.phone;

    if (!orderId || !phone) {
      setError('Nenhum pedido publico recente foi encontrado neste navegador.');
      setLoading(false);
      return;
    }

    let active = true;

    const load = async () => {
      try {
        const response = await fetch(`${publicApiBase}/tracking/public/${orderId}?phone=${encodeURIComponent(phone)}`, {
          cache: 'no-store',
        });
        const payload = await response.json().catch(() => null);
        if (!response.ok) {
          throw new Error(payload?.message ?? 'Falha ao carregar rastreio publico.');
        }
        if (!active) return;
        setTracking(payload as TrackingPayload);
        setError('');
      } catch (err) {
        if (!active) return;
        setError(err instanceof Error ? err.message : 'Falha ao carregar rastreio publico.');
      } finally {
        if (active) setLoading(false);
      }
    };

    void load();

    const socket: Socket = io(wsUrl, { transports: ['websocket', 'polling'] });
    socket.on('connect', () => {
      socket.emit('orders.subscribe', { orderId });
    });
    ['driver.assigned', 'driver.found', 'driver.location.updated', 'eta.updated', 'route.updated', 'order.picked_up', 'order.delivered'].forEach((eventName) => {
      socket.on(eventName, () => {
        void load();
      });
    });

    return () => {
      active = false;
      socket.disconnect();
    };
  }, []);

  useEffect(() => {
    if (!mapRef.current || !tracking || !googleMapsKey) {
      return;
    }

    const restaurant = toCoordinate(tracking.restaurant.latitude, tracking.restaurant.longitude);
    const customer = toCoordinate(tracking.customer.latitude, tracking.customer.longitude);
    const driver = toCoordinate(tracking.latestLocation?.latitude, tracking.latestLocation?.longitude);
    const points = [restaurant, customer, driver].filter(Boolean) as Array<{ lat: number; lng: number }>;
    if (!points.length) {
      setMapError('Mapa indisponivel ate existirem coordenadas validas para rota e rastreio.');
      return;
    }

    let cancelled = false;

    const renderMap = async () => {
      try {
        const googleApi = await loadGoogleMaps(googleMapsKey);
        if (cancelled || !mapRef.current) {
          return;
        }

        const center = {
          lat: points.reduce((sum, point) => sum + point.lat, 0) / points.length,
          lng: points.reduce((sum, point) => sum + point.lng, 0) / points.length,
        };

        const map = new googleApi.maps.Map(mapRef.current, {
          center,
          zoom: 13,
          styles: [
            { elementType: 'geometry', stylers: [{ color: '#0f172a' }] },
            { elementType: 'labels.text.fill', stylers: [{ color: '#cbd5e1' }] },
            { elementType: 'labels.text.stroke', stylers: [{ color: '#020617' }] },
            { featureType: 'road', elementType: 'geometry', stylers: [{ color: '#1e293b' }] },
            { featureType: 'water', elementType: 'geometry', stylers: [{ color: '#111827' }] },
          ],
          disableDefaultUI: true,
        });

        const bounds = new googleApi.maps.LatLngBounds();
        points.forEach((point) => bounds.extend(point));

        if (restaurant) {
          new googleApi.maps.Marker({
            position: restaurant,
            map,
            title: tracking.restaurant.name,
            label: { text: 'L', color: '#fff' },
          });
        }
        if (customer) {
          new googleApi.maps.Marker({
            position: customer,
            map,
            title: tracking.customer.name,
            label: { text: 'C', color: '#fff' },
          });
        }
        if (driver) {
          new googleApi.maps.Marker({
            position: driver,
            map,
            title: tracking.driver?.name ?? 'Entregador',
            label: { text: 'E', color: '#fff' },
            icon: {
              path: googleApi.maps.SymbolPath.CIRCLE,
              scale: 9,
              fillColor: '#f97316',
              fillOpacity: 1,
              strokeColor: '#ffffff',
              strokeWeight: 2,
            },
          });
        }

        const encodedPath = tracking.delivery?.status === 'PICKED_UP' || tracking.delivery?.status === 'ON_THE_WAY'
          ? tracking.route?.encodedPolylineToCustomer
          : tracking.route?.encodedPolylineToRestaurant;

        const path = encodedPath && googleApi.maps.geometry?.encoding
          ? googleApi.maps.geometry.encoding.decodePath(encodedPath)
          : [driver, tracking.delivery?.status === 'PICKED_UP' || tracking.delivery?.status === 'ON_THE_WAY' ? customer : restaurant].filter(Boolean);

        if (path.length >= 2) {
          new googleApi.maps.Polyline({
            path,
            geodesic: true,
            strokeColor: '#f97316',
            strokeOpacity: 0.95,
            strokeWeight: 4,
            map,
          });
        }

        if (!bounds.isEmpty()) {
          map.fitBounds(bounds, 72);
        }
        setMapError('');
      } catch (loadError) {
        setMapError(loadError instanceof Error ? loadError.message : 'Falha ao carregar mapa.');
      }
    };

    void renderMap();

    return () => {
      cancelled = true;
    };
  }, [tracking]);

  return (
    <main className="min-h-screen bg-[#e7edf3] px-4 py-6 text-slate-950 lg:px-8 lg:py-8">
      <div className="mx-auto max-w-6xl space-y-6">
        <PublicFlowNav />

        <section
          className="overflow-hidden rounded-[2rem] border border-white/10 bg-cover bg-center shadow-[0_32px_90px_rgba(2,6,23,0.35)]"
          style={{ backgroundImage: "linear-gradient(120deg, rgba(2,6,23,0.92), rgba(15,23,42,0.78)), url('/brand/chego-hero.jpeg')" }}
        >
          <div className="p-6 text-white lg:p-8">
            <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
              <div>
                <p className="text-xs font-black uppercase tracking-[0.28em] text-orange-300">Tracking publico</p>
                <h1 className="mt-3 text-4xl font-black tracking-tight">Acompanhe sua entrega com mapa e ETA</h1>
                <p className="mt-3 max-w-3xl text-sm leading-7 text-slate-200">Tela pratica, rapida e segura. O cliente ve apenas o pedido dele e o rastreio so abre com telefone validado.</p>
              </div>
              <div className="flex flex-wrap gap-3">
                <StatusBadge tone={toneFromStatus(tracking?.status)}>{tracking?.trackingStatusLabel ?? 'Aguardando'}</StatusBadge>
                <StatusBadge tone="amber">ETA {tracking?.delivery?.etaMinutes ?? tracking?.route?.estimatedDeliveryTime ?? '--'} min</StatusBadge>
              </div>
            </div>
          </div>
        </section>

        {error ? <section className="rounded-[1.4rem] border border-rose-200 bg-rose-50 px-5 py-4 text-sm text-rose-700">{error}</section> : null}

        <section className="grid gap-6 lg:grid-cols-[1.15fr_0.85fr]">
          <Panel title="Mapa da entrega" eyebrow="Rota ao vivo">
            <div className="space-y-4">
              <div ref={mapRef} className="h-[360px] rounded-[1.5rem] border border-slate-200 bg-slate-950" />
              {!googleMapsKey ? (
                <div className="rounded-[1.2rem] border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
                  Configure `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY` para habilitar o mapa real do cliente.
                </div>
              ) : null}
              {mapError ? (
                <div className="rounded-[1.2rem] border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600">{mapError}</div>
              ) : null}
            </div>
          </Panel>

          <Panel title="Linha da entrega" eyebrow="Status protegido">
            <div className="space-y-3 text-sm text-slate-700">
              <div className="rounded-[1.25rem] border border-slate-200 bg-slate-50 p-4">
                <p className="text-base font-black text-slate-950">Pedido {tracking?.orderId?.slice(0, 10) ?? '--'}</p>
                <p className="mt-1">Loja: {tracking?.restaurant.name ?? '--'}</p>
                <p className="mt-1">Cliente: {tracking?.customer.name ?? '--'}</p>
              </div>
              <div className="rounded-[1.25rem] border border-emerald-200 bg-emerald-50 p-4">
                Status atual: <strong>{tracking?.trackingStatusLabel ?? 'Aguardando'}</strong>.
              </div>
              <div className="rounded-[1.25rem] border border-sky-200 bg-sky-50 p-4">
                Ultima localizacao: <strong>{tracking?.latestLocation ? `${Number(tracking.latestLocation.latitude).toFixed(5)} / ${Number(tracking.latestLocation.longitude).toFixed(5)}` : 'sem ping de GPS'}</strong>.
              </div>
              <div className="rounded-[1.25rem] border border-orange-200 bg-orange-50 p-4">
                ETA coleta: <strong>{tracking?.route?.estimatedPickupTime ?? '--'} min</strong> • ETA entrega: <strong>{tracking?.route?.estimatedDeliveryTime ?? tracking?.delivery?.etaMinutes ?? '--'} min</strong>.
              </div>
            </div>
          </Panel>
        </section>

        <section className="grid gap-6 lg:grid-cols-2">
          <Panel title="Entregador" eyebrow="Despacho real">
            <div className="space-y-3 text-sm text-slate-700">
              <div className="rounded-[1.25rem] border border-slate-200 bg-slate-50 p-4">
                <p className="text-base font-black text-slate-950">{tracking?.driver?.name ?? 'Buscando entregador'}</p>
                <p className="mt-1">{tracking?.driver?.vehicleModel ?? 'Veiculo pendente'} • {tracking?.driver?.vehiclePlate ?? 'Placa pendente'}</p>
                <p className="mt-1">Avaliacao {tracking?.driver?.rating ?? '--'}</p>
              </div>
              <div className="rounded-[1.25rem] border border-slate-200 bg-white p-4">
                O cliente so acompanha o rastreio ligado ao proprio pedido, sem acesso a dados de outras lojas, corridas ou contas.
              </div>
            </div>
          </Panel>

          <Panel title="Atualizacao da operacao" eyebrow="Tempo real">
            <div className="space-y-3 text-sm text-slate-700">
              <div className="rounded-[1.25rem] border border-slate-200 bg-slate-50 p-4">WebSocket ligado para `driver.location.updated`, `eta.updated`, `route.updated`, `order.picked_up` e `order.delivered`.</div>
              <div className="rounded-[1.25rem] border border-slate-200 bg-slate-50 p-4">A loja acompanha a coleta, o cliente acompanha a entrega e o admin acompanha a cidade inteira no mapa ao vivo.</div>
              <div className="rounded-[1.25rem] border border-slate-200 bg-slate-50 p-4">
                {loading ? 'Sincronizando rastreio...' : 'Rastreio sincronizado com o backend real.'}
              </div>
            </div>
          </Panel>
        </section>
      </div>
    </main>
  );
}
