'use client';

import axios from 'axios';
import { Panel, StatusBadge } from '@chego/ui';
import { io, type Socket } from 'socket.io-client';
import { useEffect, useRef, useState } from 'react';
import { fetchWithSession } from '../components/api-helpers';
import { readSession } from '../lib/auth-session';

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

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

type Session = { accessToken: string };
type OrderListItem = { id: string; status: string };

const API_URL = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:3001/api';
const WS_URL = process.env.NEXT_PUBLIC_WS_URL ?? 'http://localhost:3001';
const GOOGLE_MAPS_KEY = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY ?? '';

let mapsLoader: Promise<NonNullable<Window['google']>> | null = null;

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 script = document.createElement('script');
      script.src = `https://maps.googleapis.com/maps/api/js?key=${encodeURIComponent(apiKey)}`;
      script.async = true;
      script.defer = true;
      script.onload = () => window.google?.maps ? resolve(window.google) : 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 RestaurantDeliveryTrackingPage() {
  const mapRef = useRef<HTMLDivElement | null>(null);
  const [session, setSession] = useState<Session | null>(null);
  const [tracking, setTracking] = useState<TrackingPayload | null>(null);
  const [trackedOrderId, setTrackedOrderId] = useState('');
  const [error, setError] = useState('');
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;

    const bootstrap = async () => {
      try {
        const storedSession = readSession();
        if (!storedSession?.accessToken) {
          throw new Error('Sessao da loja ausente. Entre novamente para usar o tracking protegido.');
        }

        const orders = await fetchWithSession('/orders');
        if (cancelled) {
          return;
        }

        const activeOrder = (orders as OrderListItem[]).find((order) => !['DELIVERED', 'CANCELLED', 'REFUNDED'].includes(order.status)) ?? (orders as OrderListItem[])[0];

        setSession({ accessToken: storedSession.accessToken });
        setTrackedOrderId(activeOrder?.id ?? '');
        setError(activeOrder ? '' : 'Nenhum pedido desta loja esta disponivel para rastreamento agora.');
      } catch (loadError) {
        if (cancelled) {
          return;
        }
        setSession(null);
        setTrackedOrderId('');
        setError(loadError instanceof Error ? loadError.message : 'Falha ao carregar o tracking da loja.');
        setIsLoading(false);
      }
    };

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

  useEffect(() => {
    if (!session || !trackedOrderId) {
      setIsLoading(false);
      return;
    }

    let active = true;

    const fetchTracking = async () => {
      try {
        const response = await axios.get<TrackingPayload>(`${API_URL}/restaurant/orders/${trackedOrderId}/tracking`, {
          headers: { Authorization: `Bearer ${session.accessToken}` },
        });
        if (!active) {
          return;
        }
        setTracking(response.data);
        setError('');
      } catch (loadError) {
        if (active) {
          setError(loadError instanceof Error ? loadError.message : 'Falha ao carregar tracking do restaurante.');
        }
      } finally {
        if (active) {
          setIsLoading(false);
        }
      }
    };

    void fetchTracking();

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

    return () => {
      active = false;
      ['driver.location.updated', 'eta.updated', 'route.updated', 'order.picked_up', 'order.delivered'].forEach((eventName) => {
        socket.removeAllListeners(eventName);
      });
      socket.disconnect();
    };
  }, [session, trackedOrderId]);

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

    let cancelled = false;

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

        const restaurant = toCoordinate(tracking.restaurant.latitude, tracking.restaurant.longitude);
        const driver = toCoordinate(tracking.latestLocation?.latitude, tracking.latestLocation?.longitude);
        const map = new googleApi.maps.Map(mapRef.current, {
          center: driver ?? restaurant ?? { lat: -23.55052, lng: -46.633308 },
          zoom: driver && restaurant ? 13 : 11,
          mapTypeControl: false,
          streetViewControl: false,
          fullscreenControl: false,
        });

        const bounds = new googleApi.maps.LatLngBounds();
        if (restaurant) {
          bounds.extend(restaurant);
          new googleApi.maps.Marker({ map, position: restaurant, title: tracking.restaurant.name, icon: 'http://maps.google.com/mapfiles/ms/icons/orange-dot.png' });
        }
        if (driver) {
          bounds.extend(driver);
          new googleApi.maps.Marker({ map, position: driver, title: tracking.driver?.name ?? 'Entregador', icon: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png' });
        }
        if (driver && restaurant) {
          new googleApi.maps.Polyline({
            map,
            path: [driver, restaurant],
            strokeColor: '#C2410C',
            strokeOpacity: 0.9,
            strokeWeight: 4,
          });
        }
        if (!bounds.isEmpty()) {
          map.fitBounds(bounds, 56);
        }
      } catch (loadError) {
        if (!cancelled) {
          setError(loadError instanceof Error ? loadError.message : 'Falha ao renderizar o mapa da coleta.');
        }
      }
    };

    void renderMap();

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

  return (
    <div className="space-y-6">
      <section className="rounded-[2rem] border border-white/80 bg-[linear-gradient(135deg,#2b180f_0%,#6f3f1b_55%,#c77b2f_100%)] p-6 text-white shadow-[0_28px_80px_rgba(111,63,27,0.18)] lg:p-8">
        <div className="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
          <div>
            <p className="text-xs font-semibold uppercase tracking-[0.28em] text-orange-100">Pickup tracking</p>
            <h1 className="mt-3 text-4xl font-black tracking-tight">Acompanhar entregador a caminho da loja</h1>
            <p className="mt-3 max-w-3xl text-sm leading-7 text-orange-50/90">O rastreio agora usa a sessao autenticada da loja, respeita escopo por parceiro e acompanha apenas pedidos pertencentes a este restaurante.</p>
          </div>
          <div className="flex flex-wrap gap-3">
            <StatusBadge tone="emerald">{tracking?.trackingStatusLabel ?? 'Aguardando pedido'}</StatusBadge>
            <StatusBadge tone="amber">ETA coleta {tracking?.route?.estimatedPickupTime ?? '--'} min</StatusBadge>
          </div>
        </div>
      </section>

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

      <section className="grid gap-6 xl:grid-cols-[1.2fr_0.8fr]">
        <div className="rounded-[2rem] border border-slate-200 bg-white p-5 shadow-[0_20px_60px_rgba(15,23,42,0.06)]">
          {GOOGLE_MAPS_KEY ? (
            <div ref={mapRef} className="h-[460px] rounded-[1.5rem] border border-slate-200 bg-slate-100" />
          ) : (
            <div className="flex h-[460px] items-center justify-center rounded-[1.5rem] border border-dashed border-orange-200 bg-[linear-gradient(180deg,#fff7ed_0%,#ffffff_100%)] text-center">
              <div className="max-w-lg px-8">
                <p className="text-xs font-bold uppercase tracking-[0.28em] text-orange-700">Mapa simples</p>
                <h2 className="mt-3 text-3xl font-black text-slate-950">Defina a chave do Google Maps</h2>
                <p className="mt-3 text-sm leading-7 text-slate-600">O tracking do pedido ja esta real. Falta apenas `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY` para desenhar o canvas no web-restaurant.</p>
              </div>
            </div>
          )}
        </div>

        <div className="space-y-6">
          <Panel title="Entrega designada" eyebrow="Motorista ativo" action={<StatusBadge tone="sky">{tracking?.route?.estimatedPickupTime ?? '--'} min</StatusBadge>}>
            <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 ?? 'Sem entregador definido'}</p>
                <p className="mt-1">{tracking?.driver?.vehicleModel ?? 'Veiculo pendente'} • {tracking?.driver?.vehiclePlate ?? 'Placa pendente'}</p>
                <p className="mt-1">Avaliacao {tracking?.driver?.rating ?? '--'} • Pedido {tracking?.orderId?.slice(0, 8) ?? '--'}</p>
              </div>
              <div className="rounded-[1.25rem] border border-emerald-200 bg-emerald-50 p-4">Status operacional: <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>
          </Panel>
        </div>
      </section>

      {isLoading ? <p className="text-sm text-slate-500">Carregando rastreamento...</p> : null}
    </div>
  );
}
