import type { Route } from "next";
import type { ReactNode } from "react";

import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { createContext, useContext, useRef } from "react";

import CloseSVG from "@/assets/icons/close.svg";
import ReloadSVG from "@/assets/icons/reload.svg";

import Button from "@/components/Button/Button";

import Checkbox from "./Checkbox/Checkbox";
import CheckboxFilter from "./CheckboxFilter/CheckboxFilter";
import FilterLink from "./FilterLink/FilterLink";
import FilterLinkList from "./FilterLinkList/FilterLinkList";
import FilterSection from "./FilterSection/FilterSection";
import MultiRangeFilter from "./MultiRangeFilter/MultiRangeFilter";
import Select from "./Select/Select";
import SelectFilter from "./SelectFilter/SelectFilter";

import clsx from "clsx";
import styles from "./FilterPanel.module.scss";

const FilterPanelContext = createContext<{
  register: (name: string, value?: string | string[]) => void;
} | null>(null);

export const useFilterPanelContext = () => {
  const contextValue = useContext(FilterPanelContext);

  if (!contextValue)
    throw new Error(
      "FilterPanelContext has been used outside of its provider.",
    );

  return contextValue;
};

function FilterPanel({
  isOpen,
  onToggleFilter,
  children,
}: {
  isOpen?: boolean;
  onToggleFilter?: () => void;
  children: ReactNode;
}) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParamsReadonly = useSearchParams();

  const searchParams = new URLSearchParams(searchParamsReadonly);

  const registeredFilters = useRef(new Set<string>());

  const isSlider = isOpen !== undefined && onToggleFilter;

  function handleRegisterFilter(name: string) {
    registeredFilters.current.add(name);
  }

  function handleResetFilters() {
    registeredFilters.current.forEach((name) => {
      searchParams.delete(name);
    });

    router.replace(`${pathname}?${searchParams}` as Route, { scroll: false });
  }

  return (
    <FilterPanelContext.Provider value={{ register: handleRegisterFilter }}>
      <div
        className={clsx(
          styles["filter-panel"],
          isSlider && styles[`filter-panel--slider`],
          isSlider && isOpen && styles["filter-panel--open"],
        )}
      >
        <div className={styles["filter-panel__header"]}>
          <span className={styles["filter-panel__heading"]}>Фильтры</span>

          <div className={styles["filter-panel__button-group"]}>
            <Button
              icon={ReloadSVG}
              variant="plain"
              onClick={handleResetFilters}
              className={styles["filter-panel__reset-button"]}
            />

            {isSlider && (
              <Button
                variant="primary"
                icon={CloseSVG}
                onClick={onToggleFilter}
                className={styles["filter-panel__close-button"]}
              />
            )}
          </div>
        </div>

        <div className={styles["filter-panel__body"]}>{children}</div>
      </div>
    </FilterPanelContext.Provider>
  );
}

FilterPanel.Section = FilterSection;
FilterPanel.LinkList = FilterLinkList;
FilterPanel.Link = FilterLink;
FilterPanel.MultiRangeFilter = MultiRangeFilter;
FilterPanel.SelectFilter = SelectFilter;
FilterPanel.Select = Select;
FilterPanel.CheckboxFilter = CheckboxFilter;
FilterPanel.Checkbox = Checkbox;

export default FilterPanel;
