/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
import UserViewView from "./UserViewView";
import { useEffect, useState, useMemo } from "react";
import { SYSTEM_DEFAULT } from "../../../../constant";
import _ from "lodash";
import CreateScreenPopup from "./CreateScreenPopup";
import { View } from "../../data/userView";
import {
  createScreenAction,
  deleteScreenAction,
  loadScreenByIdAction,
  loadScreensAction,
  markDefaultScreenAction,
  updateScreenAction,
} from "./actions";
import { saveSystemDefaultInSession } from "./helpers/saveSystemDefaultInSession";
import getSavedSystemDefault from "./helpers/getSavedSystemDefault";
import { getInitialData } from "../../data";
import { hasUnsavedChanges } from "./helpers/hasUnsavedChanges";
import { FilterTarget } from "../../data/advancedSearch";
import {
  FilterExpression,
  FilterTarget as FilterTargetQuick,
} from "../../data/quickFilter";
import { DataWidgetType } from "../Setting/Setting";
import { ChooserColumn } from "../../data/setting";
import { getUniqueId } from "../../helper/getUniqueId";
import { globalSearchHandler } from "./helpers/uiElementHandler/globalSearchHandler";
import { advancedSearchHandler } from "./helpers/uiElementHandler/advancedSearchHandler";
import { groupByHandler } from "./helpers/uiElementHandler/groupByHandler";
import { quickFilterHandler } from "./helpers/uiElementHandler/quickFilterHandler";
import { settingHandler } from "./helpers/uiElementHandler/settingHandler";
import { sortHandler } from "./helpers/uiElementHandler/sortHandler";
import { paginationHandler } from "./helpers/uiElementHandler/paginationHandler";
import { localSearch } from "./helpers/uiElementHandler/localSearchHandler";
import { setupServiceInterceptors } from "./services";
import { replaceCustomViewData } from "./helpers/replaceCustomViewData";
import { filterCustomViewData } from "./helpers/filterCustomViewData";

export const _defaultView = {
  id: SYSTEM_DEFAULT,
  isDefault: false,
  name: "System Default",
  isSelected: false,
};

export type UserViewProps = {
  visible: boolean;
  disabled: boolean;
  enableDefaultSaveInSession: boolean;
  advancedFilterableFields: FilterTarget[];
  quickFilterRows: FilterTargetQuick[];
  activeDataWidgetType: DataWidgetType;
  columns: ChooserColumn[];
  config: { uiElementGroupId: string };
  uiElementGroupData: Record<string, any>;
  onModelUpdate: (
    callBack: ((args: any) => void) | null,
    fieldName: string,
    value: any,
  ) => void;
  getUniqueViewId?: (callBack: (response: string) => void) => void;
  eventService?: any;
  toolBarOptions?: any;
};

const UserView = (props: UserViewProps) => {
  const [togglePopup, setTogglePopup] = useState(false);
  const [savedViewData, setSavedViewData] = useState<Record<
    string,
    any
  > | null>(null);
  const [createViewError, setCreateViewError] = useState<string>("");

  useEffect(() => {
    if (props.eventService) {
      setupServiceInterceptors(props.eventService);
    }
  }, [props.eventService]);

  useEffect(() => {
    if (props.uiElementGroupData?.processing === false) {
      loadUserViews();
    }
  }, [props.uiElementGroupData?.processing]);

  useEffect(() => {
    //call custom view service and get saved data related to default custom view
    if (props.uiElementGroupData?.reset > 0) {
      const selectedView: View = (
        props.uiElementGroupData?.userView?.allViews ?? []
      ).find((view: View) => view.isDefault);

      if (
        selectedView.id === SYSTEM_DEFAULT &&
        props.enableDefaultSaveInSession
      ) {
        let uniqueViewId = props.config.uiElementGroupId;
        if (props.getUniqueViewId) {
          props.getUniqueViewId((id: string) => {
            uniqueViewId = id + "-" + props.config.uiElementGroupId;
          });
        }
        const defaultScreenViewId = `${uniqueViewId}_${SYSTEM_DEFAULT}`;
        sessionStorage.removeItem(defaultScreenViewId);
      }

      initScreenData(
        props.uiElementGroupData?.userView?.allViews ?? [],
        selectedView,
        true,
      );
    }
  }, [props.uiElementGroupData?.reset]);

  const initScreenData = async (
    allScreens: View[],
    selectedScreen: View,
    isReset?: boolean,
  ) => {
    const initialData = getInitialData();
    initialData.advancedSearch.filterRows[0].allPropertieseToFilter =
      _.cloneDeep(props.advancedFilterableFields);
    initialData.enableDataLoading = true;
    initialData.quickFilter.filterRows = props.quickFilterRows.map(
      (filterRow) => {
        const filterExpression: FilterExpression = {
          id: "QUFS__" + getUniqueId(),
          propertyToFilter: _.cloneDeep(filterRow),
          allValues: [],
          value: undefined,
        };
        return filterExpression;
      },
    );
    initialData.setting.activeDataWidgetType =
      props.uiElementGroupData?.setting?.activeDataWidgetType ??
      props.activeDataWidgetType;
    initialData.setting.columnChooser.allColumns = _.cloneDeep(props.columns);
    initialData.setting.columnChooser.appliedColumns = _.cloneDeep(
      props.columns.filter((c) => c.selected),
    );
    initialData.setting.columnChooser.selectedColumns = _.cloneDeep(
      props.columns
        .filter((c) => c.selected)
        ?.sort((a, b) => a.order - b.order),
    );
    initialData.userView.allViews = allScreens;
    initialData.userView.selectedView = selectedScreen;

    let mergedInitialData = {
      ...props.uiElementGroupData,
      ...initialData,
    };
    if (isReset) {
      mergedInitialData.localSearch =
        props.uiElementGroupData?.defaultLocalSearch;
      mergedInitialData.sort = mergedInitialData.defaultSort;
      mergedInitialData.pagination = mergedInitialData.defaultPagination;
    }

    if (selectedScreen) {
      mergedInitialData = await loadSelectedViewData(
        selectedScreen,
        mergedInitialData,
      );
    }
    props.onModelUpdate(null, props.config.uiElementGroupId, mergedInitialData);
  };

  const loadUserViews = async () => {
    const screens = await loadScreensAction(
      props.config.uiElementGroupId,
      props.getUniqueViewId,
    );

    const defaultPosition = screens.findIndex((s) => s.isDefault === true);
    const defaultView = _.cloneDeep(_defaultView);

    if (defaultPosition < 0) {
      defaultView.isDefault = true;
      defaultView.isSelected = true;
    }

    const deserializedScreens: View[] = [defaultView, ...screens];
    const selectedScreen = deserializedScreens.find(
      (view: View) => view.isSelected === true,
    );
    if (selectedScreen) initScreenData(deserializedScreens, selectedScreen);
  };

  const loadSelectedViewData = async (selectedView: View, initialData: any) => {
    let savedFilters;
    if (
      selectedView.id === SYSTEM_DEFAULT &&
      props.enableDefaultSaveInSession
    ) {
      let uniqueViewId = props.config.uiElementGroupId;
      if (props.getUniqueViewId) {
        props.getUniqueViewId((id: string) => {
          uniqueViewId = id + "-" + props.config.uiElementGroupId;
        });
      }
      const elementId = `${uniqueViewId}_${SYSTEM_DEFAULT}`;
      savedFilters = getSavedSystemDefault(elementId);
    } else if (selectedView.id !== SYSTEM_DEFAULT) {
      savedFilters = await loadScreenByIdAction(selectedView.id);
    }

    if (savedFilters) {
      setSavedViewData(savedFilters);
      // Filter savedFilters to include only enableCustomView fields
      initialData = replaceCustomViewData(
        props.uiElementGroupData,
        initialData,
        savedFilters,
        props.toolBarOptions,
      );

      /* globalSearchHandler(savedFilters.globalSearch, initialData);
      advancedSearchHandler(savedFilters.advancedSearch, initialData);
      groupByHandler(savedFilters?.groupedBy, initialData);
      quickFilterHandler(savedFilters?.quickFilter, initialData);
      settingHandler(savedFilters?.setting, initialData);
      sortHandler(savedFilters?.sort, initialData);
      paginationHandler(savedFilters?.pagination, initialData);
      localSearch(savedFilters?.localSearch, initialData); */
    } else {
      const dataToSave = filterCustomViewData(
        initialData,
        props.toolBarOptions,
      );
      setSavedViewData(dataToSave);
    }
    return initialData;
  };

  const createUserView = async (screenName: string) => {
    const { id, viewName, error } = await createScreenAction(
      screenName,
      props.config.uiElementGroupId,
      props.getUniqueViewId,
    );
    
    if (error) {
      setCreateViewError(error);
      return;
    }
    
    const systemDefaultView = props.uiElementGroupData.userView.allViews.find(
      (view: View) => view.id === SYSTEM_DEFAULT,
    );
    const otherViews = props.uiElementGroupData.userView.allViews.filter(
      (view: View) => view.id !== SYSTEM_DEFAULT,
    );
    const newView = {
      id: id,
      isDefault: false,
      name: viewName,
      isSelected: false,
    };
    const sortedOtherViews = [newView, ...otherViews].sort((a, b) =>
      a.name.localeCompare(b.name),
    );
    const deserializedScreens: View[] = systemDefaultView
      ? [systemDefaultView, ...sortedOtherViews]
      : sortedOtherViews;

    const updatedUiElementGroupData = {
      ...props.uiElementGroupData,
      userView: {
        ...props.uiElementGroupData.userView,
        allViews: deserializedScreens,
      },
    };
    props.onModelUpdate(
      null,
      props.config.uiElementGroupId,
      updatedUiElementGroupData,
    );
    onViewToggle();
  };

  const saveUserView = async (id: string) => {
    await updateScreenAction(
      id,
      props.uiElementGroupData,
      props.toolBarOptions,
    );
    // Update saved data after saving
    const savedFilters = await loadScreenByIdAction(id);
    setSavedViewData(savedFilters);
  };

  const deleteUserView = async (id: string) => {
    await deleteScreenAction(id);
    const filteredViews = props.uiElementGroupData.userView.allViews.filter(
      (view: View) => view.id !== id,
    );
    let selectedView = props.uiElementGroupData.userView.selectedView;
    if (selectedView?.id === id) {
      selectedView = {
        ..._defaultView,
        isSelected: true,
        isDefault: selectedView.isDefault,
      };
    }
    initScreenData(filteredViews, selectedView, true);
  };

  const setViewAsDefault = async (id: string) => {
    await markDefaultScreenAction(
      id,
      props.config.uiElementGroupId,
      props.getUniqueViewId,
    );

    const updatedUserView = {
      ...props.uiElementGroupData.userView,
      allViews: props.uiElementGroupData.userView.allViews.map(
        (view: View) => ({
          ...view,
          isDefault: view.id === id,
        }),
      ),
    };

    const updatedUiElementGroupData = {
      ...props.uiElementGroupData,
      userView: updatedUserView,
    };
    props.onModelUpdate(
      null,
      props.config.uiElementGroupId,
      updatedUiElementGroupData,
    );
  };

  const markAsSelected = async (view: View) => {
    const allViews = props.uiElementGroupData.userView.allViews.map(
      (v: View) => {
        return { ...v, isSelected: v.id === view.id };
      },
    );
    const selectedView = {
      ...view,
      isSelected: true,
    };

    if (
      props.uiElementGroupData.userView.selectedView?.id === SYSTEM_DEFAULT &&
      props.enableDefaultSaveInSession
    ) {
      saveSystemDefaultInSession(
        props.config.uiElementGroupId,
        props.uiElementGroupData,
        props.toolBarOptions,
        props.getUniqueViewId,
      );
    }
    initScreenData(allViews, selectedView, true);
  };

  const onViewToggle = () => {
    setTogglePopup((prevToggle) => !prevToggle);
    setCreateViewError("");
  };

  const hasChanges = useMemo(
    () =>
      hasUnsavedChanges(
        props.uiElementGroupData,
        savedViewData,
        props.toolBarOptions,
      ),
    [JSON.stringify(props.uiElementGroupData), JSON.stringify(savedViewData)],
  );

  return props.visible ? (
    <div className="tmpl-screen-view-container">
      <UserViewView
        selectedView={props.uiElementGroupData?.userView?.selectedView}
        allViews={props.uiElementGroupData?.userView?.allViews ?? []}
        disabled={props.disabled}
        onViewToggle={onViewToggle}
        onDelete={deleteUserView}
        setDefault={setViewAsDefault}
        onSave={saveUserView}
        markAsSelected={markAsSelected}
        hasUnsavedChanges={hasChanges}
      />
      {togglePopup && !props.disabled && (
        <CreateScreenPopup
          create={createUserView}
          onViewToggle={onViewToggle}
          error={createViewError}
        />
      )}
    </div>
  ) : (
    <></>
  );
};
export default UserView;
