'use client';
import { Suspense, type FunctionComponent, type ReactNode } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useLocale, useTranslations } from 'next-intl';
import {
  Box,
  InputAdornment,
  Paper,
  Skeleton,
  Stack,
  TextField,
  ToggleButton,
  ToggleButtonGroup,
  Typography,
} from '@mui/material';
import { AppButton, AppIcon, AppLoading, CategoryTile } from '@/components';
import CascadingRegionSelect from '@/components/geography/CascadingRegionSelect';
import { ROUTES } from '@/constants';
import { useServiceCategories } from '@/services/catalog';
import { pickCatalogName } from '@/services/catalog/names';
import { useNurseSearch } from '@/services/search';
import { filtersToSearchParams } from '@/services/search/filterParams';
import type { NurseGender } from '@/services/search/types';
import { useSearchFilters } from './useSearchFilters';

/**
 * C1 — Search & filter (جستجو و فیلتر): the discovery entry screen. Pick a care category (reusing the
 * f4 catalog grid), a city (reusing the f3 cascading region picker; district optional = whole city),
 * the **prominent same-gender facet**, and an optional Toman price range; a live result count drives the
 * "مشاهده N پرستار" CTA into C2. Availability (date) is intent-only at MVP — it is carried to booking,
 * never used to hard-filter results. `useSearchParams` needs a Suspense boundary under static rendering.
 */
export default function SearchPage() {
  return (
    <Suspense fallback={<AppLoading />}>
      <SearchFilterScreen />
    </Suspense>
  );
}

const GENDER_OPTIONS: readonly (NurseGender | 'any')[] = ['female', 'male', 'any'];

function SearchFilterScreen() {
  const t = useTranslations('search');
  const router = useRouter();
  const locale = useLocale();
  const params = useSearchParams();

  const initialCategoryRaw = Number(params.get('category_id'));
  const initialCategoryId = Number.isInteger(initialCategoryRaw) && initialCategoryRaw > 0 ? initialCategoryRaw : undefined;

  const controller = useSearchFilters(initialCategoryId);
  const { data, isFetching } = useNurseSearch(controller.filters);
  const count = data?.total;

  const goToResults = () => {
    const query = filtersToSearchParams(controller.filters);
    if (controller.dateIntent) query.set('date', controller.dateIntent);
    router.push(`/${locale}${ROUTES.SEARCH_RESULTS}?${query.toString()}`);
  };

  const ctaLabel = !controller.isReady
    ? t('cta_choose_category_city')
    : isFetching || count == null
      ? t('cta_loading')
      : t('cta_view_results', { count });

  return (
    <Stack sx={{ gap: 3 }}>
      <Box>
        <Typography variant="h5" component="h1">
          {t('title')}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('subtitle')}
        </Typography>
      </Box>

      <CategorySelect selectedId={controller.categoryId} onSelect={controller.setCategoryId} />

      <FilterSection title={t('section_location')}>
        <CascadingRegionSelect value={controller.region} onChange={controller.setRegion} includeDistrict />
      </FilterSection>

      <FilterSection title={t('section_gender')} hint={t('gender_hint')}>
        <ToggleButtonGroup
          exclusive
          fullWidth
          color="primary"
          value={controller.gender ?? 'any'}
          onChange={(_event, value: NurseGender | 'any' | null) => {
            if (value != null) controller.setGender(value === 'any' ? undefined : value);
          }}
        >
          {GENDER_OPTIONS.map((option) => (
            <ToggleButton key={option} value={option} sx={{ fontWeight: 700 }}>
              {t(`gender_${option}`)}
            </ToggleButton>
          ))}
        </ToggleButtonGroup>
      </FilterSection>

      <FilterSection title={t('section_date')} hint={t('date_hint')}>
        <TextField
          type="date"
          fullWidth
          value={controller.dateIntent}
          onChange={(event) => controller.setDateIntent(event.target.value)}
          slotProps={{ inputLabel: { shrink: true } }}
        />
      </FilterSection>

      <FilterSection title={t('section_price')} hint={t('price_hint')}>
        <Stack direction="row" sx={{ gap: 2 }}>
          <PriceField
            label={t('price_min')}
            value={controller.priceMinToman}
            onChange={controller.setPriceMinToman}
            adornment={t('toman')}
          />
          <PriceField
            label={t('price_max')}
            value={controller.priceMaxToman}
            onChange={controller.setPriceMaxToman}
            adornment={t('toman')}
          />
        </Stack>
      </FilterSection>

      <AppButton
        color="primary"
        variant="contained"
        size="large"
        disabled={!controller.isReady}
        onClick={goToResults}
        startIcon="search"
        sx={{ py: 1.5 }}
      >
        {ctaLabel}
      </AppButton>
    </Stack>
  );
}

const FilterSection: FunctionComponent<{ title: string; hint?: string; children: ReactNode }> = ({
  title,
  hint,
  children,
}) => (
  <Stack sx={{ gap: 1 }}>
    <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
      {title}
    </Typography>
    {hint ? (
      <Typography variant="body2" sx={{ color: 'text.secondary' }}>
        {hint}
      </Typography>
    ) : null}
    {children}
  </Stack>
);

const PriceField: FunctionComponent<{
  label: string;
  value: string;
  onChange: (value: string) => void;
  adornment: string;
}> = ({ label, value, onChange, adornment }) => (
  <TextField
    label={label}
    value={value}
    onChange={(event) => onChange(event.target.value)}
    inputMode="numeric"
    fullWidth
    slotProps={{
      input: { endAdornment: <InputAdornment position="end">{adornment}</InputAdornment> },
    }}
  />
);

/** The reused f4 category grid (data-driven from the cached catalog reference data), with selection. */
const CategorySelect: FunctionComponent<{ selectedId: number | null; onSelect: (id: number) => void }> = ({
  selectedId,
  onSelect,
}) => {
  const t = useTranslations('search');
  const locale = useLocale();
  const { data, isLoading, isError } = useServiceCategories();
  const categories = data?.items ?? [];

  return (
    <FilterSection title={t('section_category')}>
      {isLoading ? (
        <Box sx={{ display: 'grid', gridTemplateColumns: { xs: 'repeat(2, 1fr)', sm: 'repeat(3, 1fr)' }, gap: 1.5 }}>
          {[0, 1, 2, 3].map((key) => (
            <Skeleton key={key} variant="rounded" height={116} sx={{ borderRadius: 2 }} />
          ))}
        </Box>
      ) : isError ? (
        <Paper elevation={0} sx={{ p: 3, textAlign: 'center', border: '1px dashed', borderColor: 'divider', borderRadius: 2 }}>
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {t('categories_error')}
          </Typography>
        </Paper>
      ) : (
        <Box sx={{ display: 'grid', gridTemplateColumns: { xs: 'repeat(2, 1fr)', sm: 'repeat(3, 1fr)' }, gap: 1.5 }}>
          {categories.map((category) => (
            <CategoryTile
              key={category.id}
              label={pickCatalogName(category, locale)}
              iconKey={category.iconKey}
              selected={category.id === selectedId}
              onClick={() => onSelect(category.id)}
            />
          ))}
        </Box>
      )}
    </FilterSection>
  );
};
