import { useMemo, useState } from 'react';
import { toEnglishDigits, tomanToRial } from '@/utils';
import { rialToToman } from '@/utils/money';
import { useDebouncedValue } from '@/services/search';
import { SEARCH_FILTER_DEBOUNCE_MS, SEARCH_PAGE_SIZE } from '@/services/search/constants';
import { parsePositiveInt, searchParamsToFilters } from '@/services/search/filterParams';
import type { NurseGender, NurseSearchFilters } from '@/services/search/types';
import type { CascadingRegionValue } from '@/components/geography/CascadingRegionSelect';

/** Minimal read surface shared by `URLSearchParams` and Next's `ReadonlyURLSearchParams`. */
interface ParamReader {
  get(name: string): string | null;
}

/** Toman input → IRR-Rial digit-string at the field boundary; undefined for blank/invalid input. */
function tomanInputToIrr(toman: string): string | undefined {
  const digits = toEnglishDigits(toman).trim();
  if (!/^\d+$/.test(digits)) return undefined;
  return tomanToRial(digits);
}

/** IRR digit-string (or undefined) → the whole-Toman string the price fields display. */
function irrToTomanInput(irr: string | undefined): string {
  return irr ? String(rialToToman(irr)) : '';
}

/**
 * The C1 filter controller — fast-changing UI state kept **colocated** (not in a high context provider,
 * phase §5). Holds the category, cascading region, same-gender facet, and Toman price inputs, and
 * derives the canonical `NurseSearchFilters` that becomes the live-count query key and the C2 URL. The
 * price inputs are **debounced** so typing doesn't fan out one search per keystroke before the value
 * joins the query key. `districtId = null` (whole city) is carried as an omitted filter, never a bogus id.
 *
 * `params` seeds the **initial** state only (a lazy `useState` read) — either a bare `?category_id=`
 * (the Home tile handoff) or a full filter set carried back from a C2 recap chip (`searchParamsToFilters`
 * reads every field C2's URL carries). `province_id` is a client-only convenience param (not part of
 * `NurseSearchFilters`/the search query key) so `CascadingRegionSelect` can prefill the city dropdown
 * without a server round trip; `goToResults` re-carries it so the round trip back to C1 keeps working.
 */
export function useSearchFilters(params: ParamReader) {
  const [categoryId, setCategoryId] = useState<number | null>(() => {
    const raw = searchParamsToFilters(params).serviceCategoryId;
    return raw > 0 ? raw : null;
  });
  const [region, setRegion] = useState<CascadingRegionValue>(() => {
    const initial = searchParamsToFilters(params);
    return {
      provinceId: parsePositiveInt(params.get('province_id')) ?? null,
      cityId: initial.cityId > 0 ? initial.cityId : null,
      districtId: initial.districtId ?? null,
    };
  });
  const [gender, setGender] = useState<NurseGender | undefined>(() => searchParamsToFilters(params).nurseGender);
  const [priceMinToman, setPriceMinToman] = useState(() => irrToTomanInput(searchParamsToFilters(params).priceMin));
  const [priceMaxToman, setPriceMaxToman] = useState(() => irrToTomanInput(searchParamsToFilters(params).priceMax));
  const [dateIntent, setDateIntent] = useState(() => params.get('date') ?? '');

  const debouncedMin = useDebouncedValue(priceMinToman, SEARCH_FILTER_DEBOUNCE_MS);
  const debouncedMax = useDebouncedValue(priceMaxToman, SEARCH_FILTER_DEBOUNCE_MS);

  const filters: NurseSearchFilters = useMemo(
    () => ({
      serviceCategoryId: categoryId ?? 0,
      cityId: region.cityId ?? 0,
      districtId: region.districtId ?? undefined,
      nurseGender: gender,
      priceMin: tomanInputToIrr(debouncedMin),
      priceMax: tomanInputToIrr(debouncedMax),
      sort: 'rating',
      page: 1,
      pageSize: SEARCH_PAGE_SIZE,
    }),
    [categoryId, region.cityId, region.districtId, gender, debouncedMin, debouncedMax],
  );

  const isReady = filters.serviceCategoryId > 0 && filters.cityId > 0;

  return {
    categoryId,
    setCategoryId,
    region,
    setRegion,
    gender,
    setGender,
    priceMinToman,
    setPriceMinToman,
    priceMaxToman,
    setPriceMaxToman,
    dateIntent,
    setDateIntent,
    filters,
    isReady,
  };
}
