'use client';

import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Search, MapPin, Clock, ChevronLeft, ChevronRight } from 'lucide-react';
import { motion, AnimatePresence } from 'motion/react';
import dynamic from 'next/dynamic';
import type { MoroccoCity } from './MoroccoLeafletMap';
import { fetchCities } from '@/lib/cities/client';
import type { CityTariffRow } from '@/lib/cities/types';

type DurationFilter = 'all' | '24h' | '48h' | '72h' | 'pickup';

interface MoroccoMapProps {
  className?: string;
}

function useMediaQuery(query: string) {
  // IMPORTANT: initialize to `false` so server HTML matches the first client render.
  // We'll compute the real value after mount in an effect to avoid hydration mismatch.
  const [matches, setMatches] = useState(false);

  useEffect(() => {
    // `window` is always defined here.
    const media = window.matchMedia(query);
    const onChange = () => setMatches(media.matches);
    onChange();
    media.addEventListener?.('change', onChange);
    return () => media.removeEventListener?.('change', onChange);
  }, [query]);

  return matches;
}

const MoroccoLeafletMap = dynamic(
  () => import('./MoroccoLeafletMap').then((m) => m.MoroccoLeafletMap),
  {
    ssr: false,
    loading: () => <div className="w-full h-full bg-gradient-to-br from-blue-50 to-blue-100" />,
  }
);

export function MoroccoMap({ className = '' }: MoroccoMapProps) {
  const { t, i18n } = useTranslation();
  const [cities, setCities] = useState<CityTariffRow[]>([]);
  const [citiesError, setCitiesError] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedDuration, setSelectedDuration] = useState<DurationFilter>('all');
  const [selectedCity, setSelectedCity] = useState<string | null>(null);
  const [hoveredCity, setHoveredCity] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(1);
  const ITEMS_PER_PAGE = 5;

  const currentLang = i18n.language as 'en' | 'fr' | 'ar';
  const isDesktop = useMediaQuery('(min-width: 1024px)');

  useEffect(() => {
    let cancelled = false;
    fetchCities()
      .then((data) => {
        if (cancelled) return;
        setCities(data);
        setCitiesError(null);
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        setCitiesError(err instanceof Error ? err.message : 'Failed to load cities');
        setCities([]);
      });
    return () => {
      cancelled = true;
    };
  }, []);

  const mapCities: MoroccoCity[] = useMemo(() => {
    return cities
      .filter((c) => c.x != null && c.y != null)
      .map((c) => ({
        id: c.id,
        name: c.name,
        lng: c.x,
        lat: c.y,
        pickup: c.pickup,
        duration: c.duration,
        price: c.price,
      }));
  }, [cities]);

  // Filter cities based on search and duration
  const filteredCities = useMemo(() => {
    return mapCities.filter(city => {
      const matchesSearch = city.name[currentLang].toLowerCase().includes(searchQuery.toLowerCase());
      
      if (!matchesSearch) return false;
      
      if (selectedDuration === 'all') return true;
      const duration = String(city.duration ?? '').toUpperCase();
      if (selectedDuration === '24h') return duration === '24H';
      if (selectedDuration === '48h') return duration === '48H';
      if (selectedDuration === '72h') return duration === '72H';
      if (selectedDuration === 'pickup') return city.pickup;
      
      return true;
    });
  }, [mapCities, searchQuery, selectedDuration, currentLang]);

  // Pagination
  const totalPages = Math.ceil(filteredCities.length / ITEMS_PER_PAGE);
  const paginatedCities = filteredCities.slice(
    (currentPage - 1) * ITEMS_PER_PAGE,
    currentPage * ITEMS_PER_PAGE
  );

  const handleCityClick = (cityId: string) => {
    setSelectedCity(cityId);
  };

  const durationFilters: { key: DurationFilter; label: string }[] = [
    { key: 'all', label: t('map.filters.all', 'All Cities') },
    { key: '24h', label: '24H' },
    { key: '48h', label: '48H' },
    { key: '72h', label: '72H' },
    { key: 'pickup', label: t('map.filters.pickup', 'Pickup') },
  ];

  return (
    <div className={`relative w-full rounded-2xl overflow-hidden shadow-2xl bg-white ${className}`}>
      {citiesError ? (
        <div className="px-4 py-3 bg-red-50 text-red-700 text-sm border-b border-red-200">
          {citiesError}
        </div>
      ) : null}

      {/* Mobile Layout */}
      {!isDesktop ? (
        <div className="lg:hidden">
          {/* Mobile Search & Filters Section */}
          <div className="bg-white p-4 space-y-4">
            {/* Search */}
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
                <input
                  type="text"
                  placeholder={t('map.search', 'Search for a city...')}
                  value={searchQuery}
                  onChange={(e) => {
                    setSearchQuery(e.target.value);
                    setCurrentPage(1);
                  }}
                  className="w-full pl-11 pr-4 py-3 bg-gray-50 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#3A4A9C]/20 transition-all"
                />
            </div>

            {/* Duration Filters - Scrollable on mobile */}
            <div className="overflow-x-auto scrollbar-hide -mx-4 px-4">
              <div className="flex gap-2 min-w-max">
                {durationFilters.map((filter) => (
                  <button
                    key={filter.key}
                    onClick={() => {
                      setSelectedDuration(filter.key);
                      setCurrentPage(1);
                    }}
                    className={`px-4 py-2 rounded-lg text-xs font-medium transition-all whitespace-nowrap flex-shrink-0 ${
                      selectedDuration === filter.key
                        ? 'bg-[#3A4A9C] text-white shadow-md'
                        : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
                    } ${filter.key !== 'all' && filter.key !== 'pickup' ? 'font-mono' : ''}`}
                  >
                    {filter.label}
                  </button>
                ))}
              </div>
            </div>
          </div>

          {/* Mobile Map View - OpenStreetMap */}
          <div className="relative h-[300px]">
            <MoroccoLeafletMap
              cities={filteredCities}
              selectedCity={selectedCity}
              hoveredCity={hoveredCity}
              onSelect={handleCityClick}
              onHover={setHoveredCity}
            />
          </div>

          {/* Mobile City List - Cards */}
          <div className="p-4 bg-gray-50 space-y-3 max-h-[400px] overflow-y-auto">
            <AnimatePresence>
              {paginatedCities.map((city, index) => (
                <motion.div
                  key={city.id}
                  initial={{ opacity: 0, y: 10 }}
                  animate={{ opacity: 1, y: 0 }}
                  exit={{ opacity: 0, y: -10 }}
                  transition={{ delay: index * 0.05 }}
                  onClick={() => handleCityClick(city.id)}
                  onMouseEnter={() => setHoveredCity(city.id)}
                  onMouseLeave={() => setHoveredCity(null)}
                  className={`p-4 rounded-lg cursor-pointer transition-all bg-white border-2 ${
                    selectedCity === city.id || hoveredCity === city.id
                      ? 'border-[#3A4A9C] shadow-md'
                      : 'border-transparent shadow-sm'
                  }`}
                >
                  <div className="flex items-start justify-between gap-3">
                    <div className="flex items-start gap-3 flex-1 min-w-0">
                      <div className="flex-shrink-0">
                        <div className="w-10 h-10 rounded-full bg-[#3A4A9C]/10 flex items-center justify-center">
                          <MapPin className="w-5 h-5 text-[#3A4A9C]" />
                        </div>
                      </div>
                      
                      <div className="flex-1 min-w-0">
                        <h4 className="font-semibold text-gray-900 truncate">
                          {city.name[currentLang]}
                        </h4>
                        <div className="flex items-center gap-2 mt-1">
                          <Clock className="w-3.5 h-3.5 text-gray-400" />
                          <span className="text-xs text-gray-500 font-mono">
                            {city.duration ?? '—'}
                          </span>
                        </div>
                      </div>
                    </div>

                    <div className="flex flex-col items-end gap-1.5">
                      {city.price ? (
                        <span className="px-2.5 py-1 bg-[#3A4A9C] text-white text-xs font-medium rounded-full font-mono whitespace-nowrap">
                          {city.price}
                        </span>
                      ) : null}
                      {city.pickup && (
                        <span className="px-2.5 py-1 bg-emerald-500 text-white text-xs font-medium rounded-full whitespace-nowrap">
                          {t('map.pickup', 'Pickup')}
                        </span>
                      )}
                    </div>
                  </div>
                </motion.div>
              ))}
            </AnimatePresence>

            {/* Mobile Pagination */}
            {totalPages > 1 && (
              <div className="pt-3 border-t border-gray-200">
                <div className="flex items-center justify-between">
                  <span className="text-xs text-gray-600 font-mono">
                    {(currentPage - 1) * ITEMS_PER_PAGE + 1}-{Math.min(currentPage * ITEMS_PER_PAGE, filteredCities.length)} / {filteredCities.length}
                  </span>
                  <div className="flex gap-2">
                    <button
                      onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
                      disabled={currentPage === 1}
                      className="w-8 h-8 rounded flex items-center justify-center bg-white border border-gray-200 text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all"
                    >
                      <ChevronLeft className="w-4 h-4" />
                    </button>
                    {Array.from({ length: Math.min(totalPages, 3) }, (_, i) => {
                      let page;
                      if (totalPages <= 3) {
                        page = i + 1;
                      } else if (currentPage === 1) {
                        page = i + 1;
                      } else if (currentPage === totalPages) {
                        page = totalPages - 2 + i;
                      } else {
                        page = currentPage - 1 + i;
                      }
                      return (
                        <button
                          key={page}
                          onClick={() => setCurrentPage(page)}
                          className={`w-8 h-8 rounded text-xs font-medium font-mono transition-all ${
                            currentPage === page
                              ? 'bg-[#3A4A9C] text-white'
                              : 'bg-white border border-gray-200 text-gray-700 hover:bg-gray-50'
                          }`}
                        >
                          {page}
                        </button>
                      );
                    })}
                    <button
                      onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
                      disabled={currentPage === totalPages}
                      className="w-8 h-8 rounded flex items-center justify-center bg-white border border-gray-200 text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-all"
                    >
                      <ChevronRight className="w-4 h-4" />
                    </button>
                  </div>
                </div>
              </div>
            )}
          </div>
        </div>
      ) : null}

      {/* Desktop Layout */}
      {isDesktop ? (
      <div className="hidden lg:block relative w-full h-[600px]">
        {/* Sidebar */}
        <motion.div 
          initial={{ x: -20, opacity: 0 }}
          animate={{ x: 0, opacity: 1 }}
          className="absolute left-6 top-6 bottom-6 w-[420px] bg-white rounded-xl shadow-xl z-20 flex flex-col overflow-hidden"
        >
          {/* Search */}
          <div className="p-5 border-b border-gray-100">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
              <input
                type="text"
                placeholder={t('map.search', 'Search for a city...')}
                value={searchQuery}
                onChange={(e) => {
                  setSearchQuery(e.target.value);
                  setCurrentPage(1);
                }}
                className="w-full pl-11 pr-4 py-3 bg-gray-50 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#3A4A9C]/20 transition-all"
              />
            </div>
          </div>

          {/* Duration Filters */}
          <div className="p-5 border-b border-gray-100">
            <div className="flex flex-nowrap gap-1.5">
              {durationFilters.map((filter) => (
                <button
                  key={filter.key}
                  onClick={() => {
                    setSelectedDuration(filter.key);
                    setCurrentPage(1);
                  }}
                  className={`px-3 py-2 rounded-lg text-xs font-medium transition-all whitespace-nowrap flex-shrink-0 ${
                    selectedDuration === filter.key
                      ? 'bg-[#3A4A9C] text-white shadow-md'
                      : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
                  } ${filter.key !== 'all' && filter.key !== 'pickup' ? 'font-mono' : ''}`}
                >
                  {filter.label}
                </button>
              ))}
            </div>
          </div>

          {/* City List */}
          <div className="flex-1 overflow-y-auto scrollbar-dropex">
            <div className="divide-y divide-gray-100">
              <AnimatePresence>
                {paginatedCities.map((city, index) => (
                  <motion.div
                    key={city.id}
                    initial={{ opacity: 0, y: 10 }}
                    animate={{ opacity: 1, y: 0 }}
                    exit={{ opacity: 0, y: -10 }}
                    transition={{ delay: index * 0.05 }}
                    onClick={() => handleCityClick(city.id)}
                    onMouseEnter={() => setHoveredCity(city.id)}
                    onMouseLeave={() => setHoveredCity(null)}
                    className={`p-4 cursor-pointer transition-all ${
                      selectedCity === city.id || hoveredCity === city.id
                        ? 'bg-[#3A4A9C]/5'
                        : 'hover:bg-gray-50'
                    }`}
                  >
                    <div className="flex items-center gap-3">
                      <div className="flex-shrink-0">
                        <div className="w-10 h-10 rounded-full bg-[#3A4A9C]/10 flex items-center justify-center">
                          <MapPin className="w-5 h-5 text-[#3A4A9C]" />
                        </div>
                      </div>
                      
                      <div className="flex-1 min-w-0">
                        <h4 className="font-semibold text-gray-900 truncate">
                          {city.name[currentLang]}
                        </h4>
                        <div className="flex items-center gap-2 mt-1">
                          <Clock className="w-3.5 h-3.5 text-gray-400" />
                          <span className="text-xs text-gray-500 font-mono">
                            {city.duration ?? '—'}
                          </span>
                        </div>
                      </div>

                      <div className="flex items-center gap-2">
                        {city.price ? (
                          <span className="px-3 py-1.5 bg-[#3A4A9C] text-white text-sm font-medium rounded-full font-mono">
                            {city.price}
                          </span>
                        ) : null}
                        {city.pickup && (
                          <span className="px-3 py-1.5 bg-emerald-500 text-white text-sm font-medium rounded-full">
                            {t('map.pickup', 'Pickup')}
                          </span>
                        )}
                      </div>
                    </div>
                  </motion.div>
                ))}
              </AnimatePresence>
            </div>
          </div>

          {/* Pagination */}
          {totalPages > 1 && (
            <div className="p-4 border-t border-gray-100">
              <div className="flex items-center justify-between">
                <span className="text-sm text-gray-600 font-mono">
                  {(currentPage - 1) * ITEMS_PER_PAGE + 1} to {Math.min(currentPage * ITEMS_PER_PAGE, filteredCities.length)} of {filteredCities.length}
                </span>
                <div className="flex gap-2">
                  <button
                    onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
                    disabled={currentPage === 1}
                    className="w-8 h-8 rounded flex items-center justify-center bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-all"
                  >
                    <ChevronLeft className="w-4 h-4" />
                  </button>
                  {Array.from({ length: Math.min(totalPages, 3) }, (_, i) => {
                    let page;
                    if (totalPages <= 3) {
                      page = i + 1;
                    } else if (currentPage === 1) {
                      page = i + 1;
                    } else if (currentPage === totalPages) {
                      page = totalPages - 2 + i;
                    } else {
                      page = currentPage - 1 + i;
                    }
                    return (
                      <button
                        key={page}
                        onClick={() => setCurrentPage(page)}
                        className={`w-8 h-8 rounded text-sm font-medium font-mono transition-all ${
                          currentPage === page
                            ? 'bg-[#3A4A9C] text-white'
                            : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
                        }`}
                      >
                        {page}
                      </button>
                    );
                  })}
                  <button
                    onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
                    disabled={currentPage === totalPages}
                    className="w-8 h-8 rounded flex items-center justify-center bg-gray-100 text-gray-700 hover:bg-gray-200 disabled:opacity-50 disabled:cursor-not-allowed transition-all"
                  >
                    <ChevronRight className="w-4 h-4" />
                  </button>
                </div>
              </div>
            </div>
          )}
        </motion.div>

        {/* Map Container - OpenStreetMap */}
        <div className="absolute inset-0 z-0">
          <MoroccoLeafletMap
            cities={filteredCities}
            selectedCity={selectedCity}
            hoveredCity={hoveredCity}
            onSelect={handleCityClick}
            onHover={setHoveredCity}
          />
        </div>
      </div>
      ) : null}
    </div>
  );
}
