/**
 * @ai-summary Desktop stations page with map and list layout
 */

import React, { useState, useMemo, useCallback, useEffect } from 'react';
import {
  Grid,
  Paper,
  Tabs,
  Tab,
  Box,
  Alert,
  useMediaQuery,
  useTheme,
  CircularProgress,
  Typography
} from '@mui/material';
import LocalGasStationIcon from '@mui/icons-material/LocalGasStation';
import { SavedStation, Station, StationSearchRequest } from '../types/stations.types';
import { CommunityStation, StationBounds } from '../types/community-stations.types';
import {
  useStationsSearch,
  useSavedStations,
  useSaveStation,
  useDeleteStation,
  useGeolocation
} from '../hooks';
import {
  StationMap,
  StationsList,
  SavedStationsList,
  StationsSearchForm,
  GoogleMapsErrorBoundary,
  SubmitFor93Dialog,
  Premium93TabContent
} from '../components';
import { resolveSavedStationPlaceId } from '../utils/savedStations';
import { useEnrichedStations } from '../hooks/useEnrichedStations';

interface TabPanelProps {
  children?: React.ReactNode;
  index: number;
  value: number;
}

const TabPanel: React.FC<TabPanelProps> = ({ children, value, index }) => {
  // Only render content when tab is active to prevent IntersectionObserver errors
  // on hidden MUI components
  if (value !== index) {
    return null;
  }

  return (
    <div
      role="tabpanel"
      id={`stations-tabpanel-${index}`}
      aria-labelledby={`stations-tab-${index}`}
    >
      <Box sx={{ padding: 2 }}>{children}</Box>
    </div>
  );
};

/**
 * Desktop stations page layout
 * Left: Map (60%), Right: Search form + Tabs (40%)
 * Mobile: Stacks vertically
 */
export const StationsPage: React.FC = () => {
  console.log('[DEBUG StationsPage] Rendering');

  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));

  const [tabValue, setTabValue] = useState(0);
  const [searchResults, setSearchResults] = useState<Station[]>([]);
  const [mapCenter, setMapCenter] = useState<{ lat: number; lng: number } | null>(null);
  const [currentLocation, setCurrentLocation] = useState<
    { latitude: number; longitude: number } | undefined
  >();
  const [isPageReady, setIsPageReady] = useState(false);
  const [isMapReady, setIsMapReady] = useState(false);
  const [submitFor93Station, setSubmitFor93Station] = useState<Station | null>(null);
  const [searchBounds, setSearchBounds] = useState<StationBounds | null>(null);

  // Queries and mutations
  const { mutate: search, isPending: isSearching, error: searchError } = useStationsSearch();
  const { data: savedStations = [], isLoading: isSavedLoading, error: savedError, isFetching, isSuccess } = useSavedStations();
  console.log('[DEBUG StationsPage] useSavedStations result:', {
    data: savedStations,
    isLoading: isSavedLoading,
    isFetching,
    isSuccess,
    error: savedError
  });

  // Get user's geolocation for community station lookups (fallback when no search performed)
  const { coordinates: geoCoordinates } = useGeolocation();

  // Effective coordinates: use search location if available, otherwise use geolocation
  const effectiveLatitude = currentLocation?.latitude ?? geoCoordinates?.latitude ?? null;
  const effectiveLongitude = currentLocation?.longitude ?? geoCoordinates?.longitude ?? null;

  // Enrich search results with community station data
  const { enrichedStations, communityStationsMap } = useEnrichedStations(
    searchResults,
    currentLocation?.latitude ?? null,
    currentLocation?.longitude ?? null
  );

  // Multi-stage initialization: Wait for auth, data, and DOM
  useEffect(() => {
    // Stage 1: Wait for saved stations query to settle (loading complete or error)
    const isDataReady = !isSavedLoading && !isFetching;

    if (isDataReady && !isPageReady) {
      console.log('[DEBUG StationsPage] Data ready, waiting for DOM...');
      // Stage 2: Wait for DOM to be ready
      const timer = setTimeout(() => {
        setIsPageReady(true);
        console.log('[DEBUG StationsPage] Page ready');
      }, 150);
      return () => clearTimeout(timer);
    }

    return undefined;
  }, [isSavedLoading, isFetching, isPageReady]);

  // Stage 3: Wait for page render to complete before allowing map initialization
  useEffect(() => {
    if (isPageReady && !isMapReady) {
      console.log('[DEBUG StationsPage] Page rendered, enabling map...');
      const timer = setTimeout(() => {
        setIsMapReady(true);
        console.log('[DEBUG StationsPage] Map ready');
      }, 100);
      return () => clearTimeout(timer);
    }

    return undefined;
  }, [isPageReady, isMapReady]);

  const { mutate: saveStation } = useSaveStation();
  const { mutate: deleteStation } = useDeleteStation();

  // Create set of saved place IDs and addresses for quick lookup
  const { savedStationsMap, savedPlaceIds, savedAddresses } = useMemo(() => {
    const map = new Map<string, SavedStation>();
    const addresses = new Set<string>();

    savedStations.forEach((station) => {
      const placeId = resolveSavedStationPlaceId(station);
      if (!placeId) {
        return;
      }

      const normalizedStation =
        station.placeId === placeId ? station : { ...station, placeId };

      map.set(placeId, normalizedStation);

      // Also track addresses for community station matching
      if (station.address) {
        addresses.add(station.address.toLowerCase().trim());
      }
    });

    return {
      savedStationsMap: map,
      savedPlaceIds: new Set(map.keys()),
      savedAddresses: addresses
    };
  }, [savedStations]);

  // Compute which stations to display on map based on active tab
  const mapStations = useMemo(() => {
    if (tabValue === 1) {
      // Saved tab: show saved stations with valid coordinates
      return savedStations.filter(
        (station) =>
          station.latitude !== undefined &&
          station.longitude !== undefined
      ) as Station[];
    }
    if (tabValue === 2) {
      // Premium 93 tab: show saved stations with 93 octane
      return savedStations.filter(
        (station) =>
          station.has93Octane &&
          station.latitude !== undefined &&
          station.longitude !== undefined
      ) as Station[];
    }
    // Results tab: show search results
    return searchResults;
  }, [tabValue, savedStations, searchResults]);

  // Handle search
  const handleSearch = (request: StationSearchRequest) => {
    setCurrentLocation({ latitude: request.latitude, longitude: request.longitude });
    setMapCenter({ lat: request.latitude, lng: request.longitude });

    // Calculate approximate bounds from search location and radius
    const radiusKm = (request.radius || 5000) / 1000;
    const latDelta = radiusKm / 111; // ~111km per degree latitude
    const lngDelta = radiusKm / (111 * Math.cos(request.latitude * Math.PI / 180));

    setSearchBounds({
      north: request.latitude + latDelta,
      south: request.latitude - latDelta,
      east: request.longitude + lngDelta,
      west: request.longitude - lngDelta
    });

    search(request, {
      onSuccess: (stations) => {
        setSearchResults(stations);
        setTabValue(0); // Switch to results tab
      }
    });
  };

  // Handle save station - auto-copies 93 octane data from community verification
  const handleSave = (station: Station) => {
    // Get community data for this station if available
    const normalizedAddress = station.address
      ?.toLowerCase()
      .trim()
      .replace(/\s+/g, ' ')
      .replace(/[,]/g, '') || '';
    const communityData = communityStationsMap.get(normalizedAddress);

    saveStation(
      {
        placeId: station.placeId,
        data: {
          isFavorite: true,
          has93Octane: communityData?.has93Octane,
          has93OctaneEthanolFree: communityData?.has93OctaneEthanolFree
        }
      },
      {
        onSuccess: () => {
          setSearchResults((prev) =>
            prev.map((s) =>
              s.placeId === station.placeId ? { ...s } : s
            )
          );
        }
      }
    );
  };

  // Handle save community station (auto-sets has93Octane flag)
  const handleSaveCommunityStation = useCallback((station: CommunityStation) => {
    saveStation({
      placeId: station.id, // Use community station ID as placeId
      data: {
        isFavorite: true,
        has93Octane: station.has93Octane,
        has93OctaneEthanolFree: station.has93OctaneEthanolFree
      }
    });
  }, [saveStation]);

  // Handle unsave community station
  const handleUnsaveCommunityStation = useCallback((stationId: string) => {
    deleteStation(stationId);
  }, [deleteStation]);

  // Handle delete station
  const handleDelete = (placeId: string) => {
    deleteStation(placeId);
  };

  // Handle station selection - wrapped in useCallback to prevent infinite renders
  const handleSelectStation = useCallback((station: Station | CommunityStation) => {
    setMapCenter({
      lat: station.latitude,
      lng: station.longitude
    });
  }, []);

  // Show comprehensive loading state until everything is ready
  if (!isPageReady || !isMapReady) {
    return (
      <Box
        sx={{
          padding: 4,
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'center',
          alignItems: 'center',
          minHeight: '400px',
          gap: 2
        }}
      >
        <CircularProgress size={48} />
        <Typography variant="body1" color="textSecondary">
          Loading stations...
        </Typography>
      </Box>
    );
  }

  // If mobile, stack components vertically
  if (isMobile) {
    return (
      <Box sx={{ padding: 2, display: 'flex', flexDirection: 'column', gap: 2 }}>
        <Paper>
          <StationsSearchForm onSearch={handleSearch} isSearching={isSearching} />
        </Paper>

        {searchError && (
          <Alert severity="error">{(searchError as any).message || 'Search failed'}</Alert>
        )}

        {isMapReady ? (
          <GoogleMapsErrorBoundary>
            <StationMap
              key="mobile-station-map"
              stations={mapStations}
              savedPlaceIds={savedPlaceIds}
              currentLocation={currentLocation}
              center={mapCenter || undefined}
              height="300px"
              readyToRender={true}
            />
          </GoogleMapsErrorBoundary>
        ) : (
          <Box sx={{ height: '300px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <CircularProgress />
          </Box>
        )}

        <Tabs
          value={tabValue}
          onChange={(_, newValue) => setTabValue(newValue)}
          indicatorColor="primary"
          textColor="primary"
          aria-label="stations tabs"
        >
          <Tab label={`Results (${searchResults.length})`} id="stations-tab-0" />
          <Tab label={`Saved (${savedStations.length})`} id="stations-tab-1" />
          <Tab
            label="Premium 93"
            icon={<LocalGasStationIcon />}
            iconPosition="start"
            id="stations-tab-2"
          />
        </Tabs>

        <TabPanel value={tabValue} index={0}>
          <StationsList
            stations={enrichedStations}
            savedPlaceIds={savedPlaceIds}
            savedStationsMap={savedStationsMap}
            loading={isSearching}
            error={searchError ? (searchError as any).message : null}
            onSaveStation={handleSave}
            onDeleteStation={handleDelete}
            communityStationsMap={communityStationsMap}
            onSubmitFor93={(station) => setSubmitFor93Station(station)}
          />
        </TabPanel>

        <TabPanel value={tabValue} index={1}>
          <SavedStationsList
            stations={savedStations}
            loading={isSavedLoading}
            error={savedError ? (savedError as any).message : null}
            onSelectStation={handleSelectStation}
            onDeleteStation={handleDelete}
            onSubmitFor93={(station) => setSubmitFor93Station(station as unknown as Station)}
            communityStationsMap={communityStationsMap}
            latitude={effectiveLatitude}
            longitude={effectiveLongitude}
          />
        </TabPanel>

        <TabPanel value={tabValue} index={2}>
          <Premium93TabContent
            latitude={effectiveLatitude}
            longitude={effectiveLongitude}
            savedStations={savedStations}
            communityStationsMap={communityStationsMap}
            onStationSelect={handleSelectStation}
            searchBounds={searchBounds}
            onSaveCommunityStation={handleSaveCommunityStation}
            onUnsaveCommunityStation={handleUnsaveCommunityStation}
            onSubmitFor93={(station) => setSubmitFor93Station(station as unknown as Station)}
            savedAddresses={savedAddresses}
          />
        </TabPanel>
      </Box>
    );
  }

  // Desktop layout: top-row map + search, full-width results
  return (
    <Box sx={{ padding: 2 }}>
      <Grid container spacing={2}>
        {/* Map */}
        <Grid item xs={12} md={6}>
          <Paper
            sx={{
              height: { xs: 300, md: 520 },
              display: 'flex',
              overflow: 'hidden'
            }}
          >
            {isMapReady ? (
              <GoogleMapsErrorBoundary>
                <StationMap
                  key="desktop-station-map"
                  stations={mapStations}
                  savedPlaceIds={savedPlaceIds}
                  currentLocation={currentLocation}
                  center={mapCenter || undefined}
                  height="100%"
                  readyToRender={true}
                />
              </GoogleMapsErrorBoundary>
            ) : (
              <Box sx={{ width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <CircularProgress />
              </Box>
            )}
          </Paper>
        </Grid>

        {/* Search form */}
        <Grid item xs={12} md={6}>
          <Paper
            sx={{
              height: { xs: 'auto', md: 520 },
              display: 'flex',
              flexDirection: 'column',
              overflow: 'hidden'
            }}
          >
            <Box sx={{ padding: 2, flex: 1 }}>
              <StationsSearchForm onSearch={handleSearch} isSearching={isSearching} />
            </Box>
          </Paper>
        </Grid>
      </Grid>

      {/* Error Alert */}
      {searchError && (
        <Box sx={{ mt: 2 }}>
          <Alert severity="error">{(searchError as any).message || 'Search failed'}</Alert>
        </Box>
      )}

      {/* Full-width Results */}
      <Paper
        sx={{
          mt: 2,
          display: 'flex',
          flexDirection: 'column'
        }}
      >
        <Tabs
          value={tabValue}
          onChange={(_, newValue) => setTabValue(newValue)}
          indicatorColor="primary"
          textColor="primary"
          aria-label="stations tabs"
        >
          <Tab label={`Results (${searchResults.length})`} id="stations-tab-0" />
          <Tab label={`Saved (${savedStations.length})`} id="stations-tab-1" />
          <Tab
            label="Premium 93"
            icon={<LocalGasStationIcon />}
            iconPosition="start"
            id="stations-tab-2"
          />
        </Tabs>

        <Box sx={{ flex: 1, overflow: 'auto', padding: 2 }}>
          <TabPanel value={tabValue} index={0}>
            <StationsList
              stations={enrichedStations}
              savedPlaceIds={savedPlaceIds}
              savedStationsMap={savedStationsMap}
              loading={isSearching}
              error={searchError ? (searchError as any).message : null}
              onSaveStation={handleSave}
              onDeleteStation={handleDelete}
              onSelectStation={handleSelectStation}
              communityStationsMap={communityStationsMap}
              onSubmitFor93={(station) => setSubmitFor93Station(station)}
            />
          </TabPanel>

          <TabPanel value={tabValue} index={1}>
            <SavedStationsList
              stations={savedStations}
              loading={isSavedLoading}
              error={savedError ? (savedError as any).message : null}
              onSelectStation={handleSelectStation}
              onDeleteStation={handleDelete}
              onSubmitFor93={(station) => setSubmitFor93Station(station as unknown as Station)}
              communityStationsMap={communityStationsMap}
              latitude={effectiveLatitude}
              longitude={effectiveLongitude}
            />
          </TabPanel>

          <TabPanel value={tabValue} index={2}>
            <Premium93TabContent
              latitude={effectiveLatitude}
              longitude={effectiveLongitude}
              savedStations={savedStations}
              communityStationsMap={communityStationsMap}
              onStationSelect={handleSelectStation}
              searchBounds={searchBounds}
              onSaveCommunityStation={handleSaveCommunityStation}
              onUnsaveCommunityStation={handleUnsaveCommunityStation}
              onSubmitFor93={(station) => setSubmitFor93Station(station as unknown as Station)}
              savedAddresses={savedAddresses}
            />
          </TabPanel>
        </Box>
      </Paper>

      <SubmitFor93Dialog
        open={!!submitFor93Station}
        onClose={() => setSubmitFor93Station(null)}
        station={submitFor93Station}
        communityStationId={
          submitFor93Station
            ? // If it's a CommunityStation from Premium 93 tab, use its id directly
              ('status' in submitFor93Station && submitFor93Station.status === 'approved')
              ? (submitFor93Station as unknown as CommunityStation).id
              // Otherwise look up in map (for search results)
              : communityStationsMap.get(submitFor93Station.address?.toLowerCase().trim() || '')?.communityStationId
            : undefined
        }
      />
    </Box>
  );
};

export default StationsPage;
