'use client';

import { Suspense, useEffect, useMemo, useState } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import Link from 'next/link';
import { WorkerCard } from '@/components/workers/WorkerCard';
import { WorkersMapPanel } from '@/components/workers/WorkersMapPanel';
import {
  countActiveWorkersBrowseFilters,
  defaultWorkersBrowseFilters,
  WorkersBrowseFilterButton,
  WorkersBrowseFilterModal,
  type WorkersBrowseFilters,
} from '@/components/workers/WorkersBrowseFilterModal';
import { Button } from '@/components/ui/button';
import { BrowsePageHero } from '@/components/layout/BrowsePageHero';
import {
  Search,
  Users,
  MapPin,
  Briefcase,
  LayoutGrid,
  Map,
  Columns2,
} from 'lucide-react';
import { api } from '@/lib/api';
import { BROWSE_PAGE_SIZE, formatBrowseCount, type PaginationMeta } from '@/lib/pagination';
import { useInfiniteScroll } from '@/hooks/useInfiniteScroll';
import { appendAreaQuery, isRegionFilterActive, regionLabel, regionPath, resolveBrowseRegionSlug } from '@/lib/region';
import { buildPostJobAuthUrl } from '@/lib/createJob';
import { useRegion } from '@/contexts/RegionContext';
import { JOBS_FEATURE_ENABLED } from '@/lib/features';
import { cn } from '@/lib/utils';

type CategoryOption = { id: string; name: string; slug: string; icon?: string };
type WorkersViewMode = 'list' | 'map' | 'split';

function parseViewMode(value: string | null): WorkersViewMode {
  if (value === 'map' || value === 'split') return value;
  return 'list';
}

export function WorkersBrowseContent({
  regionSlug: regionSlugFromPath,
  postJobHref = buildPostJobAuthUrl(),
  customerActions = false,
}: {
  regionSlug?: string;
  postJobHref?: string;
  customerActions?: boolean;
}) {
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const router = useRouter();
  const { slug: contextSlug, regionReady } = useRegion();
  const regionSlug = resolveBrowseRegionSlug(regionSlugFromPath, contextSlug);
  const [categories, setCategories] = useState<CategoryOption[]>([]);
  const [workers, setWorkers] = useState<Record<string, unknown>[]>([]);
  const [search, setSearch] = useState(searchParams.get('search') || '');
  const [filters, setFilters] = useState<WorkersBrowseFilters>(() => ({
    categorySlug: searchParams.get('category') || '',
    gender: searchParams.get('gender') || '',
    sort: searchParams.get('sort') || 'recommended',
    verified: searchParams.get('verified') === 'true',
    areaSlug: searchParams.get('area') || '',
  }));
  const [filterOpen, setFilterOpen] = useState(false);
  const [viewMode, setViewMode] = useState<WorkersViewMode>(() =>
    parseViewMode(searchParams.get('view'))
  );
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [page, setPage] = useState(1);
  const [meta, setMeta] = useState<PaginationMeta | null>(null);

  const { categorySlug, gender, sort, verified, areaSlug } = filters;
  const label = areaSlug ? regionLabel(areaSlug) : regionLabel(regionSlug);
  const mapRegionSlug = areaSlug || regionSlug;
  const selectedCategory = categories.find((c) => c.slug === categorySlug);
  const activeFilterCount = useMemo(() => countActiveWorkersBrowseFilters(filters), [filters]);
  const showList = viewMode === 'list' || viewMode === 'split';
  const showMap = viewMode === 'map' || viewMode === 'split';

  const syncBrowseParams = (next: WorkersBrowseFilters) => {
    const params = new URLSearchParams(searchParams.toString());
    if (next.categorySlug) params.set('category', next.categorySlug);
    else params.delete('category');
    if (next.gender) params.set('gender', next.gender);
    else params.delete('gender');
    if (next.sort && next.sort !== 'recommended') params.set('sort', next.sort);
    else params.delete('sort');
    if (next.verified) params.set('verified', 'true');
    else params.delete('verified');
    if (next.areaSlug) params.set('area', next.areaSlug);
    else params.delete('area');
    const query = params.toString();
    router.replace(query ? `${pathname}?${query}` : pathname, { scroll: false });
  };

  const handleFiltersChange = (next: WorkersBrowseFilters) => {
    setFilters(next);
    syncBrowseParams(next);
  };

  const updateViewInUrl = (nextView: WorkersViewMode) => {
    const params = new URLSearchParams(searchParams.toString());
    if (nextView === 'list') params.delete('view');
    else params.set('view', nextView);
    const query = params.toString();
    router.replace(query ? `${pathname}?${query}` : pathname, { scroll: false });
  };

  const handleViewChange = (nextView: WorkersViewMode) => {
    setViewMode(nextView);
    updateViewInUrl(nextView);
  };

  const clearAllFilters = () => {
    setSearch('');
    const resetFilters: WorkersBrowseFilters = {
      ...defaultWorkersBrowseFilters,
      areaSlug: isRegionFilterActive(regionSlug) ? regionSlug : '',
    };
    handleFiltersChange(resetFilters);
    fetchWorkers({ search: '', categorySlug: '' });
  };

  const fetchWorkers = (
    pageNum = 1,
    append = false,
    overrides?: { search?: string; categorySlug?: string }
  ) => {
    if (pageNum === 1) setLoading(true);
    else setLoadingMore(true);

    const params = new URLSearchParams({
      limit: String(BROWSE_PAGE_SIZE),
      page: String(pageNum),
    });
    const q = overrides?.search !== undefined ? overrides.search : search;
    const cat = overrides?.categorySlug !== undefined ? overrides.categorySlug : categorySlug;
    if (q) params.set('search', q);
    if (cat) params.set('categorySlug', cat);
    if (sort) params.set('sort', sort);
    if (verified) params.set('verified', 'true');
    if (gender) params.set('gender', gender);
    appendAreaQuery(params, mapRegionSlug);

    api<{ data: Record<string, unknown>[]; meta?: PaginationMeta }>(`/workers?${params}`)
      .then((res) => {
        setWorkers((prev) => (append ? [...prev, ...res.data] : res.data));
        setMeta(res.meta ?? null);
        setPage(pageNum);
      })
      .catch(console.error)
      .finally(() => {
        setLoading(false);
        setLoadingMore(false);
      });
  };

  const hasMore = meta != null && page < meta.totalPages;

  const loadMore = () => {
    if (loading || loadingMore || !hasMore) return;
    fetchWorkers(page + 1, true);
  };

  const loadMoreRef = useInfiniteScroll(loadMore, { enabled: hasMore && !loading });

  useEffect(() => {
    api<{ data: CategoryOption[] }>('/categories?limit=50')
      .then((res) => setCategories(res.data))
      .catch(console.error);
  }, []);

  useEffect(() => {
    if (!regionReady || searchParams.get('area')) return;
    setFilters((prev) => {
      if (prev.areaSlug) return prev;
      if (!isRegionFilterActive(regionSlug)) return prev;
      return { ...prev, areaSlug: regionSlug };
    });
  }, [regionReady, regionSlug, searchParams]);

  useEffect(() => {
    if (!regionReady) return;
    fetchWorkers(1, false);
  }, [sort, verified, gender, areaSlug, regionSlug, categorySlug, regionReady]);

  const emptyMapTitle = search
    ? `No workers match "${search}"`
    : selectedCategory
      ? `No ${selectedCategory.name.toLowerCase()} workers in ${label}`
      : `No workers in ${label}`;

  const emptyMapSubtitle = search
    ? 'Try a different keyword or clear your search.'
    : selectedCategory
      ? 'Try another trade or browse all workers.'
      : 'Adjust your filters or check back later.';

  return (
    <>
      <div className="mb-4 space-y-3">
        <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
          <div className="relative min-w-0 flex-1">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
            <input
              type="text"
              placeholder="Search by name, skill, or trade (e.g. mekaniko, labandera)..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && fetchWorkers()}
              className="search-input-icon h-11"
            />
          </div>
          <div className="flex shrink-0 items-center gap-2">
            <Button
              onClick={() => fetchWorkers()}
              size="sm"
              className="h-9 px-4 worker-cta-amber rounded-none"
            >
              Search
            </Button>
            <WorkersBrowseFilterButton
              activeCount={activeFilterCount}
              onClick={() => setFilterOpen(true)}
            />
            {([
              { value: 'list' as const, label: 'List', icon: LayoutGrid },
              { value: 'map' as const, label: 'Map', icon: Map },
              { value: 'split' as const, label: 'Split', icon: Columns2, desktopOnly: true },
            ]).map((item) => (
              <button
                key={item.value}
                type="button"
                onClick={() => handleViewChange(item.value)}
                className={cn(
                  'filter-chip gap-1.5',
                  viewMode === item.value && 'filter-chip-active',
                  item.desktopOnly && 'hidden lg:inline-flex'
                )}
              >
                <item.icon className="h-3.5 w-3.5" />
                <span className="hidden sm:inline">{item.label}</span>
              </button>
            ))}
          </div>
        </div>

        {!loading && (
          <p className="text-sm text-muted">
            <Users className="mr-1 inline h-4 w-4 -mt-0.5 text-[var(--home-amber)]" />
            <span className="font-semibold text-slate-900">
              {formatBrowseCount(workers.length, meta?.total)}
            </span>{' '}
            worker
            {meta?.total === 1 || (meta == null && workers.length === 1) ? '' : 's'}
            {selectedCategory ? ` · ${selectedCategory.name}` : ''}
            {verified ? ' · verified only' : ''} in {label}
            {activeFilterCount > 0 ? ' · filtered' : ''}
            {showMap && (
              <span className="hidden sm:inline text-muted"> · tap a pin for profile details</span>
            )}
          </p>
        )}
      </div>

      <WorkersBrowseFilterModal
        open={filterOpen}
        onClose={() => setFilterOpen(false)}
        filters={filters}
        onChange={handleFiltersChange}
        categories={categories}
        resultCount={meta?.total ?? workers.length}
      />

      {loading && viewMode === 'list' ? (
        <div className="text-center py-16 text-muted">Loading workers...</div>
      ) : (
        <div
          className={cn(
            showList && showMap && 'lg:grid lg:grid-cols-[minmax(0,1fr)_min(420px,38%)] lg:gap-6 lg:items-start'
          )}
        >
          {showList && (
            <div className={cn(viewMode === 'split' && 'min-w-0')}>
              {loading ? (
                <div className="text-center py-16 text-muted">Loading workers...</div>
              ) : workers.length > 0 ? (
                <>
                  <div
                    className={cn(
                      'grid gap-2 sm:gap-4',
                      viewMode === 'split'
                        ? 'grid-cols-1 xl:grid-cols-2'
                        : 'grid-cols-2 lg:grid-cols-3'
                    )}
                  >
                    {workers.map((w) => (
                      <WorkerCard
                        key={w.id as string}
                        worker={w as Parameters<typeof WorkerCard>[0]['worker']}
                        responsive={viewMode !== 'split'}
                        compact={viewMode === 'split'}
                        customerActions={customerActions}
                      />
                    ))}
                  </div>
                  {hasMore && (
                    <div ref={loadMoreRef} className="py-6 text-center text-sm text-muted">
                      {loadingMore ? 'Loading more workers…' : 'Scroll for more'}
                    </div>
                  )}
                </>
              ) : (
                <div className="border border-dashed border-[#d6d0c4] bg-[#fffdf9] py-16 px-6 text-center">
                  <div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center bg-[var(--home-ink)] text-white">
                    <Users className="h-7 w-7" />
                  </div>
                  <h3 className="home-display font-bold text-slate-900 text-lg">No workers found</h3>
                  <p className="text-sm text-muted mt-2 max-w-sm mx-auto">
                    {search
                      ? `No results for "${search}". Try a different keyword or browse all workers.`
                      : selectedCategory
                        ? `No ${selectedCategory.name.toLowerCase()} workers in ${label} right now.`
                        : JOBS_FEATURE_ENABLED
                        ? `No workers listed in ${label} right now. Check back soon or post a job to attract talent.`
                        : `No workers listed in ${label} right now. Check back soon.`}
                  </p>
                  <div className="flex flex-col sm:flex-row gap-2 justify-center mt-6">
                    {(search || activeFilterCount > 0) && (
                      <Button variant="outline" className="rounded-none border-[#d6d0c4]" onClick={clearAllFilters}>
                        Clear filters
                      </Button>
                    )}
                    {JOBS_FEATURE_ENABLED && (
                      <Link href={postJobHref}>
                        <Button className="worker-cta-amber gap-2 w-full sm:w-auto rounded-none">
                          <Briefcase className="h-4 w-4" />
                          Post a Job
                        </Button>
                      </Link>
                    )}
                  </div>
                </div>
              )}
            </div>
          )}

          {showMap && (
            <WorkersMapPanel
              workers={workers}
              categorySlug={categorySlug}
              regionSlug={mapRegionSlug}
              loading={loading}
              emptyTitle={emptyMapTitle}
              emptySubtitle={emptyMapSubtitle}
              className={cn(
                viewMode === 'split'
                  ? 'mt-4 h-[min(70vh,560px)] lg:mt-0 lg:sticky lg:top-20 lg:h-[calc(100vh-6rem)]'
                  : 'h-[min(72vh,640px)] min-h-[420px]'
              )}
            />
          )}
        </div>
      )}
    </>
  );
}

export function WorkersPageView({ regionSlug: regionSlugFromPath }: { regionSlug?: string }) {
  const { slug: contextSlug } = useRegion();
  const regionSlug = resolveBrowseRegionSlug(regionSlugFromPath, contextSlug);
  const label = regionLabel(regionSlug);
  const mapHref = regionSlug ? regionPath(regionSlug, '/map?filter=workers') : '/map?filter=workers';
  const jobsHref = regionSlug ? regionPath(regionSlug, '/jobs') : '/jobs';

  return (
    <div className="workers-directory">
      <BrowsePageHero
        variant="directory"
        eyebrow={`Worker directory · ${label}`}
        title="Find Workers"
        description={`Browse verified blue-collar professionals in ${label}. Use list, map, or split view to explore by trade and location.`}
        actions={
          JOBS_FEATURE_ENABLED
            ? [
                { href: mapHref, label: 'Jobs + map', icon: MapPin, variant: 'heroOutline' },
                { href: jobsHref, label: 'Find jobs', icon: Briefcase, variant: 'accent' },
              ]
            : [
                { href: mapHref, label: 'Workers map', icon: MapPin, variant: 'accent' },
                { href: '/categories', label: 'Browse trades', icon: LayoutGrid, variant: 'heroOutline' },
              ]
        }
      />

      <div className="page-container max-w-6xl">
        <Suspense fallback={<div className="text-center py-16 text-muted">Loading...</div>}>
          <WorkersBrowseContent regionSlug={regionSlug} />
        </Suspense>
      </div>
    </div>
  );
}
