/**
 * Shop filter state: mirrors backend filter args (brand, tags, attributes).
 * Used for URL persistence and passing to Convex product list queries.
 */

export type ShopFilterState = {
  brand?: string;
  tags: string[];
  attributes: {
    petSize: string[];
    ageRange: string[];
    specialDiet: string[];
    material?: string;
    flavor?: string;
  };
};

export const DEFAULT_SHOP_FILTER_STATE: ShopFilterState = {
  tags: [],
  attributes: {
    petSize: [],
    ageRange: [],
    specialDiet: [],
  },
};

const PARAM_BRAND = "brand";
const PARAM_TAG = "tag";
const PARAM_PET_SIZE = "petSize";
const PARAM_AGE_RANGE = "ageRange";
const PARAM_SPECIAL_DIET = "specialDiet";
const PARAM_MATERIAL = "material";
const PARAM_FLAVOR = "flavor";

const FILTER_PARAM_KEYS = [
  PARAM_BRAND,
  PARAM_TAG,
  PARAM_PET_SIZE,
  PARAM_AGE_RANGE,
  PARAM_SPECIAL_DIET,
  PARAM_MATERIAL,
  PARAM_FLAVOR,
];

export type SearchParamsLike = {
  get(name: string): string | null;
  getAll(name: string): string[];
};

export function filterStateFromSearchParams(
  searchParams: SearchParamsLike,
): ShopFilterState {
  const brand = searchParams.get(PARAM_BRAND) ?? undefined;
  const tags = searchParams.getAll(PARAM_TAG).filter(Boolean);
  const petSize = searchParams.getAll(PARAM_PET_SIZE).filter(Boolean);
  const ageRange = searchParams.getAll(PARAM_AGE_RANGE).filter(Boolean);
  const specialDiet = searchParams.getAll(PARAM_SPECIAL_DIET).filter(Boolean);
  const material = searchParams.get(PARAM_MATERIAL) ?? undefined;
  const flavor = searchParams.get(PARAM_FLAVOR) ?? undefined;

  return {
    brand: brand || undefined,
    tags,
    attributes: {
      petSize,
      ageRange,
      specialDiet,
      material: material || undefined,
      flavor: flavor || undefined,
    },
  };
}

export function filterStateToSearchParams(state: ShopFilterState): URLSearchParams {
  const params = new URLSearchParams();
  if (state.brand) params.set(PARAM_BRAND, state.brand);
  state.tags.forEach((t) => params.append(PARAM_TAG, t));
  state.attributes.petSize.forEach((v) => params.append(PARAM_PET_SIZE, v));
  state.attributes.ageRange.forEach((v) => params.append(PARAM_AGE_RANGE, v));
  state.attributes.specialDiet.forEach((v) => params.append(PARAM_SPECIAL_DIET, v));
  if (state.attributes.material) params.set(PARAM_MATERIAL, state.attributes.material);
  if (state.attributes.flavor) params.set(PARAM_FLAVOR, state.attributes.flavor);
  return params;
}

/** Merge filter state into existing search params (e.g. preserve `pet` on top-category pages). Pass current as URLSearchParams (e.g. new URLSearchParams(searchParams.toString())). */
export function mergeFilterStateIntoSearchParams(
  current: URLSearchParams,
  state: ShopFilterState,
): URLSearchParams {
  const next = new URLSearchParams();
  current.forEach((value, key) => {
    if (!FILTER_PARAM_KEYS.includes(key)) next.append(key, value);
  });
  filterStateToSearchParams(state).forEach((value, key) => next.append(key, value));
  return next;
}

/** Convert frontend filter state to args for Convex listActive / listByRootCategory / listByTopCategory */
export function shopFilterStateToApiArgs(state: ShopFilterState): {
  brand?: string;
  tags?: string[];
  attributes?: {
    petSize?: string[];
    ageRange?: string[];
    specialDiet?: string[];
    material?: string;
    flavor?: string;
  };
} {
  const attrs = state.attributes;
  const hasAttrs =
    (attrs.petSize?.length ?? 0) > 0 ||
    (attrs.ageRange?.length ?? 0) > 0 ||
    (attrs.specialDiet?.length ?? 0) > 0 ||
    attrs.material != null ||
    attrs.flavor != null;
  return {
    ...(state.brand ? { brand: state.brand } : {}),
    ...(state.tags.length > 0 ? { tags: state.tags } : {}),
    ...(hasAttrs
      ? {
          attributes: {
            ...(attrs.petSize?.length ? { petSize: attrs.petSize } : {}),
            ...(attrs.ageRange?.length ? { ageRange: attrs.ageRange } : {}),
            ...(attrs.specialDiet?.length ? { specialDiet: attrs.specialDiet } : {}),
            ...(attrs.material ? { material: attrs.material } : {}),
            ...(attrs.flavor ? { flavor: attrs.flavor } : {}),
          },
        }
      : {}),
  };
}
