/* eslint-disable @typescript-eslint/no-explicit-any */
import { useEffect, useRef, useState } from "react";
import QuickFilterView from "./QuickFilterView";
import { FilterExpression, FilterValue } from "../../data/quickFilter";
import { ValueLoadType } from "../../type";
import FilterPopup from "./FilterPopup";
import _ from "lodash";
import { FilterTargetType, OperatorCreiteria } from "../../enum";

export type QuickFilterProps = {
  visible: boolean;
  disabled: boolean;
  enableCustomView?: boolean;
  uiElementGroupData: Record<string, any>;
  config: { uiElementGroupId: string };
  onModelUpdate: (
    callBack: ((args: any) => void) | null,
    fieldName: string,
    value: any,
  ) => void;
  loadTemplateSupportiveData?: (
    callBack: (args: any) => void,
    supportiveKeys: any,
  ) => Promise<any>;
};

const QuickFilter = (props: QuickFilterProps) => {
  const [dataKeyRelatedValues, setDataKeyRelatedValues] = useState({});
  const [togglePopup, setTogglePopup] = useState(false);
  const popupRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (props.uiElementGroupData?.quickFilter?.filterRows?.length > 0) {
      loadFilterValues();
    }
  }, [props.uiElementGroupData?.quickFilter?.filterRows?.length]);

  useEffect(() => {
    if (togglePopup) {
      document.addEventListener("mousedown", handleClickOutside);
    } else {
      document.removeEventListener("mousedown", handleClickOutside);
    }
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [togglePopup]);

  const updateQuickFilterSupportiveData = (result: Record<string, any[]>) => {
    let dataKeyValues: Record<string, any[]> = {};
    props.uiElementGroupData?.quickFilter?.filterRows.map(
      (filterRow: FilterExpression) => {
        if (
          filterRow.propertyToFilter?.dataProvider?.valueLoadType ===
          ValueLoadType.API
        ) {
          dataKeyValues = {
            ...dataKeyValues,
            [filterRow.propertyToFilter?.dataProvider.key ?? ""]:
              result[filterRow.propertyToFilter?.dataProvider.key ?? ""],
          };
        } else if (
          filterRow.propertyToFilter?.dataProvider?.valueLoadType ===
          ValueLoadType.SELF
        ) {
          dataKeyValues = {
            ...dataKeyValues,
            [filterRow.propertyToFilter?.dataProvider.key ?? ""]: filterRow
              .propertyToFilter?.dataProvider.value as FilterValue[],
          };
        }
      },
    );
    setDataKeyRelatedValues(dataKeyValues);
  };

  const loadFilterValues = () => {
    const dataProviderKeys: string[] = [];
    props.uiElementGroupData?.quickFilter?.filterRows?.map(
      (filterRow: FilterExpression) => {
        if (
          filterRow.propertyToFilter?.dataProvider?.valueLoadType ===
          ValueLoadType.API
        ) {
          dataProviderKeys.push(
            filterRow.propertyToFilter?.dataProvider.key ?? "",
          );
        }
      },
    );

    if (dataProviderKeys.length > 0) {
      props.loadTemplateSupportiveData?.(
        updateQuickFilterSupportiveData,
        dataProviderKeys,
      );
    } else {
      updateQuickFilterSupportiveData({});
    }
  };
  const onQuickFilterApply = (
    id: string,
    value: FilterValue | FilterValue[],
  ) => {
    const filterRows = _.cloneDeep(
      props.uiElementGroupData?.quickFilter?.filterRows,
    );
    const filterRowIndex = filterRows.findIndex(
      (filterRow: FilterExpression) => filterRow.id === id,
    );

    filterRows[filterRowIndex].value = value;
    const appliedFilterRows = _.cloneDeep(filterRows).filter(
      (row: FilterExpression) => {
        if (row.propertyToFilter.type === FilterTargetType.LIST)
          return (
            (row.value as { label: string; value: any })?.value !== undefined &&
            (row.value as { label: string; value: any })?.value !== null
          );
        return row.value;
      },
    );

    const updatedQuickFilter = {
      ...props.uiElementGroupData.quickFilter,
      filterRows: filterRows,
      appliedQuery: {
        criteria: "",
        filterRows: _.cloneDeep(
          appliedFilterRows.map((row: FilterExpression) => ({
            value: row.value,
            propertyToFilter: row.propertyToFilter,
            id: row.id,
          })),
        ),
        joinCriteria: OperatorCreiteria.AND,
      },
    };

    const updatedUiElementGroupData = {
      ...props.uiElementGroupData,
      quickFilter: updatedQuickFilter,
      pagination: { ...props.uiElementGroupData.pagination, skip: 0 },
    };

    props.onModelUpdate(
      null,
      props.config.uiElementGroupId,
      updatedUiElementGroupData,
    );
    setTogglePopup(false);
  };

  const handleClickOutside = (event: MouseEvent) => {
    const target = event.target as HTMLElement;
    const isInsideMyPopup = target.closest(`.tmpl-prvent-outside-click-close`);

    if (
      popupRef.current &&
      !popupRef.current.contains(event.target as Node) &&
      !isInsideMyPopup
    ) {
      setTogglePopup(false);
    }
  };

  const onPopupToggle = () => {
    if (popupRef.current && togglePopup) {
      popupRef.current.classList.add("tmpl-popup-animation-reverse");
      setTimeout(() => {
        setTogglePopup((prevToggle) => !prevToggle);
      }, 200);
    } else {
      setTogglePopup((prevToggle) => !prevToggle);
    }
  };
  return props.visible ? (
    <div className="tmpl-quick-filter-container" ref={popupRef}>
      <QuickFilterView
        disabled={props.disabled}
        onPopupToggle={onPopupToggle}
        hasAppliedFilter={
          props.enableCustomView &&
          (props.uiElementGroupData?.quickFilter?.appliedQuery?.filterRows?.length > 0)
        }
      />
      {togglePopup && !props.disabled && (
        <FilterPopup
          filterRows={props.uiElementGroupData?.quickFilter?.filterRows ?? []}
          uiElementGroupData={props.uiElementGroupData}
          config={props.config}
          onModelUpdate={props.onModelUpdate}
          onQuickFilterApply={onQuickFilterApply}
          dataKeyRelatedValues={dataKeyRelatedValues}
        />
      )}
    </div>
  ) : (
    <></>
  );
};
export default QuickFilter;
