'use client';

import {
  Check,
  ChevronLeft,
  ChevronRight,
  Filter,
  List,
  MapPin,
} from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';

import { Stations } from '@/app/api-utlities/@types';

import { useTextController } from '@/shared/language/hooks/use-text-controller';
import { Badge } from '@/shared/shadcn-ui/badge';
import { Button } from '@/shared/shadcn-ui/button';
import { Separator } from '@/shared/shadcn-ui/separator';
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from '@/shared/shadcn-ui/tabs';

import { Point } from '../model';
import { YandexMap } from './yandex-map';

// Пропсы для компонента GasStationMap
interface GasStationMapProps {
  stations: Stations;
}

// Пропсы для панели фильтров
interface FilterPanelProps {
  isOpen: boolean;
  onClose: () => void;
  activeFilters: string[];
  activeCities: string[];
  allCities: string[];
  allFilters: string[];
  activeFilterTab: string;
  toggleFilter: (filter: string) => void;
  toggleCity: (city: string) => void;
  selectAllCities: () => void;
  setActiveFilterTab: (tab: string) => void;
  resetFilters: () => void;
  resetCities: () => void;
}

// Пропсы для панели списка станций
interface StationListPanelProps {
  isOpen: boolean;
  onClose: () => void;
  stations: Stations;
  selectedStation: number | null;
  activeFilters: string[];
  activeCities: string[];
  handleMapStationClick: (id: number) => void;
  filterToFieldMap: { [key: string]: keyof Stations[number] };
  allFilters: string[];
  resetFilters: () => void;
  resetCities: () => void;
}

// Компонент панели фильтров
function FilterPanel({
  isOpen,
  onClose,
  activeFilters,
  activeCities,
  allCities,
  allFilters,
  activeFilterTab,
  toggleFilter,
  toggleCity,
  selectAllCities,
  setActiveFilterTab,
  resetFilters,
  resetCities,
}: FilterPanelProps) {
  const { t } = useTextController();

  return (
    <div
      className={`absolute top-0 bottom-0 left-0 z-20 transform bg-white shadow-lg transition-transform duration-300 ${
        isOpen ? 'translate-x-0' : '-translate-x-full'
      }`}
      style={{ width: '300px' }}
    >
      <div className='flex items-center justify-between border-b border-gray-200 p-4'>
        <div className='flex items-center gap-2'>
          <Filter className='h-5 w-5 text-red-600' />
          <span className='font-medium'>{t('map.filters')}</span>
        </div>
        <Button variant='ghost' size='sm' onClick={onClose}>
          <ChevronLeft className='h-5 w-5' />
        </Button>
      </div>

      <div className='p-4'>
        <Tabs
          value={activeFilterTab}
          onValueChange={setActiveFilterTab}
          className='w-full'
        >
          <TabsList className='mb-4 grid w-full grid-cols-2'>
            <TabsTrigger value='cities'>{t('map.cities')}</TabsTrigger>
            <TabsTrigger value='services'>{t('map.services')}</TabsTrigger>
          </TabsList>

          <TabsContent
            value='cities'
            className='mt-0 max-h-[300px] overflow-y-auto py-2 pr-1'
          >
            <Button
              variant='outline'
              size='sm'
              className='mb-3 flex w-full items-center justify-between'
              onClick={selectAllCities}
            >
              <span>{t('map.allCities')}</span>
              {activeCities.length === allCities.length && (
                <Check className='h-4 w-4 text-green-600' />
              )}
            </Button>

            <div className='flex max-h-[calc(100vh-250px)] flex-col gap-2 overflow-y-auto'>
              {allCities.map((city) => (
                <Button
                  key={city}
                  variant={activeCities.includes(city) ? 'default' : 'outline'}
                  size='sm'
                  className={`justify-between ${
                    activeCities.includes(city)
                      ? 'bg-red-600 hover:bg-red-700'
                      : ''
                  }`}
                  onClick={() => toggleCity(city)}
                >
                  <span>{city}</span>
                  {activeCities.includes(city) && (
                    <Check className='ml-2 h-4 w-4' />
                  )}
                </Button>
              ))}
            </div>
          </TabsContent>

          <TabsContent value='services' className='mt-0'>
            <div className='flex flex-wrap gap-2'>
              {allFilters.map((filter) => (
                <Button
                  key={filter}
                  variant={
                    activeFilters.includes(filter) ? 'default' : 'outline'
                  }
                  size='sm'
                  className={
                    activeFilters.includes(filter)
                      ? 'bg-red-600 hover:bg-red-700'
                      : ''
                  }
                  onClick={() => toggleFilter(filter)}
                >
                  {filter}
                </Button>
              ))}
            </div>
          </TabsContent>

          <Separator className='mt-2' />

          {/* Кнопка сброса фильтров */}
          {activeFilterTab === 'cities'
            ? activeCities.length > 0 && (
                <Button
                  variant='link'
                  className='p-0 text-red-600'
                  onClick={resetCities}
                >
                  {t('common.buttons.resetFilters')}
                </Button>
              )
            : activeFilters.length > 0 && (
                <Button
                  variant='link'
                  className='mt-4 p-0 text-red-600'
                  onClick={resetFilters}
                >
                  {t('common.buttons.resetFilters')}
                </Button>
              )}
        </Tabs>
      </div>
    </div>
  );
}

// Компонент панели списка станций
function StationListPanel({
  isOpen,
  onClose,
  stations,
  selectedStation,
  activeFilters,
  activeCities,
  handleMapStationClick,
  filterToFieldMap,
  allFilters,
  resetCities,
  resetFilters,
}: StationListPanelProps) {
  const { t } = useTextController();
  const scrollContainerRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    if (!selectedStation || !scrollContainerRef.current) return;

    const selectedStationItem = document.getElementById(
      `station_${selectedStation}`,
    );

    if (selectedStationItem) {
      const container = scrollContainerRef.current;
      const itemRect = selectedStationItem.getBoundingClientRect();
      const containerRect = container.getBoundingClientRect();

      // Calculate the item's position relative to the container
      const itemTopRelativeToContainer =
        itemRect.top - containerRect.top + container.scrollTop - 10;

      // Scroll the container to bring the item into view
      container.scrollTo({
        top: itemTopRelativeToContainer,
        behavior: 'smooth',
      });
    }
  }, [selectedStation]);

  return (
    <div
      className={`absolute top-0 right-0 bottom-0 z-20 transform bg-white shadow-lg transition-transform duration-300 ${
        isOpen ? 'translate-x-0' : 'translate-x-full'
      }`}
      style={{ width: '350px' }}
    >
      <div className='flex items-center justify-between border-b border-gray-200 p-4'>
        <Button variant='ghost' size='sm' onClick={onClose}>
          <ChevronRight className='h-5 w-5' />
        </Button>
        <div className='flex items-center gap-2'>
          <span className='font-medium'>{t('map.stationsList')}</span>
          <Badge>{stations.length}</Badge>
        </div>
      </div>
      <div
        className='overflow-y-auto'
        style={{ height: 'calc(100% - 60px)' }}
        ref={scrollContainerRef}
      >
        {stations.length > 0 ? (
          <div className='p-2'>
            {stations.map((station) => {
              const services = allFilters.filter(
                (filter) => station[filterToFieldMap[filter]],
              );

              return (
                <div
                  key={station.id}
                  id={`station_${station.id}`}
                  className={`mb-2 cursor-pointer rounded-lg border p-3 transition-colors ${
                    selectedStation === station.id
                      ? 'border-blue-500 bg-blue-50'
                      : 'border-gray-200 hover:bg-gray-50'
                  }`}
                  onClick={() => handleMapStationClick(station.id)}
                >
                  <div className='flex items-start justify-between'>
                    <h4 className='font-medium'>{station.name}</h4>
                    <ChevronRight className='h-4 w-4 text-gray-400' />
                  </div>
                  <p className='mb-2 text-sm text-gray-500'>
                    {station.address}
                  </p>
                  {station.workingHours && (
                    <p className='mb-2 text-sm text-gray-500'>
                      {t('map.workingHours')}: {station.workingHours}
                    </p>
                  )}
                  {station.description && (
                    <p className='mb-2 text-sm text-gray-500'>
                      {station.description}
                    </p>
                  )}
                  <div className='flex flex-wrap gap-1'>
                    {station.region && (
                      <Badge className='mb-1 border-blue-200 bg-blue-100 text-blue-800'>
                        {station.region}
                      </Badge>
                    )}
                    {services.map((service) => (
                      <Badge
                        key={service}
                        variant='outline'
                        className={
                          activeFilters.includes(service)
                            ? 'border-red-200 bg-red-100 text-red-800'
                            : ''
                        }
                      >
                        {service}
                      </Badge>
                    ))}
                  </div>
                  {station.image && (
                    <img
                      src={station.image}
                      alt={station.name}
                      className='mt-2 h-20 w-full rounded object-cover'
                    />
                  )}
                </div>
              );
            })}
          </div>
        ) : (
          <div className='p-4 text-center text-gray-500'>
            <p>{t('map.noStations')}</p>
            <div className='mt-2 flex justify-center gap-2'>
              {activeFilters.length > 0 && (
                <Button
                  variant='link'
                  className='text-red-600'
                  onClick={resetFilters}
                >
                  {t('common.buttons.resetFilters')}
                </Button>
              )}
              {activeCities.length > 0 && (
                <Button
                  variant='link'
                  className='text-red-600'
                  onClick={resetCities}
                >
                  {t('map.allCities')}
                </Button>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

// Главный компонент
export default function GasStationMap({ stations }: GasStationMapProps) {
  const { t } = useTextController();
  const [activeFilters, setActiveFilters] = useState<string[]>([]);
  const [activeCities, setActiveCities] = useState<string[]>([]);
  const [selectedStation, setSelectedStation] = useState<number | null>(null);
  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [isStationListOpen, setIsStationListOpen] = useState(false);
  const [activeFilterTab, setActiveFilterTab] = useState('cities');

  useEffect(() => {
    if (selectedStation === null) return;
    setIsStationListOpen(true);
  }, [selectedStation]);

  // Все доступные фильтры
  const allFilters = [
    'ДТ',
    'АИ-92',
    'АИ-95',
    'Z-100 Power',
    'Пропан',
    'Зарядная станция',
    'Минимаркет',
    'Автомойка',
    'Туалет',
  ];

  // Маппинг фильтров на поля Station
  const filterToFieldMap: { [key: string]: keyof Stations[number] } = {
    'АИ-92': 'ai92',
    ДТ: 'dt',
    'АИ-95': 'ai95',
    'Z-100 Power': 'z100',
    Пропан: 'propan',
    'Зарядная станция': 'electricCharge',
    Минимаркет: 'miniMarket',
    Автомойка: 'carWash',
    Туалет: 'toilet',
  };

  // Мемоизация списка уникальных регионов
  const allCities = useMemo(() => {
    return [
      ...new Set(
        stations
          .map((station) => station.region)
          .filter((region): region is string => region !== null),
      ),
    ].sort();
  }, [stations]);

  // Мемоизация фильтрованных станций
  const filteredStations = useMemo(() => {
    let filtered = stations;

    // Фильтрация по регионам (ИЛИ)
    if (activeCities.length > 0) {
      filtered = filtered.filter(
        (station) => station.region && activeCities.includes(station.region),
      );
    }

    // Фильтрация по услугам (И)
    if (activeFilters.length > 0) {
      filtered = filtered.filter((station) =>
        activeFilters.every((filter) => {
          const field = filterToFieldMap[filter];
          return Boolean(station[field]) === true;
        }),
      );
    }
    return filtered;
  }, [activeFilters, activeCities, stations]);

  // Мемоизация точек для карты
  const points = useMemo(
    (): Point[] =>
      filteredStations.map((st) => ({
        id: st.id,
        coordinates: [st.latitude, st.longitude],
      })),
    [filteredStations],
  );

  const handleMapStationClick = (stationId: number) => {
    setSelectedStation(() => {
      if (selectedStation !== null && selectedStation === stationId) {
        return null;
      }

      return stationId;
    });
  };

  // Переключение фильтра услуг
  const toggleFilter = (filter: string) => {
    setActiveFilters((prev) =>
      prev.includes(filter)
        ? prev.filter((f) => f !== filter)
        : [...prev, filter],
    );
  };

  // Переключение фильтра региона
  const toggleCity = (city: string) => {
    setActiveCities((prev) =>
      prev.includes(city) ? prev.filter((c) => c !== city) : [...prev, city],
    );
  };

  // Выбор всех регионов
  const selectAllCities = () => {
    setActiveCities(
      activeCities.length === allCities.length ? [] : [...allCities],
    );
  };

  // Сброс фильтров услуг
  const resetFilters = () => {
    setActiveFilters([]);
  };

  // Сброс фильтров регионов
  const resetCities = () => {
    setActiveCities([]);
  };

  return (
    <div className='relative h-full w-full'>
      {/* Filter panel */}
      <FilterPanel
        isOpen={isFilterOpen}
        onClose={() => setIsFilterOpen(false)}
        activeFilters={activeFilters}
        activeCities={activeCities}
        allCities={allCities}
        allFilters={allFilters}
        activeFilterTab={activeFilterTab}
        toggleFilter={toggleFilter}
        toggleCity={toggleCity}
        selectAllCities={selectAllCities}
        setActiveFilterTab={setActiveFilterTab}
        resetFilters={resetFilters}
        resetCities={resetCities}
      />

      {/* Station list panel */}
      <StationListPanel
        isOpen={isStationListOpen}
        onClose={() => setIsStationListOpen(false)}
        stations={filteredStations}
        selectedStation={selectedStation}
        activeFilters={activeFilters}
        activeCities={activeCities}
        handleMapStationClick={handleMapStationClick}
        filterToFieldMap={filterToFieldMap}
        allFilters={allFilters}
        resetFilters={resetFilters}
        resetCities={resetCities}
      />

      {/* Map */}
      <div className='h-full w-full'>
        <YandexMap
          points={points}
          selectedStation={selectedStation}
          handleMapStationClick={handleMapStationClick}
        />
      </div>

      {/* Control buttons */}
      <div className='absolute top-4 left-4 z-10'>
        <Button
          variant='default'
          size='sm'
          className='border border-gray-200 bg-white text-gray-800 shadow-md hover:bg-gray-100'
          onClick={() => setIsFilterOpen(true)}
        >
          <Filter className='h-4 w-4 text-red-600 sm:mr-2' />
          <span className='hidden sm:flex'>{t('map.filters')}</span>
          {(activeFilters.length > 0 || activeCities.length > 0) && (
            <Badge className='ml-2 bg-red-600' variant='default'>
              {activeFilters.length + activeCities.length}
            </Badge>
          )}
        </Button>
      </div>

      <div className='absolute top-4 right-4 z-10'>
        <Button
          variant='default'
          size='sm'
          className='border border-gray-200 bg-white text-gray-800 shadow-md hover:bg-gray-100'
          onClick={() => setIsStationListOpen(true)}
        >
          <List className='h-4 w-4 text-red-600 sm:mr-2' />
          <span className='hidden sm:flex'>{t('map.stationsList')}</span>
          <Badge className='ml-2 bg-red-600' variant='default'>
            {filteredStations.length}
          </Badge>
        </Button>
      </div>

      <div className='absolute bottom-4 left-4 rounded-lg bg-white p-3 shadow-lg'>
        <div className='flex items-center gap-2 text-sm font-medium'>
          <MapPin className='h-5 w-5 text-red-600' />
          <span>{t('map.ourStations')}</span>
        </div>
        <p className='mt-1 text-xs text-gray-500'>
          {t('map.totalStations')}: {filteredStations.length}
        </p>
      </div>
    </div>
  );
}
