/* eslint-disable react-hooks/exhaustive-deps */
import React, { useCallback, useEffect, useMemo, useState } from "react";
import styles from "./styles.module.scss";
import { useTranslations } from "next-intl";
import ModalMaker, {
  ModalMakerProps,
} from "@/components/ModalMaker/ModalMaker";
import TitleAndSubtitle from "@/components/TitleAndSubtitle/TitleAndSubtitle";
import { Button, InputBase } from "@mui/material";
import { SearchObject } from "@/screens/Results/components/MoreFilters/moreFilters";
import {
  GetPropertCategoriesParams,
  GetPropertCategoriesResponse,
  GetPropertTypesParams,
  GetPropertTypesResponse,
  GetPropertUrbTypesParams,
  GetPropertUrbTypesResponse,
} from "@/lib/services/redux/reducers/properties/propertiesActions.d";
import {
  GetPropertyCategories,
  GetPropertyTypes,
  GetPropertyUrbTypes,
} from "@/lib/services/redux/reducers/properties/propertiesActions";
import useRequestHandler from "@/hooks/useRequestHandler/useRequestHandler";
import { SelectOptionsProps } from "@/components/FormInput/types";
import { PRIMARY_COLOR, WHITE } from "@/styles/constants";
import { debounce } from "lodash";

interface FiltersModalProps {
  modalProps: ModalMakerProps;
  filters: SearchObject;
  setFilters: (currentFilters: Partial<SearchObject>) => unknown;
  retrySearchFunction: (currentFilters?: Partial<SearchObject>) => unknown;
}

const FiltersModal: React.FC<FiltersModalProps> = ({
  modalProps,
  filters,
  setFilters: setFiltersNoReal,
  retrySearchFunction,
}) => {
  const t = useTranslations();

  const { fetcher: fetcherTypes } = useRequestHandler<
    GetPropertTypesResponse,
    GetPropertTypesParams
  >(GetPropertyTypes);
  const { fetcher: fetcherUrbTypes } = useRequestHandler<
    GetPropertUrbTypesResponse,
    GetPropertUrbTypesParams
  >(GetPropertyUrbTypes);
  const { fetcher: fetcherCategories } = useRequestHandler<
    GetPropertCategoriesResponse,
    GetPropertCategoriesParams
  >(GetPropertyCategories);

  const [propertyTypes, setPropertyTypes] = useState<SelectOptionsProps[]>([]);
  const [categories, setCategories] = useState<SelectOptionsProps[]>([]);
  const [urbTypes, setUrbTypes] = useState<SelectOptionsProps[]>([]);

  const quantities = Array(6)
    .fill(0)
    .map((d, i) => {
      return {
        label: `${d + i + 1}+`,
        name: `${d + i + 1}+`,
        value: d + i + 1,
      };
    });

  const debouncedSearch = useMemo(
    () =>
      debounce(
        (currentFilters: Partial<SearchObject>) =>
          retrySearchFunction(currentFilters),
        1000
      ),
    []
  );

  const setFilters = (currentFilters: Partial<SearchObject>) => {
    setFiltersNoReal(currentFilters);
    debouncedSearch(currentFilters);
  };

  const retryFunction = async () => {
    const typeshere = await fetcherTypes({});

    if (typeshere.status === "success") {
      setPropertyTypes(
        typeshere.response.types.map((d) => {
          return {
            label: d.nombre,
            name: d.id,
            value: d.id,
          };
        })
      );
    }

    const urbTypeshere = await fetcherUrbTypes({});

    if (urbTypeshere.status === "success") {
      setUrbTypes(
        urbTypeshere.response.sets.map((d) => {
          return {
            label: d.nombre,
            name: d.id,
            value: d.id,
          };
        })
      );
    }
    const categorieshere = await fetcherCategories({});

    if (categorieshere.status === "success") {
      setCategories(
        categorieshere.response.categories.map((d) => {
          return {
            label: d.nombre,
            name: d.id,
            value: d.id,
          };
        })
      );
    }
  };

  useEffect(() => {
    retryFunction();
  }, []);

  const handlePropertyTypes = useCallback(
    (val: string) => {
      const values = [...(filters.propertyType ?? [])];

      if (values.includes(val)) {
        setFilters({
          ...filters,
          propertyType: values.filter((d) => d !== val),
        });
      } else {
        setFilters({ ...filters, propertyType: values.concat(val) });
      }
    },
    [filters]
  );
  const handlePropertyUrbTypes = useCallback(
    (val: string) => {
      const values = [...(filters.urbType ?? [])];

      if (values.includes(val)) {
        setFilters({
          ...filters,
          urbType: values.filter((d) => d !== val),
        });
      } else {
        setFilters({ ...filters, urbType: values.concat(val) });
      }
    },
    [filters]
  );

  const handleClean = () => {
    setFilters({
      price: [0, 0],
      terrain: [0, 0],
      built: [0, 0],
    });
  };

  const handleSubmit = useCallback(() => {
    modalProps.toggle();
  }, []);

  return (
    <ModalMaker
      {...modalProps}
      showToggle
      style={{
        maxWidth: "506px",
        padding: 0,
      }}
    >
      <div className={styles.filtersModalContainer}>
        <div className={styles.header}>
          <TitleAndSubtitle
            title={t("filters")}
            titleStyle={{
              marginBottom: "10px",
            }}
            style={{ alignItems: "center" }}
            showBottomDivider
          />
          <p className={styles.subtitle}>{t("selectDesiredFilters")}</p>
        </div>
        <div className={styles.content}>
          <div className={styles.contentFill}>
            <div className={styles.card}>
              <p className={styles.title}>{t("category")}</p>
              {categories.map((d) => {
                return (
                  <Button
                    variant="contained"
                    disableElevation
                    key={d.value}
                    className={styles.button}
                    style={{
                      minWidth: "47.5%",
                      background: filters.propertyType?.includes(d.value)
                        ? "#E23052"
                        : WHITE,
                      color: !filters.propertyType?.includes(d.value)
                        ? "#E23052"
                        : WHITE,
                      borderColor: "#E23052",
                    }}
                    onClick={() => handlePropertyTypes(d.value)}
                  >
                    {d.label}
                  </Button>
                );
              })}
            </div>
            <div className={styles.card}>
              <p className={styles.title}>{t("propertyType")}</p>
              {propertyTypes.map((d) => {
                return (
                  <Button
                    variant="contained"
                    disableElevation
                    key={d.value}
                    className={styles.button}
                    style={{
                      minWidth: "47.5%",
                      background: filters.propertyType?.includes(d.value)
                        ? PRIMARY_COLOR
                        : WHITE,
                      color: !filters.propertyType?.includes(d.value)
                        ? PRIMARY_COLOR
                        : WHITE,
                    }}
                    onClick={() => handlePropertyTypes(d.value)}
                  >
                    {d.label}
                  </Button>
                );
              })}
            </div>
            <div className={styles.rowOfCards}>
              <div className={styles.cardLimit}>
                <div className={styles.card}>
                  <p className={styles.title}>{t("rooms")}</p>
                  {quantities.map((d) => {
                    return (
                      <Button
                        variant="contained"
                        key={d.name}
                        disableElevation
                        className={styles.button}
                        style={{
                          minWidth: "fit-content",
                          maxWidth: "66px",
                          width: "fit-content",
                          background:
                            filters.rooms === d.value ? PRIMARY_COLOR : WHITE,
                          color:
                            filters.rooms !== d.value ? PRIMARY_COLOR : WHITE,
                        }}
                        onClick={() =>
                          setFilters({ ...filters, rooms: d.value })
                        }
                      >
                        {d.label}
                      </Button>
                    );
                  })}
                </div>
              </div>
              <div className={styles.cardLimit}>
                <div className={styles.card}>
                  <p className={styles.title}>{t("bathRooms")}</p>
                  {quantities.map((d) => {
                    return (
                      <Button
                        variant="contained"
                        key={d.name}
                        disableElevation
                        className={styles.button}
                        style={{
                          minWidth: "fit-content",
                          maxWidth: "66px",
                          width: "fit-content",
                          background:
                            filters.bathRooms === d.value
                              ? PRIMARY_COLOR
                              : WHITE,
                          color:
                            filters.bathRooms !== d.value
                              ? PRIMARY_COLOR
                              : WHITE,
                        }}
                        onClick={() =>
                          setFilters({ ...filters, bathRooms: d.value })
                        }
                      >
                        {d.label}
                      </Button>
                    );
                  })}
                </div>
              </div>
              <div className={styles.cardLimit}>
                <div className={styles.card}>
                  <p className={styles.title}>{t("parkings")}</p>
                  {quantities.map((d) => {
                    return (
                      <Button
                        variant="contained"
                        key={d.name}
                        disableElevation
                        className={styles.button}
                        style={{
                          minWidth: "fit-content",
                          maxWidth: "66px",
                          width: "fit-content",
                          background:
                            filters.parkings === d.value
                              ? PRIMARY_COLOR
                              : WHITE,
                          color:
                            filters.parkings !== d.value
                              ? PRIMARY_COLOR
                              : WHITE,
                        }}
                        onClick={() =>
                          setFilters({ ...filters, parkings: d.value })
                        }
                      >
                        {d.label}
                      </Button>
                    );
                  })}
                </div>
              </div>
            </div>
            <div className={styles.rowOfCards}>
              <div className={styles.cardLimit}>
                <div className={styles.card} style={{ height: "fit-content" }}>
                  <p className={styles.title} style={{ textAlign: "left" }}>
                    {t("price")}
                  </p>
                  <div className={styles.inputRow}>
                    <InputBase
                      className={styles.input}
                      placeholder={t("from")}
                      type="number"
                      value={filters?.price?.[0] ?? undefined}
                      onChange={(d) => {
                        const value = [...(filters.price ?? [])];
                        value[0] = Number(d.target.value);

                        setFilters({ ...filters, price: value });
                      }}
                    />
                    <InputBase
                      className={styles.input}
                      placeholder={t("until")}
                      type="number"
                      value={filters?.price?.[1] ?? undefined}
                      onChange={(d) => {
                        const value = [...(filters.price ?? [])];
                        value[1] = Number(d.target.value);

                        setFilters({ ...filters, price: value });
                      }}
                    />
                  </div>
                </div>
              </div>
              <div className={styles.cardLimit}>
                <div className={styles.card} style={{ height: "fit-content" }}>
                  <p className={styles.title} style={{ textAlign: "left" }}>
                    {t("terrain")}
                  </p>
                  <div className={styles.inputRow}>
                    <InputBase
                      className={styles.input}
                      placeholder={t("from")}
                      type="number"
                      value={filters?.terrain?.[0] ?? undefined}
                      onChange={(d) => {
                        const value = [...(filters.terrain ?? [])];
                        value[0] = Number(d.target.value);

                        setFilters({ ...filters, terrain: value });
                      }}
                    />
                    <InputBase
                      className={styles.input}
                      placeholder={t("until")}
                      type="number"
                      value={filters?.terrain?.[1] ?? undefined}
                      onChange={(d) => {
                        const value = [...(filters.terrain ?? [])];
                        value[1] = Number(d.target.value);

                        setFilters({ ...filters, terrain: value });
                      }}
                    />
                  </div>
                </div>
              </div>
              <div className={styles.cardLimit}>
                <div className={styles.card} style={{ height: "fit-content" }}>
                  <p className={styles.title} style={{ textAlign: "left" }}>
                    {t("built")}
                  </p>
                  <div className={styles.inputRow}>
                    <InputBase
                      className={styles.input}
                      placeholder={t("from")}
                      type="number"
                      value={filters?.built?.[0] ?? undefined}
                      onChange={(d) => {
                        const value = [...(filters.built ?? [])];
                        value[0] = Number(d.target.value);

                        setFilters({ ...filters, built: value });
                      }}
                    />
                    <InputBase
                      className={styles.input}
                      placeholder={t("until")}
                      type="number"
                      value={filters?.built?.[1] ?? undefined}
                      onChange={(d) => {
                        const value = [...(filters.built ?? [])];
                        value[1] = Number(d.target.value);

                        setFilters({ ...filters, built: value });
                      }}
                    />
                  </div>
                </div>
              </div>
            </div>
            <div className={styles.card}>
              <p className={styles.title}>{t("urbType")}</p>
              {urbTypes.map((d) => {
                return (
                  <Button
                    variant="contained"
                    key={d.value}
                    disableElevation
                    className={styles.button}
                    style={{
                      minWidth: "47.5%",
                      background: filters.urbType?.includes(d.value)
                        ? PRIMARY_COLOR
                        : WHITE,
                      color: !filters.urbType?.includes(d.value)
                        ? PRIMARY_COLOR
                        : WHITE,
                    }}
                    onClick={() => handlePropertyUrbTypes(d.value)}
                  >
                    {d.label}
                  </Button>
                );
              })}
            </div>
          </div>
        </div>
        <div className={styles.footer}>
          <Button
            variant="contained"
            disableElevation
            className={styles.clean}
            onClick={handleClean}
          >
            {t("clean")}
          </Button>
          <Button
            variant="contained"
            disableElevation
            className={styles.viewResults}
            onClick={handleSubmit}
          >
            {t("viewResults")}
          </Button>
        </div>
      </div>
    </ModalMaker>
  );
};

export default FiltersModal;
