<script setup lang="ts">
import { onMounted, ref, watch, nextTick, onUnmounted, shallowRef, markRaw, defineAsyncComponent } from "vue";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import { useRouteStore } from "@/stores/route";
import { useMapStore } from "@/stores/map";
import { useCouponStore } from "@/stores/coupon";
import { useAuthStore } from "@/stores/auth";
import { useGoogleMaps } from "@/composables/useGoogleMaps";
import { analyticsService } from "@/services/analyticsService";
import { getImageUrl } from "@/utils/imageUrl";

import { useDirectionsRoute } from "@/composables/useDirectionsRoute";
import { useParadaCercana } from "@/composables/useParadaCercana";
import { useETA } from "@/composables/useETA";
import { useFlujoPrincipal } from "@/composables/useFlujoPrincipal";
import { useMapState } from "@/composables/useMapState";

// Optimized Components (Extracted)
import SearchOverlay from "@/components/map/SearchOverlay.vue";
import PromoCarousel from "@/components/map/PromoCarousel.vue";
import ArrivalBanner from "@/components/map/ArrivalBanner.vue";

const ETACard = defineAsyncComponent(() => import("@/components/ETACard.vue"));
import type { BusStop } from '@/types'

const router = useRouter();
const { t } = useI18n();

const routeStore = useRouteStore();
const mapStore = useMapStore();
const couponStore = useCouponStore();
const authStore = useAuthStore();

const { map, isLoaded, error: mapsError, initMap, addHtmlMarker, setCenter, setZoom, addMarker } = useGoogleMaps();
const { estasCargando: estasCargandoRuta, errorRuta } = useDirectionsRoute();
const { encontrarParadaCercana, paradaCercana, distanciaMetros, duracionCaminata } = useParadaCercana();
const { calcularETA, busesActivos, cargando: etaCargando } = useETA();

const { procesarSeleccionDeRuta } = useFlujoPrincipal();
const { limpiarMapa: limpiarTodoCentralizado } = useMapState();

const showETACard = ref(false);

// PERFORMANCE FIX: Use shallowRef for heavy object arrays and Map objects
const promoMarkers = shallowRef<any[]>([]);
const userMarker = shallowRef<any>(null);
const isUpdatingMarkers = ref(false);
const unitMarkers = shallowRef<Map<string, any>>(new Map());
const unitFetchInterval = ref<any>(null);
const userCoords = ref<{ lat: number; lng: number } | null>(null);
const showUberSearch = ref(false);
const showPromos = ref(false);
const isBannerClosing = ref(false);
const showPromoModal = ref(false);
const selectedPromo = ref<any>(null);
const currentCarouselIndex = ref(0);
const carouselTimer = ref<any>(null);

// Search optimization: Simple debounce implementation
// Helper functions

// performSearch removed

function openUberSearch() {
  showPromos.value = false;
  showUberSearch.value = true;
}

function closeUberSearch() {
  showUberSearch.value = false;
}

function animateAndReload() {
  isBannerClosing.value = true;
  setTimeout(() => {
    routeStore.clearSelection();
    isBannerClosing.value = false;
    router.replace({ query: {} });
  }, 450);
}

function handlePromoClick(promo: any) {
  selectedPromo.value = promo;
  showPromoModal.value = true;
}

function closePromoModal() {
  showPromoModal.value = false;
  selectedPromo.value = null;
}

// Map initialization & Lifecycle
onMounted(async () => {
  analyticsService.logEvent({ event_name: 'screen_view', properties: { screen_name: 'Map' } })
  
  await Promise.all([
    routeStore.loadRoutes(),
    couponStore.loadCoupons({ active_only: true })
  ]);

  const queryRouteId = router.currentRoute.value.query.routeId as string;
  if (queryRouteId && queryRouteId !== routeStore.selectedRouteId) {
    const foundRoute = routeStore.allRoutes.find(r => r.id === queryRouteId);
    if (foundRoute) {
      await routeStore.selectRoute(foundRoute.id, foundRoute.name);
    }
  }

  if (isLoaded.value) {
    await initializeMap();
  } else {
    const unwatch = watch(isLoaded, async (loaded) => {
      if (loaded) {
        await initializeMap();
        unwatch();
      }
    });
  }

  unitFetchInterval.value = setInterval(updateActiveUnits, 15000);
  updateActiveUnits();
  startCarousel();
});

onUnmounted(() => {
  if (unitFetchInterval.value) clearInterval(unitFetchInterval.value);
  if (carouselTimer.value) clearInterval(carouselTimer.value);
  clearMapMarkers();
  unitMarkers.value.forEach(m => m.setMap(null));
  unitMarkers.value.clear();
});

async function initializeMap() {
  await nextTick();
  await new Promise(resolve => setTimeout(resolve, 100));
  
  initMap("map", mapStore.center, mapStore.zoom);
  
  if (map.value) {
    // PERFORMANCE: Use passive listeners for native events if added (Google Maps doesn't expose this directly easily)
    map.value.addListener('click', () => {
      if (showETACard.value) showETACard.value = false;
    });
  }
  
  if (routeStore.selectedRouteId && routeStore.selectedRouteStops.length > 0 && routeStore.wasSelectedFromMap) {
    updateMapMarkers();
  } else {
    clearMapMarkers();
  }
  
  updatePromoMarkers();
  
  if (authStore.userProfile?.auto_location) {
    locateUser();
  }
  
  if (routeStore.selectedRouteId && routeStore.wasSelectedFromMap) {
    highlightOptimalStopForRoute();
  }
}

// MARKER RECYCLING & REACTIVITY OPTIMIZATION
function clearMapMarkers() {
  limpiarTodoCentralizado()
  if (userCoords.value) {
     reDrawUserMarker();
  }
}

function reDrawUserMarker() {
    if (!userCoords.value || !map.value) return;
    if (userMarker.value && typeof userMarker.value.setMap === 'function') {
        userMarker.value.setMap(null);
    }
    
    userMarker.value = markRaw(addHtmlMarker(
        { lat: userCoords.value.lat, lng: userCoords.value.lng },
        sonarHtml,
        { x: -30, y: -30 }
    )!);
}

async function updateMapMarkers(skipZoom = false) {
  if (!isLoaded.value || !map.value || isUpdatingMarkers.value) return;

  isUpdatingMarkers.value = true;
  const currentRequestRouteId = routeStore.selectedRouteId;
  const stops = [...routeStore.selectedRouteStops];
  
  try {
    if (!currentRequestRouteId || stops.length === 0) {
      clearMapMarkers();
      return;
    }
    
    const selectedRouteObj = routeStore.allRoutes.find(r => r.id === currentRequestRouteId) || { id: currentRequestRouteId, short_name: currentRequestRouteId };
    await procesarSeleccionDeRuta(selectedRouteObj, stops as BusStop[], map.value, skipZoom);
    reDrawUserMarker();
    
    if (routeStore.selectedRouteId !== currentRequestRouteId) return;

    if (routeStore.wasSelectedFromMap && !skipZoom) {
        await highlightOptimalStopForRoute();
    }
  } finally {
    isUpdatingMarkers.value = false;
  }
}

async function updatePromoMarkers() {
  if (!isLoaded.value) return;

  promoMarkers.value.forEach(m => m.setMap(null));
  const newMarkers: any[] = [];

  const promosWithCoords = couponStore.coupons.filter(c => 
    c.is_active && c.business && c.business.latitude && c.business.longitude
  );

  promosWithCoords.forEach(promo => {
    const marker = addMarker(
      { lat: promo.business!.latitude!, lng: promo.business!.longitude! },
      {
        title: promo.title,
        icon: {
          path: "M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.65-.5-.65C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z",
          fillColor: '#FF4081',
          fillOpacity: 1,
          strokeColor: '#FFFFFF',
          strokeWeight: 2,
          anchor: new google.maps.Point(12, 12),
          scale: 2
        }
      }
    );
    if (marker) {
      const rawMarker = markRaw(marker);
      rawMarker.addListener('click', () => handlePromoClick(promo));
      newMarkers.push(rawMarker);
    }
  });
  promoMarkers.value = newMarkers;
}

// Carousel logic
function startCarousel() {
  if (carouselTimer.value) clearInterval(carouselTimer.value);
  carouselTimer.value = setInterval(() => {
    if (couponStore.coupons.length > 0) {
      currentCarouselIndex.value = (currentCarouselIndex.value + 1) % couponStore.coupons.length;
    }
  }, 5000);
}

function stopCarousel() {
  if (carouselTimer.value) clearInterval(carouselTimer.value);
}

function selectRouteAndClose(route: any) {
  if (routeStore.selectedRouteId === route.id) {
    showUberSearch.value = false;
    highlightOptimalStopForRoute();
    return;
  }
  showUberSearch.value = false;
  routeStore.wasSelectedFromMap = true;
  routeStore.selectRoute(route.id, route.name);
}

async function updateActiveUnits() {
  if (!isLoaded.value) return;
  if (routeStore.selectedRouteId && paradaCercana.value) {
    await calcularETA(routeStore.selectedRouteId, paradaCercana.value as BusStop);
  }
}

function locateUser(): Promise<void> {
  return new Promise((resolve) => {
    if (!navigator.geolocation) { return resolve(); }
    navigator.geolocation.getCurrentPosition(
      (position) => {
        const { latitude, longitude } = position.coords;
        userCoords.value = { lat: latitude, lng: longitude };
        setCenter(latitude, longitude);
        setZoom(16);
        reDrawUserMarker();
        resolve();
      },
      () => {
        if (authStore.userProfile?.auto_location) {
           authStore.updateProfile({ auto_location: false });
        }
        resolve();
      },
      { enableHighAccuracy: true, timeout: 8000, maximumAge: 30000 }
    );
  });
}

async function highlightOptimalStopForRoute() {
  if (!userCoords.value) { await locateUser(); }
  else { reDrawUserMarker(); }

  if (!userCoords.value || routeStore.selectedRouteStops.length === 0) return;
  
  try {
    await encontrarParadaCercana(userCoords.value, routeStore.selectedRouteStops as BusStop[], map.value || undefined);
  } catch (e) {
    console.error('Error calculating optimal stop:', e);
  }
}

const sonarHtml = `
  <div style="position: relative; width: 60px; height: 60px; display: flex; align-items: center; justify-content: center;">
    <div style="position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: rgba(0, 212, 255, 0.5); animation: sonar-pulse 2.5s infinite ease-out;"></div>
    <div style="position: absolute; width: 100%; height: 100%; border-radius: 50%; background-color: rgba(0, 212, 255, 0.3); animation: sonar-pulse 2.5s infinite ease-out; animation-delay: 1.25s;"></div>
    <div style="width: 16px; height: 16px; background-color: #00d4ff; border-radius: 50%; box-shadow: 0 0 20px #00d4ff, 0 0 40px rgba(0, 212, 255, 0.6); border: 2px solid white; z-index: 2;"></div>
    <style> @keyframes sonar-pulse { 0% { transform: scale(0.1); opacity: 0.8; } 100% { transform: scale(4); opacity: 0; } } </style>
  </div>
`;

// Watch for route selection changes
watch(() => routeStore.selectedRouteId, (routeId) => {
  if (routeId) {
    if (routeStore.wasSelectedFromMap) {
      updateMapMarkers(false);
    } else {
      clearMapMarkers();
    }
  } else {
    clearMapMarkers();
  }
});

function handleImageError(event: Event) {
  (event.target as HTMLImageElement).src = getImageUrl(null, 'coupon');
}
</script>

<template>
  <div class="split-view">
    <div class="map-side">
      <div class="map-view">
        <div v-if="estasCargandoRuta || errorRuta" class="status-indicator">
          <div v-if="estasCargandoRuta" class="loading-pill">{{ t('map.calculatingRoute') }}</div>
          <div v-if="errorRuta" class="error-pill">{{ errorRuta }}</div>
        </div>

        <div class="map-container">
          <div v-if="mapsError" class="error">
            <div class="error-content">
              <h3>⚠️ {{ t('map.mapLoadingError') }}</h3>
              <div class="error-detail">{{ mapsError }}</div>
            </div>
          </div>
          <div v-else-if="!isLoaded" class="loading">
            <p>{{ t('map.loadingMap') }}</p>
          </div>
          <div id="map" class="map" :style="{ display: isLoaded ? 'block' : 'none' }"></div>
          
          <div class="map-floating-controls">
            <button v-if="isLoaded && !showPromos && couponStore.coupons.length > 0" class="offers-fab pulse" @click="showPromos = true">
              <span class="material-icons">local_offer</span>
              <span v-if="couponStore.coupons.length > 0" class="offers-badge">{{ couponStore.coupons.length }}</span>
            </button>

            <button v-if="isLoaded && !authStore.userProfile?.auto_location" class="location-loader-btn" @click="locateUser">
              <span class="material-icons">my_location</span>
            </button>
          </div>
        </div>

        <!-- COMPONENTIZED SEARCH & BANNER -->
        <SearchOverlay 
          :show-panel="showUberSearch"
          :is-compact="!!(routeStore.selectedRouteId && routeStore.wasSelectedFromMap)"
          :is-route-active="!!routeStore.selectedRouteId"
          :all-routes="routeStore.allRoutes"
          :selected-route-id="routeStore.selectedRouteId"
          :was-selected-from-map="routeStore.wasSelectedFromMap"
          @open="openUberSearch"
          @close="closeUberSearch"
          @select-route="selectRouteAndClose"
        >
          <template #extra-triggers>
            <ArrivalBanner 
              :is-visible="!!(paradaCercana && routeStore.selectedRouteId && !isBannerClosing && routeStore.wasSelectedFromMap)"
              :stop-name="paradaCercana?.name || ''"
              :is-loading="etaCargando"
              :has-active-buses="busesActivos.length > 0"
              :eta-value="busesActivos[0]?.etaMinutos ?? 0"
              @close="animateAndReload"
              @click="showETACard = true"
            />
          </template>
        </SearchOverlay>
      </div>
    </div>

    <!-- COMPONENTIZED PROMOS -->
    <PromoCarousel 
      :is-open="showPromos"
      :coupons="couponStore.coupons"
      :current-index="currentCarouselIndex"
      @update:index="currentCarouselIndex = $event"
      @close="showPromos = false"
      @prev="currentCarouselIndex = (currentCarouselIndex - 1 + couponStore.coupons.length) % couponStore.coupons.length"
      @next="currentCarouselIndex = (currentCarouselIndex + 1) % couponStore.coupons.length"
      @pause="stopCarousel"
      @resume="startCarousel"
      @promo-click="handlePromoClick"
    />

    <!-- MODALS & CARDS -->
    <Transition name="modal-fade">
      <div v-if="showPromoModal && selectedPromo" class="promo-modal-overlay" @click="closePromoModal">
        <div class="promo-modal-content" @click.stop>
          <div class="promo-header-modal">
            <img :src="getImageUrl(selectedPromo.image_url, 'coupon')" class="promo-img-modal" @error="handleImageError" />
            <div class="promo-badge-modal">{{ t('map.promo') }}</div>
          </div>
          <div class="promo-body-modal">
            <h2 class="promo-title-modal">{{ selectedPromo.title }}</h2>
            <div class="promo-biz">{{ selectedPromo.business?.name }}</div>
            <p>{{ selectedPromo.description }}</p>
          </div>
          <div class="promo-actions-modal">
            <button class="business-detail-btn-modal" @click="router.push('/business/' + selectedPromo.business_id)">
              {{ t('business.viewBusiness') }}
            </button>
          </div>
        </div>
      </div>
    </Transition>
    
    <ETACard
      :is-open="showETACard"
      :stop-name="paradaCercana?.name || ''"
      :walk-distance="distanciaMetros"
      :walk-duration="duracionCaminata"
      :buses="busesActivos"
      :is-loading="etaCargando"
      @close="showETACard = false"
      @refresh="paradaCercana && routeStore.selectedRouteId ? calcularETA(routeStore.selectedRouteId, paradaCercana) : null"
    />
  </div>
</template>

<style scoped>
.split-view {
  display: flex;
  width: 100%;
  height: calc(100vh - 64px);
  overflow: hidden;
  position: relative;
}

.map-side, .map-view, .map-container, .map {
  width: 100%;
  height: 100%;
  position: relative;
}

.status-indicator {
  position: absolute;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.loading-pill {
  background: #1e40af;
  color: white;
  padding: 0.5rem 1rem;
  border-radius: 9999px;
  font-size: 0.875rem;
  animation: pulse 2s infinite;
}

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }

.error-content { text-align: center; padding: 20px; }
.error-detail { color: var(--text-primary); background: var(--bg-secondary); padding: 15px; border-radius: 8px; margin-top: 10px; }

.map-floating-controls {
  position: fixed;
  bottom: 85px; 
  right: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  z-index: 1001;
}

.offers-fab {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #fee715;
  color: #000;
  border: none;
  box-shadow: 0 4px 10px rgba(0,0,0,0.3);
  position: relative;
}

.offers-badge {
  position: absolute;
  top: -5px; right: -5px;
  background: #f44336;
  color: white;
  padding: 2px 6px;
  border-radius: 10px;
  border: 2px solid #fff;
}

.location-loader-btn {
  background: var(--header-bg);
  backdrop-filter: blur(20px);
  border: 1px solid var(--border-color);
  width: 50px;
  height: 50px;
  border-radius: 50%;
  color: var(--active-color);
  box-shadow: var(--shadow);
}

.promo-modal-overlay {
  position: fixed;
  top: 0; left: 0; width: 100%; height: 100%;
  background: rgba(0,0,0,0.8);
  z-index: 4000;
  display: flex; align-items: center; justify-content: center;
}

.promo-modal-content {
  background: var(--card-bg); width: 90%; max-width: 450px;
  border-radius: 24px; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

.promo-header-modal { position: relative; height: 200px; }
.promo-img-modal { width: 100%; height: 100%; object-fit: cover; }
.promo-badge-modal { position: absolute; bottom: 0; left: 0; background: #EAB308; color: #000; padding: 5px 15px; font-weight: 800; border-top-right-radius: 12px; }
.promo-body-modal { padding: 25px; }
.promo-title-modal { font-size: 1.5rem; font-weight: 800; margin-bottom: 10px; }
.promo-biz { color: var(--active-color); font-weight: 700; margin-bottom: 15px; }
.promo-actions-modal { padding: 0 25px 25px; }
.business-detail-btn-modal { width: 100%; background: var(--active-color); color: #000; border: none; padding: 15px; border-radius: 12px; font-weight: 800; cursor: pointer; }

.modal-fade-enter-active, .modal-fade-leave-active { transition: opacity 0.3s ease; }
.modal-fade-enter-from, .modal-fade-leave-to { opacity: 0; }

.pulse { animation: pulse-animation 2s infinite; }
@keyframes pulse-animation {
  0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(254, 231, 21, 0.7); }
  70% { transform: scale(1.1); box-shadow: 0 0 0 15px rgba(254, 231, 21, 0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(254, 231, 21, 0); }
}

@media (max-width: 600px) {
  .map-floating-controls { bottom: 100px; }
}
</style>
