'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { AppShell } from '@/components/ui/layout/AppShell';
import { BottomNav, useCustomerNavItems } from '@/components/ui/layout/BottomNav';
import { Container } from '@/components/ui/layout/Container';
import { Grid } from '@/components/ui/layout/Grid';
import { PageHeader } from '@/components/ui/layout/PageHeader';
import { SiteNav } from '@/components/ui/layout/SiteNav';
import { BrowseFilterSidebar } from '@/components/ui/domain/BrowseFilterSidebar';
import type { ActiveChip } from '@/components/ui/domain/FilterShell';
import { OpeningHoursFilter } from '@/components/ui/domain/OpeningHoursFilter';
import { StoresMap } from '@/components/ui/domain/StoresMap';
import { VendorCard } from '@/components/ui/domain/VendorCard';
import { ViewToggle, type ViewMode } from '@/components/ui/domain/ViewToggle';
import { GlobalCartDrawer } from '@/components/ui/domain/cart/GlobalCartDrawer';
import { EmptyState } from '@/components/ui/feedback/EmptyState';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { SearchResultsSkeleton, SkeletonGuard } from '@/components/ui/feedback/Skeleton';
import { Button } from '@/components/ui/primitives/Button';
import { Label } from '@/components/ui/primitives/Label';
import { Pagination } from '@/components/ui/primitives/Pagination';
import { SearchInput } from '@/components/ui/primitives/SearchInput';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { useT, useLocale } from '@/lib/i18n/react';
import { interpolate } from '@/lib/i18n/interpolate';
import { useUrlFilterState } from '@/lib/url/useUrlFilterState';
import { makeStoresCodec, type StoresUrlState } from '@/lib/url/codecs/storesCodec';
import { HISTORY } from '@/lib/url/historyPolicy';
import type { Locale } from '@/lib/i18n';
import { useStores } from './useStores';

export interface StoresProps {
  locale: Locale;
  initialUrlState?: StoresUrlState;
  isGuest?: boolean;
  isAdmin?: boolean;
  isVendor?: boolean;
  userName?: string;
}

const PAGE_SIZE = 12;

export function Stores({
  locale: _locale,
  initialUrlState,
  isGuest = true,
  isAdmin = false,
  isVendor = false,
  userName,
}: StoresProps) {
  const t = useT('stores');
  const tCommon = useT('common');
  const tError = useT('error');
  const tNearYou = useT('near_you');
  const { locale } = useLocale();
  const navItems = useCustomerNavItems('/stores');
  const codec = useMemo(() => makeStoresCodec('/stores'), []);
  const { state, setUrlState } = useUrlFilterState<StoresUrlState>({
    initial: initialUrlState ?? {
      query: '',
      city: null,
      businessTypeId: null,
      hours: { mode: 'any' },
      sortBy: 'rating',
      view: 'grid',
      page: 1,
    },
    codec,
  });
  const [searchInput, setSearchInput] = useState(state.query);

  useEffect(() => {
    const timeout = window.setTimeout(() => {
      const query = searchInput.trim();
      if (query !== state.query) setUrlState({ query, page: 1 }, HISTORY.tweak);
    }, 300);
    return () => window.clearTimeout(timeout);
  }, [searchInput, setUrlState, state.query]);

  const { data, isLoading, isFetching, isError, refetch } = useStores(
    {
      query: state.query || undefined,
      city: state.city || undefined,
      businessTypeId: state.businessTypeId || undefined,
      hours: state.hours,
      sortBy: state.sortBy,
    },
    state.page,
    PAGE_SIZE,
  );

  const cities = data?.filters.cities ?? [];
  const businessTypes = data?.filters.businessTypes ?? [];
  const stores = useMemo(() => data?.stores ?? [], [data]);
  const totalCount = data?.totalCount ?? 0;
  const selectedBusinessType = businessTypes.find((type) => type.id === state.businessTypeId);
  const clearFilters = useCallback(() => {
    setSearchInput('');
    setUrlState(
      {
        query: '',
        city: null,
        businessTypeId: null,
        hours: { mode: 'any' },
        page: 1,
      },
      HISTORY.nav,
    );
  }, [setUrlState]);

  const activeChips = useMemo(
    () =>
      [
        state.query
          ? {
              label: state.query,
              onRemove: () => {
                setSearchInput('');
                setUrlState({ query: '', page: 1 }, HISTORY.tweak);
              },
            }
          : null,
        state.city
          ? {
              label: state.city,
              onRemove: () => setUrlState({ city: null, page: 1 }, HISTORY.tweak),
            }
          : null,
        selectedBusinessType
          ? {
              label: locale === 'en' ? selectedBusinessType.nameEn : selectedBusinessType.nameHe,
              onRemove: () => setUrlState({ businessTypeId: null, page: 1 }, HISTORY.tweak),
            }
          : null,
        state.hours.mode !== 'any'
          ? {
              label:
                state.hours.mode === 'openNow' ? tNearYou('openNow') : tNearYou('customWindow'),
              onRemove: () => setUrlState({ hours: { mode: 'any' }, page: 1 }, HISTORY.tweak),
            }
          : null,
      ].filter(Boolean) as ActiveChip[],
    [locale, selectedBusinessType, setUrlState, state, tNearYou],
  );

  const filters = (
    <div className="flex flex-col gap-5">
      <div className="flex flex-col gap-2">
        <Label htmlFor="stores-city">{t('filter_city')}</Label>
        <Select
          value={state.city ?? '__all__'}
          onValueChange={(value) =>
            setUrlState({ city: value === '__all__' ? null : value, page: 1 }, HISTORY.tweak)
          }
        >
          <SelectTrigger id="stores-city" aria-label={t('filter_city')}>
            <SelectValue placeholder={t('all_cities')} />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="__all__">{t('all_cities')}</SelectItem>
            {cities.map((city) => (
              <SelectItem key={city} value={city}>
                {city}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      <div className="flex flex-col gap-2">
        <Label htmlFor="stores-business-type">{t('filter_business_type')}</Label>
        <Select
          value={state.businessTypeId ?? '__all__'}
          onValueChange={(value) =>
            setUrlState(
              { businessTypeId: value === '__all__' ? null : value, page: 1 },
              HISTORY.tweak,
            )
          }
        >
          <SelectTrigger id="stores-business-type" aria-label={t('filter_business_type')}>
            <SelectValue placeholder={t('all_business_types')} />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="__all__">{t('all_business_types')}</SelectItem>
            {businessTypes.map((type) => (
              <SelectItem key={type.id} value={type.id}>
                {locale === 'en' ? type.nameEn : type.nameHe}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      <div className="flex flex-col gap-2">
        <p className="text-text-secondary text-sm font-medium">{t('hours_label')}</p>
        <OpeningHoursFilter
          value={state.hours}
          onChange={(hours) => setUrlState({ hours, page: 1 }, HISTORY.tweak)}
        />
      </div>
    </div>
  );

  const cards = (
    <Grid cols={1} lgCols={3} gap="4" className="sm:grid-cols-2">
      {stores.map((vendor) => (
        <VendorCard key={vendor.id} vendor={vendor} locale={locale} />
      ))}
    </Grid>
  );

  return (
    <AppShell
      mode="customer"
      desktopTopBar={
        <SiteNav
          variant="desktop"
          currentPath="/stores"
          isGuest={isGuest}
          isAdmin={isAdmin}
          isVendor={isVendor}
          userName={userName}
        />
      }
      topBar={
        <SiteNav
          variant="mobile"
          title={t('title')}
          currentPath="/stores"
          isGuest={isGuest}
          isAdmin={isAdmin}
          isVendor={isVendor}
        />
      }
      bottomNav={<BottomNav mode="customer" items={navItems} />}
      pageOverlays={<GlobalCartDrawer />}
    >
      <main id="main">
        <Container maxWidth="4xl" px="6" className="py-6">
          <PageHeader
            title={t('title')}
            subtitle={t('subtitle')}
            className="px-0 pt-0"
            actions={
              <ViewToggle
                value={(state.view === 'map' ? 'map' : 'gallery') as ViewMode}
                onChange={(view) =>
                  setUrlState({ view: view === 'map' ? 'map' : 'grid', page: 1 }, HISTORY.tweak)
                }
              />
            }
          />

          <div className="mb-6 flex items-center gap-3">
            <SearchInput
              value={searchInput}
              onChange={(event) => setSearchInput(event.target.value)}
              placeholder={t('search_placeholder')}
              aria-label={t('search_placeholder')}
              className="flex-1"
            />
            <Select
              value={state.sortBy}
              onValueChange={(sortBy) =>
                setUrlState({ sortBy: sortBy as StoresUrlState['sortBy'], page: 1 }, HISTORY.tweak)
              }
            >
              <SelectTrigger aria-label={t('sort_label')} className="w-36">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="rating">{t('sort_rating')}</SelectItem>
                <SelectItem value="deals">{t('sort_deals')}</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="flex flex-col gap-4 lg:flex-row lg:gap-6">
            <BrowseFilterSidebar activeChips={activeChips} onClearAll={clearFilters}>
              {filters}
            </BrowseFilterSidebar>

            <section className="min-w-0 flex-1" aria-live="polite" aria-busy={isLoading && !data}>
              {isLoading && !data ? (
                <div role="status">
                  <span className="sr-only">{tCommon('loading')}</span>
                  <SkeletonGuard>
                    <SearchResultsSkeleton count={6} />
                  </SkeletonGuard>
                </div>
              ) : isError && !data ? (
                <ErrorState
                  title={tError('title')}
                  description={tError('description')}
                  action={
                    <Button variant="primary" size="sm" onClick={() => void refetch()}>
                      {tCommon('retry')}
                    </Button>
                  }
                />
              ) : stores.length === 0 ? (
                <EmptyState
                  title={t('empty_title')}
                  description={t('empty_description')}
                  action={
                    <Button variant="secondary" size="sm" onClick={clearFilters}>
                      {t('clear_filters')}
                    </Button>
                  }
                />
              ) : (
                <div data-skeleton-ready className="flex flex-col gap-4">
                  <p className="text-text-secondary text-sm">
                    {interpolate(t('results_summary'), {
                      shown: stores.length,
                      total: totalCount,
                    })}
                  </p>
                  {state.view === 'map' ? (
                    <div className="h-96">
                      <StoresMap vendors={stores} className="h-full" />
                    </div>
                  ) : (
                    cards
                  )}
                  <Pagination
                    page={state.page}
                    totalPages={data?.totalPages ?? 1}
                    onPageChange={(page) => setUrlState({ page }, HISTORY.nav)}
                    isLoading={isFetching}
                  />
                </div>
              )}
            </section>
          </div>
        </Container>
      </main>
    </AppShell>
  );
}
