import React, { useState, useEffect, useRef } from "react";
import { useSearchParams, useNavigate } from "react-router-dom";
import { Item } from "../types";
import { itemAPI } from "../services/api";
import ItemCard from "../components/ItemCard";
import SearchResultsMap from "../components/SearchResultsMap";
import FilterPanel from "../components/FilterPanel";
import { useAuth } from "../contexts/AuthContext";

const ITEMS_PER_PAGE = 20;

const ItemList: React.FC = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const navigate = useNavigate();
  const { user } = useAuth();
  const [items, setItems] = useState<Item[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [viewMode, setViewMode] = useState<'list' | 'map'>('list');
  const [showFilterPanel, setShowFilterPanel] = useState(false);
  const [locationName, setLocationName] = useState(searchParams.get("locationName") || "");
  const locationCheckDone = useRef(false);
  const filterButtonRef = useRef<HTMLDivElement>(null);
  const [currentPage, setCurrentPage] = useState(parseInt(searchParams.get("page") || "1"));
  const [totalPages, setTotalPages] = useState(1);
  const [totalItems, setTotalItems] = useState(0);
  const [filters, setFilters] = useState({
    search: searchParams.get("search") || "",
    city: searchParams.get("city") || "",
    zipCode: searchParams.get("zipCode") || "",
    lat: searchParams.get("lat") || "",
    lng: searchParams.get("lng") || "",
    radius: searchParams.get("radius") || "",
  });

  // Auto-apply user's saved address if no location is set
  useEffect(() => {
    // Only run this check once per mount
    if (locationCheckDone.current) return;

    const hasLocation = searchParams.has("lat") || searchParams.has("city") || searchParams.has("zipCode");

    if (!hasLocation) {
      // Check user's saved address for lat/lng
      const userLat = user?.addresses?.[0]?.latitude;
      const userLng = user?.addresses?.[0]?.longitude;

      if (userLat && userLng) {
        // Use saved address coordinates
        const params = new URLSearchParams(searchParams);
        params.set("lat", userLat.toString());
        params.set("lng", userLng.toString());
        params.set("radius", "25");
        locationCheckDone.current = true;
        navigate(`/items?${params.toString()}`, { replace: true });
      } else {
        locationCheckDone.current = true;
      }
    } else {
      locationCheckDone.current = true;
    }
  }, [user, searchParams, navigate]);

  useEffect(() => {
    fetchItems();
  }, [filters, currentPage]);

  // Reset to page 1 when filters change
  useEffect(() => {
    setCurrentPage(1);
  }, [filters.search, filters.city, filters.zipCode, filters.lat, filters.lng, filters.radius]);

  // Update filters when URL params change (e.g., from navbar search)
  useEffect(() => {
    setFilters({
      search: searchParams.get("search") || "",
      city: searchParams.get("city") || "",
      zipCode: searchParams.get("zipCode") || "",
      lat: searchParams.get("lat") || "",
      lng: searchParams.get("lng") || "",
      radius: searchParams.get("radius") || "",
    });
    setLocationName(searchParams.get("locationName") || "");
  }, [searchParams]);

  const handleApplyFilters = (newFilters: {
    lat: string;
    lng: string;
    radius: string;
    locationName: string;
  }) => {
    const params = new URLSearchParams(searchParams);

    if (newFilters.lat && newFilters.lng) {
      params.set("lat", newFilters.lat);
      params.set("lng", newFilters.lng);
      params.set("radius", newFilters.radius || "25");
      params.set("locationName", newFilters.locationName);
      // Remove city/zipCode since we're using coordinates
      params.delete("city");
      params.delete("zipCode");
    } else {
      // Clear location filters
      params.delete("lat");
      params.delete("lng");
      params.delete("radius");
      params.delete("locationName");
    }

    setLocationName(newFilters.locationName);
    navigate(`/items?${params.toString()}`, { replace: true });
  };

  const hasActiveLocationFilter = filters.lat && filters.lng;

  const fetchItems = async () => {
    try {
      setLoading(true);
      const params: Record<string, string | number> = {
        ...filters,
        page: currentPage,
        limit: ITEMS_PER_PAGE,
      };
      // Remove empty filters
      Object.keys(params).forEach((key) => {
        if (!params[key]) {
          delete params[key];
        }
      });

      const response = await itemAPI.getItems(params);
      // Access the items array from response.data.items
      const allItems = response.data.items || response.data || [];
      // Filter only available items
      const availableItems = allItems.filter((item: Item) => item.isAvailable);
      setItems(availableItems);
      setTotalPages(response.data.totalPages || 1);
      setTotalItems(response.data.totalItems || availableItems.length);
    } catch (err: any) {
      console.error("Error fetching items:", err);
      console.error("Error response:", err.response);
      setError(
        err.response?.data?.message || err.message || "Failed to fetch items"
      );
    } finally {
      setLoading(false);
    }
  };

  const handleItemSelect = (item: Item) => {
    navigate(`/items/${item.id}`);
  };

  const handlePageChange = (page: number) => {
    setCurrentPage(page);
    // Update URL with page parameter
    const params = new URLSearchParams(searchParams);
    if (page === 1) {
      params.delete("page");
    } else {
      params.set("page", page.toString());
    }
    navigate(`/items?${params.toString()}`, { replace: true });
    // Scroll to top
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const getSearchLocationString = () => {
    if (filters.lat && filters.lng) {
      // When using coordinates, return them as a string for the map
      return `${filters.lat},${filters.lng}`;
    }
    if (filters.city) return filters.city;
    if (filters.zipCode) return filters.zipCode;
    return '';
  };

  if (loading) {
    return (
      <div className="container mt-5">
        <div className="text-center">
          <div className="spinner-border" role="status">
            <span className="visually-hidden">Loading...</span>
          </div>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="container mt-5">
        <div className="alert alert-danger" role="alert">
          {error}
        </div>
      </div>
    );
  }

  return (
    <div className="container-fluid mt-4" style={{ maxWidth: '1800px' }}>
      <div className="d-flex flex-column flex-md-row justify-content-between align-items-start align-items-md-center mb-4 gap-3">
        <div>
          <h1 className="mb-1">Browse Items</h1>
          <span className="text-muted">
            {totalItems} items found
            {totalPages > 1 && ` (page ${currentPage} of ${totalPages})`}
          </span>
        </div>
        
        <div className="d-flex align-items-center gap-2">
          {/* Filter Button */}
          <div className="position-relative" ref={filterButtonRef} style={{ overflow: 'visible' }}>
            <button
              type="button"
              className={`btn btn-outline-secondary ${hasActiveLocationFilter ? 'active' : ''}`}
              onClick={() => setShowFilterPanel(!showFilterPanel)}
              data-filter-button
            >
              <i className="bi bi-filter me-1 me-md-2 align-middle"></i>
              <span className="d-none d-md-inline">Filters</span>
              {hasActiveLocationFilter && (
                <span className="position-absolute top-0 start-100 translate-middle p-1 bg-primary border border-light rounded-circle">
                  <span className="visually-hidden">Active filters</span>
                </span>
              )}
            </button>
            <FilterPanel
              show={showFilterPanel}
              onClose={() => setShowFilterPanel(false)}
              currentFilters={{
                lat: filters.lat,
                lng: filters.lng,
                radius: filters.radius,
                locationName: locationName,
              }}
              onApplyFilters={handleApplyFilters}
            />
          </div>

          {/* View Toggle */}
          {items.length > 0 && (
            <div className="btn-group" role="group" aria-label="View toggle">
              <button
                type="button"
                className={`btn btn-outline-secondary ${viewMode === 'list' ? 'active' : ''}`}
                onClick={() => setViewMode('list')}
              >
                <i className="bi bi-list-ul me-1 me-md-2"></i>
                <span className="d-none d-md-inline">List</span>
              </button>
              <button
                type="button"
                className={`btn btn-outline-secondary ${viewMode === 'map' ? 'active' : ''}`}
                onClick={() => setViewMode('map')}
              >
                <i className="bi bi-geo-alt-fill me-1 me-md-2"></i>
                <span className="d-none d-md-inline">Map</span>
              </button>
            </div>
          )}
        </div>
      </div>

      {items.length === 0 ? (
        <div className="text-center py-5">
          <i className="bi bi-search text-muted mb-3" style={{ fontSize: '4rem' }}></i>
          <h3 className="text-muted">No items found</h3>
          <p className="text-muted">
            Try adjusting your search criteria or browse all available items.
          </p>
        </div>
      ) : viewMode === 'list' ? (
        <>
          <div className="row">
            {items.map((item) => (
              <div key={item.id} className="col-md-6 col-lg-4 col-xl-3 mb-4">
                <ItemCard item={item} variant="standard" />
              </div>
            ))}
          </div>

          {/* Pagination */}
          {totalPages > 1 && (
            <nav aria-label="Item list pagination" className="mt-4">
              <ul className="pagination justify-content-center">
                <li className={`page-item ${currentPage === 1 ? 'disabled' : ''}`}>
                  <button
                    className="page-link"
                    onClick={() => handlePageChange(currentPage - 1)}
                    disabled={currentPage === 1}
                    aria-label="Previous page"
                  >
                    <i className="bi bi-chevron-left"></i>
                  </button>
                </li>

                {/* Page numbers */}
                {(() => {
                  const pages = [];
                  const maxVisiblePages = 5;
                  let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
                  let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);

                  // Adjust start if we're near the end
                  if (endPage - startPage + 1 < maxVisiblePages) {
                    startPage = Math.max(1, endPage - maxVisiblePages + 1);
                  }

                  // First page + ellipsis
                  if (startPage > 1) {
                    pages.push(
                      <li key={1} className="page-item">
                        <button className="page-link" onClick={() => handlePageChange(1)}>1</button>
                      </li>
                    );
                    if (startPage > 2) {
                      pages.push(
                        <li key="start-ellipsis" className="page-item disabled">
                          <span className="page-link">...</span>
                        </li>
                      );
                    }
                  }

                  // Page numbers
                  for (let i = startPage; i <= endPage; i++) {
                    pages.push(
                      <li key={i} className={`page-item ${currentPage === i ? 'active' : ''}`}>
                        <button
                          className="page-link"
                          onClick={() => handlePageChange(i)}
                          aria-current={currentPage === i ? 'page' : undefined}
                        >
                          {i}
                        </button>
                      </li>
                    );
                  }

                  // Last page + ellipsis
                  if (endPage < totalPages) {
                    if (endPage < totalPages - 1) {
                      pages.push(
                        <li key="end-ellipsis" className="page-item disabled">
                          <span className="page-link">...</span>
                        </li>
                      );
                    }
                    pages.push(
                      <li key={totalPages} className="page-item">
                        <button className="page-link" onClick={() => handlePageChange(totalPages)}>
                          {totalPages}
                        </button>
                      </li>
                    );
                  }

                  return pages;
                })()}

                <li className={`page-item ${currentPage === totalPages ? 'disabled' : ''}`}>
                  <button
                    className="page-link"
                    onClick={() => handlePageChange(currentPage + 1)}
                    disabled={currentPage === totalPages}
                    aria-label="Next page"
                  >
                    <i className="bi bi-chevron-right"></i>
                  </button>
                </li>
              </ul>
            </nav>
          )}
        </>
      ) : (
        <div className="mb-4">
          <SearchResultsMap
            items={items}
            searchLocation={getSearchLocationString()}
            onItemSelect={handleItemSelect}
            style={{
              height: window.innerWidth < 768 ? '60vh' : '70vh',
              minHeight: window.innerWidth < 768 ? '400px' : '500px'
            }}
          />
        </div>
      )}
    </div>
  );
};

export default ItemList;
