/**
 * @ai-summary Mobile-optimized gas stations screen with bottom tab navigation
 * @ai-context Four tabs: Search, Saved, Premium 93, Map with responsive mobile-first design
 */

import React, { useState, useCallback, useMemo } from 'react';
import {
  Box,
  Tabs,
  Tab,
  SwipeableDrawer,
  Fab,
  IconButton,
  Typography,
  Divider,
  useTheme,
  Button
} from '@mui/material';
import SearchIcon from '@mui/icons-material/Search';
import BookmarkIcon from '@mui/icons-material/Bookmark';
import MapIcon from '@mui/icons-material/Map';
import LocalGasStationIcon from '@mui/icons-material/LocalGasStation';
import CloseIcon from '@mui/icons-material/Close';

import { StationsSearchForm } from '../components/StationsSearchForm';
import { StationsList } from '../components/StationsList';
import { SavedStationsList } from '../components/SavedStationsList';
import { StationMap } from '../components/StationMap';
import { Premium93TabContent } from '../components/Premium93TabContent';
import { SubmitFor93Dialog } from '../components/SubmitFor93Dialog';

import {
  useStationsSearch,
  useSavedStations,
  useSaveStation,
  useDeleteStation,
  useGeolocation,
  useEnrichedStations
} from '../hooks';

import {
  Station,
  SavedStation,
  StationSearchRequest
} from '../types/stations.types';
import { CommunityStation, StationBounds } from '../types/community-stations.types';
import { resolveSavedStationPlaceId } from '../utils/savedStations';
import { buildNavigationLinks } from '../utils/navigation-links';

// Tab indices
const TAB_SEARCH = 0;
const TAB_SAVED = 1;
const TAB_PREMIUM_93 = 2;
const TAB_MAP = 3;

// iOS swipeable drawer configuration
const iOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);

export const StationsMobileScreen: React.FC = () => {
  const theme = useTheme();

  // Tab state
  const [activeTab, setActiveTab] = useState(TAB_SEARCH);

  // Bottom sheet state
  const [selectedStation, setSelectedStation] = useState<Station | SavedStation | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [submitFor93Station, setSubmitFor93Station] = useState<Station | null>(null);
  const [searchBounds, setSearchBounds] = useState<StationBounds | null>(null);

  // Hooks
  const { coordinates } = useGeolocation();
  const {
    mutate: performSearch,
    data: searchResults,
    isPending: isSearching,
    error: searchError
  } = useStationsSearch();

  const {
    data: savedStations,
    isLoading: isLoadingSaved,
    error: savedError
  } = useSavedStations();

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

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

  // Compute 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]);

  // Handle search submission
  const handleSearch = useCallback((request: StationSearchRequest) => {
    // 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
    });

    performSearch(request);
  }, [performSearch]);

  // Handle station selection (opens bottom sheet)
  const handleSelectStation = useCallback((station: Station | SavedStation) => {
    setSelectedStation(station);
    setDrawerOpen(true);
  }, []);

  // Handle station selection from Premium 93 tab (supports CommunityStation)
  const handleSelectPremium93Station = useCallback((station: Station | CommunityStation) => {
    // CommunityStation doesn't have the same fields as Station/SavedStation
    // For now, only handle actual Station types
    if ('placeId' in station || 'isFavorite' in station) {
      setSelectedStation(station as Station | SavedStation);
      setDrawerOpen(true);
    }
  }, []);

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

      await saveStation({
        placeId: station.placeId,
        data: {
          nickname: station.name,
          isFavorite: false,
          has93Octane: communityData?.has93Octane,
          has93OctaneEthanolFree: communityData?.has93OctaneEthanolFree
        }
      });
    } catch (error) {
      console.error('Failed to save station:', error);
    }
  }, [saveStation, communityStationsMap]);

  // Handle delete station
  const handleDeleteStation = useCallback(async (placeId: string) => {
    try {
      await deleteStation(placeId);

      // Close drawer if currently viewing deleted station
      if (selectedStation?.placeId === placeId) {
        setDrawerOpen(false);
        setSelectedStation(null);
      }
    } catch (error) {
      console.error('Failed to delete station:', error);
    }
  }, [deleteStation, selectedStation]);

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

  // Handle unsave community station
  const handleUnsaveCommunityStation = useCallback(async (stationId: string) => {
    try {
      await deleteStation(stationId);
    } catch (error) {
      console.error('Failed to unsave community station:', error);
    }
  }, [deleteStation]);

  // Close bottom sheet
  const handleCloseDrawer = useCallback(() => {
    setDrawerOpen(false);
  }, []);

  // Navigate to search tab (from Map FAB)
  const handleBackToSearch = useCallback(() => {
    setActiveTab(TAB_SEARCH);
  }, []);

  // Tab change handler
  const handleTabChange = useCallback((_event: React.SyntheticEvent, newValue: number) => {
    setActiveTab(newValue);
  }, []);

  // Pull-to-refresh handler (Search tab) - not implemented yet
  const handleRefresh = useCallback(() => {
    // TODO: Implement pull-to-refresh
  }, []);

  const navigationLinks = useMemo(
    () => (selectedStation ? buildNavigationLinks(selectedStation) : null),
    [selectedStation]
  );

  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        height: '100vh',
        pb: 0,
        overflow: 'hidden'
      }}
    >
      {/* Tab controls */}
      <Box
        sx={{
          position: 'sticky',
          top: 0,
          zIndex: theme.zIndex.appBar,
          backgroundColor: theme.palette.background.paper,
          borderBottom: `1px solid ${theme.palette.divider}`
        }}
      >
        <Tabs
          value={activeTab}
          onChange={handleTabChange}
          variant="fullWidth"
          textColor="primary"
          indicatorColor="primary"
          aria-label="Stations views"
        >
          <Tab
            value={TAB_SEARCH}
            icon={<SearchIcon fontSize="small" />}
            iconPosition="start"
            label="Search"
            sx={{ minHeight: 56 }}
          />
          <Tab
            value={TAB_SAVED}
            icon={<BookmarkIcon fontSize="small" />}
            iconPosition="start"
            label="Saved"
            sx={{ minHeight: 56 }}
          />
          <Tab
            value={TAB_PREMIUM_93}
            icon={<LocalGasStationIcon fontSize="small" />}
            iconPosition="start"
            label="Premium 93"
            sx={{ minHeight: 56 }}
          />
          <Tab
            value={TAB_MAP}
            icon={<MapIcon fontSize="small" />}
            iconPosition="start"
            label="Map"
            sx={{ minHeight: 56 }}
          />
        </Tabs>
      </Box>

      {/* Tab content area */}
      <Box
        sx={{
          flex: 1,
          overflow: 'auto',
          WebkitOverflowScrolling: 'touch'
        }}
      >
        {/* Search Tab */}
        {activeTab === TAB_SEARCH && (
          <Box sx={{ p: 2, pb: 12 }}>
            <StationsSearchForm
              onSearch={handleSearch}
              isSearching={isSearching}
            />

            {enrichedStations.length > 0 && (
              <Box sx={{ mt: 3 }}>
                <StationsList
                  stations={enrichedStations}
                  savedPlaceIds={savedPlaceIds}
                  savedStationsMap={savedStationsMap}
                  loading={isSearching}
                  error={searchError ? 'Failed to search stations' : null}
                  onSaveStation={handleSaveStation}
                  onDeleteStation={handleDeleteStation}
                  onSelectStation={handleSelectStation}
                  onRetry={handleRefresh}
                  communityStationsMap={communityStationsMap}
                  onSubmitFor93={(station) => setSubmitFor93Station(station)}
                />
              </Box>
            )}
          </Box>
        )}

        {/* Saved Tab */}
        {activeTab === TAB_SAVED && (
          <Box sx={{ p: 2, pb: 12 }}>
            <SavedStationsList
              stations={savedStations || []}
              loading={isLoadingSaved}
              error={savedError ? 'Failed to load saved stations' : null}
              onSelectStation={handleSelectStation}
              onDeleteStation={handleDeleteStation}
              onSubmitFor93={(station) => setSubmitFor93Station(station as unknown as Station)}
              communityStationsMap={communityStationsMap}
              latitude={coordinates?.latitude ?? null}
              longitude={coordinates?.longitude ?? null}
            />
          </Box>
        )}

        {/* Premium 93 Tab */}
        {activeTab === TAB_PREMIUM_93 && (
          <Box sx={{ p: 2, pb: 12 }}>
            <Premium93TabContent
              latitude={coordinates?.latitude ?? null}
              longitude={coordinates?.longitude ?? null}
              savedStations={savedStations || []}
              communityStationsMap={communityStationsMap}
              onStationSelect={handleSelectPremium93Station}
              searchBounds={searchBounds}
              onSaveCommunityStation={handleSaveCommunityStation}
              onUnsaveCommunityStation={handleUnsaveCommunityStation}
              onSubmitFor93={(station) => setSubmitFor93Station(station as unknown as Station)}
              savedAddresses={savedAddresses}
            />
          </Box>
        )}

        {/* Map Tab */}
        {activeTab === TAB_MAP && (
          <Box sx={{ height: '100%', position: 'relative' }}>
            <StationMap
              stations={enrichedStations}
              savedPlaceIds={savedPlaceIds}
              currentLocation={coordinates ? {
                latitude: coordinates.latitude,
                longitude: coordinates.longitude
              } : undefined}
              onMarkerClick={handleSelectStation}
              height="100%"
            />

            {/* FAB to go back to search */}
            <Fab
              color="primary"
              size="medium"
              sx={{
                position: 'absolute',
                bottom: 16,
                right: 16,
                minWidth: '44px',
                minHeight: '44px'
              }}
              onClick={handleBackToSearch}
              aria-label="Back to search"
            >
              <SearchIcon />
            </Fab>
          </Box>
        )}
      </Box>

      {/* Bottom Sheet for Station Details */}
      <SwipeableDrawer
        anchor="bottom"
        open={drawerOpen}
        onClose={handleCloseDrawer}
        onOpen={() => setDrawerOpen(true)}
        disableBackdropTransition={!iOS}
        disableDiscovery={iOS}
        sx={{
          '& .MuiDrawer-paper': {
            borderTopLeftRadius: 16,
            borderTopRightRadius: 16,
            maxHeight: '80vh',
            overflow: 'visible'
          }
        }}
      >
        {selectedStation && (
          <Box sx={{ p: 2, pb: 4 }}>
            {/* Drawer handle */}
            <Box
              sx={{
                width: 40,
                height: 4,
                backgroundColor: theme.palette.divider,
                borderRadius: 2,
                margin: '0 auto 16px'
              }}
            />

            {/* Header */}
            <Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', mb: 2 }}>
              <Box sx={{ flex: 1 }}>
                <Typography variant="h6" sx={{ fontWeight: 600, mb: 0.5 }}>
                  {'nickname' in selectedStation && selectedStation.nickname
                    ? selectedStation.nickname
                    : selectedStation.name}
                </Typography>
                {'nickname' in selectedStation && selectedStation.nickname && (
                  <Typography variant="body2" color="text.secondary">
                    {selectedStation.name}
                  </Typography>
                )}
              </Box>
              <IconButton
                onClick={handleCloseDrawer}
                sx={{
                  minWidth: '44px',
                  minHeight: '44px'
                }}
                aria-label="Close"
              >
                <CloseIcon />
              </IconButton>
            </Box>

            <Divider sx={{ mb: 2 }} />

            {/* Station Details */}
            <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
              <Box>
                <Typography variant="caption" color="text.secondary">
                  Address
                </Typography>
                <Typography variant="body1">
                  {selectedStation.address}
                </Typography>
              </Box>

              {selectedStation.rating > 0 && (
                <Box>
                  <Typography variant="caption" color="text.secondary">
                    Rating
                  </Typography>
                  <Typography variant="body1">
                    {selectedStation.rating.toFixed(1)} / 5.0
                  </Typography>
                </Box>
              )}

              {selectedStation.distance !== undefined && (
                <Box>
                  <Typography variant="caption" color="text.secondary">
                    Distance
                  </Typography>
                  <Typography variant="body1">
                    {(selectedStation.distance / 1609.34).toFixed(1)} miles away
                  </Typography>
                </Box>
              )}

              {'notes' in selectedStation && selectedStation.notes && (
                <Box>
                  <Typography variant="caption" color="text.secondary">
                    Notes
                  </Typography>
                  <Typography variant="body1">
                    {selectedStation.notes}
                  </Typography>
                </Box>
              )}

              {navigationLinks && (
                <Box>
                  <Typography variant="caption" color="text.secondary">
                    Navigate
                  </Typography>
                  <Box
                    sx={{
                      display: 'flex',
                      flexWrap: 'wrap',
                      gap: 1,
                      mt: 1
                    }}
                  >
                    <Button
                      variant="outlined"
                      size="small"
                      component="a"
                      href={navigationLinks.google}
                      target="_blank"
                      rel="noopener"
                    >
                      Navigate in Google
                    </Button>
                    <Button
                      variant="outlined"
                      size="small"
                      component="a"
                      href={navigationLinks.apple}
                      target="_blank"
                      rel="noopener"
                    >
                      Navigate in Apple Maps
                    </Button>
                    <Button
                      variant="outlined"
                      size="small"
                      component="a"
                      href={navigationLinks.waze}
                      target="_blank"
                      rel="noopener"
                    >
                      Navigate in Waze
                    </Button>
                  </Box>
                </Box>
              )}
            </Box>
          </Box>
        )}
      </SwipeableDrawer>

      {/* Submit for 93 Dialog */}
      <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 StationsMobileScreen;
