import { useEffect, useState } from "react";
import { filterBy } from "@progress/kendo-data-query";
import DropDownWidgetView from "./DropDownWidgetView";
import debounce from "lodash/debounce";
import { ComprehensiveProps } from "../../DomainProps";

export enum ValueLoadType {
  "SELF" = "SELF",
  "API" = "API",
  "ADAPTER" = "ADAPTER",
  "STATE" = "STATE",
}

export interface DropDownProps extends ComprehensiveProps {
  dataItemKey?: string | undefined;
  toggleFetch?: number;
  defaultItem?: any;
  defaultValue?: any;
  textField?: string;
  popupSettings?: Record<string, any>;
  config?: any;
  pagination?: { skip: number; take: number };
  dataProvider?:
    | {
        value: string | { label: string; value: any; [key: string]: any }[];
        valueLoadType: ValueLoadType;
        apiKey?: string;
      }
    | undefined;
  lazyLoading?: boolean;
  enableSearch?: boolean;
  loadData?: (
    callBack: (response: any) => void,
    supportiveKeys: string[]
  ) => void;
}

const DropDownWidget = (props: DropDownProps) => {
  const eventService = props.eventService;
  const [page, setPage] = useState(1);
  const [supportiveData, setSupportiveData] = useState(props.listData);
  const [localValue, setLocalValue] = useState(props.value);

  const resultHandler = (response: any) => {
    const appActions = eventService?.emit("DATASTATE_ACTION");
    const dispatch = eventService?.emit("DISPATCH_STORE");

    let dropDownData = response[props.dataProvider?.apiKey || ""];

    if (props.lazyLoading === true && page > 1) {
      dropDownData = [...(props.listData || []), ...(dropDownData || [])];
    }

    dispatch(
      appActions.updateViewModel({
        key: props.supportiveDataField,
        value: dropDownData,
      })
    );
  };

  const loadSelfData = (dropDownData: any) => {
    const appActions = eventService?.emit("DATASTATE_ACTION");
    const dispatch = eventService?.emit("DISPATCH_STORE");
    dispatch(
      appActions.updateViewModel({
        key: props.supportiveDataField,
        value: dropDownData,
      })
    );
  };

  const handleScroll = debounce((event) => {
    if (props.lazyLoading === true) {
      eventService?.subscribe(
        props.config.uiElementGroupId + "GET_SUPPORTIVE_PAGE",
        () => {
          return { take: props.pagination?.take, skip: props.pagination?.skip };
        }
      );
      setPage((prevPage) => prevPage + 1);
    }
  }, 200);

  const onFilterChange = debounce((event) => {
    if (props.dataProvider?.valueLoadType === "STATE") {
      const filteredData = filterBy(
        props.listData?.slice() || [],
        event.filter
      );
      setSupportiveData(filteredData);
    } else {
      eventService?.subscribe(
        props.config.uiElementGroupId + "GET_SUPPORTIVE_FILTERS",
        () => event.filter
      );
      setPage((prevPage) => prevPage + 1);
    }
  }, 200);

  const handleChange = (event: any) => {
    setLocalValue(event.value);
    if (props?.onChange)
      props?.onChange(null, props?.screenDataField, event.value, event);
  };

  useEffect(() => {
    if (props.value !== localValue) {
      setLocalValue(props.value);
    }
  }, [props.value]);

  useEffect(() => {
    if (
      props.loadData &&
      props.dataProvider?.valueLoadType === ValueLoadType.API
    ) {
      props.loadData(resultHandler, [props.dataProvider?.apiKey || ""]);
    } else if (props.dataProvider?.valueLoadType === ValueLoadType.SELF) {
      loadSelfData(props.dataProvider.value);
    }
  }, [props?.config?.uiElementGroupId, page, props?.toggleFetch]);

  useEffect(() => {
    setSupportiveData(props?.listData);
  }, [props?.listData]);

  return (
    <section
      id={props.rootStyle?.id}
      className={props.rootStyle?.className}
      style={props.rootStyle?.inline}
    >
      <DropDownWidgetView
        screenDataField={props.screenDataField}
        dataItemKey={props.dataItemKey}
        defaultItem={props.defaultItem}
        defaultValue={props.defaultValue}
        textField={props.textField}
        enableSearch={props.enableSearch}
        handleScroll={handleScroll}
        onFilterChange={onFilterChange}
        supportiveData={supportiveData}
        widgetStyle={props.widgetStyle}
        helperText={props.helperText}
        label={props.label}
        toolTip={props.toolTip}
        validations={props.validations}
        onChange={handleChange}
        value={localValue}
        disabled={props.disabled}
        onBlur={props.onBlur}
        popupSettings={props.popupSettings}
      />
    </section>
  );
};

export default DropDownWidget;
