/* eslint-disable @typescript-eslint/no-explicit-any */
import { CodeEditor } from "@/components/CodeEditor";
import { getSelectedTheme } from "@/redux/config/configSelector";
import { configActions } from "@/redux/config/configSlice";
import { getStringSnippets, isDynamicStringSnippet } from "@/redux/utils";
import { evaluateDynamicString } from "@/utils/evaluateDynamicString";
import { useModal } from "@/utils/model/src";
import { VALIDATION_TYPES } from "@/utils/validationFactory";
import Add from "@mui/icons-material/Add";
import { Box, Button, IconButton, Tab, Tabs } from "@mui/material";
import { t } from "i18next";
import { isEqual } from "lodash-es";
import React, {
  useCallback, 
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import { useDispatch, useSelector } from "react-redux";
import { EmptySelected } from "../../../InspectPanel/components/EmptySelected";
import {
  // getAppliedTheme,
  getAppliedThemeName,
  getCachedTheme,
  getThemesObject,
} from "@/redux/currentApp/style/styleSelector";
import { styleActions } from "@/redux/currentApp/style/cursorSlice";
import { EditableText } from "@/components/EditableText";
import { createNotification } from "@/utils/Notification";
import DeleteIcon from "@mui/icons-material/Delete";
import ContrastIcon from "@mui/icons-material/Contrast";
import SaveIcon from "@mui/icons-material/Save";
import { ShortCutContext } from "@/utils/shortcut/shortcutProvider";
import { DisplayNameGenerator } from "@/utils/generators/generateDisplayName";
interface TabPanelProps {
  children?: React.ReactNode;
  // onTabClick: any;
  selectedTheme: string;
  index: number;
  value: string;
}
const Theme = () => {
  const selectedTheme = useSelector(getSelectedTheme);
  const cacheTheme = useSelector(getCachedTheme);
  const appliedTheme = useSelector(getAppliedThemeName);
  const ThemeStyle = useSelector(getThemesObject);
  const [value, setValue] = useState(`{{ 
        ${JSON.stringify(ThemeStyle[selectedTheme] || {})}
}}`);
  const modal = useModal();
  const ThemeNamesMap = useMemo(() => {
    return Object.keys(ThemeStyle);
  }, [ThemeStyle]);
  const dispatch = useDispatch();
  const handleChange = (_event: React.SyntheticEvent, newValue: string) => {
    if (selectedTheme === null) {
      dispatch(configActions.updateSelectedThemePanel(newValue));
      dispatch(styleActions.updateCachedTheme(ThemeStyle[newValue]));
      return;
    }
    if (selectedTheme !== newValue) {
      if (isEqual(ThemeStyle[selectedTheme], cacheTheme)) {
        dispatch(configActions.updateSelectedThemePanel(newValue));
        dispatch(styleActions.updateCachedTheme(ThemeStyle[newValue]));
      } else {
        // show dialog
        modal.show({
          z: 10,
          children: t("editor.action.action_list.message.confirm_switch"),
          onOk: () => {
            dispatch(configActions.updateSelectedThemePanel(newValue));
            dispatch(styleActions.updateCachedTheme(ThemeStyle[newValue]));
          },
          okButtonProps: {
            colorScheme: "red",
          },
        });
      }
    }
  };
  const handleThemeAdd = useCallback(() => {
    dispatch(
      styleActions.updateThemeReducer({
        themeName: `Theme ${ThemeNamesMap.length}`,
        theme: {},
      })
    );
  }, [ThemeNamesMap.length, dispatch]);
  useEffect(() => {
    dispatch(styleActions.updateCachedTheme(ThemeStyle[selectedTheme]));
    setValue(
      `{{ 
        ${JSON.stringify(ThemeStyle[selectedTheme], null, 2)} 
}}`
    );
  }, [ThemeStyle, dispatch, selectedTheme]);
  const handleOnChangeValue = (value: string) => {
    setValue(value);
    dispatch(
      styleActions.updateCachedTheme({
        ...ThemeStyle[selectedTheme],
        initialValue: value,
      })
    );
  };
  const saveHandler = useCallback(
    (activeTheme) => {
      const dynamicStrings = getStringSnippets(value);
      dynamicStrings.forEach((dynamicString) => {
        if (isDynamicStringSnippet(dynamicString)) {
          try {
            const calcRes = evaluateDynamicString("", dynamicString, {
              themes: ThemeStyle,
            });
            dispatch(
              styleActions.updateThemeReducer({
                themeName: activeTheme,
                theme: calcRes,
              })
            );
            dispatch(styleActions.updateCachedTheme(calcRes));
            const notification = createNotification();
            notification.show({
              title: `Save Successfully`,
              content: ``,
              duration: 1000,
              type: "success",
            });
          } catch (e) {
            console.log(e);
          }
        }
      });
    },
    [ThemeStyle, dispatch, value]
  );
  const handleUpdateDisplayNameByBlur = useCallback(
    (newThemeName: string) => {
      if (DisplayNameGenerator.isAlreadyGenerate(newThemeName)) {
        return;
      }
      DisplayNameGenerator.addDisplayNames([newThemeName]);
      DisplayNameGenerator.removeDisplayName(selectedTheme);
      dispatch(
        styleActions.updateThemeNameReducer({
          themeName: selectedTheme,
          newThemeName,
        })
      );
      dispatch(styleActions.deleteThemeReducer(selectedTheme));
      dispatch(styleActions.updateCachedTheme({}));
      dispatch(configActions.updateSelectedThemePanel(newThemeName));
    },
    [dispatch, selectedTheme]
  );
  const shortcut = useContext(ShortCutContext);
  const deleteThemehandler = useCallback(() => {
    shortcut.showDeleteDialog([selectedTheme], "theme", {
      source: "manage_delete",
    });
  }, [selectedTheme, shortcut]);
  const applyThemeHandler = useCallback(() => {
    dispatch(styleActions.updateAppliedTheme(selectedTheme));
  }, [selectedTheme, dispatch]);
  return (
    <Box sx={{ width: "100%" }}>
      <Box
        sx={{
          borderBottom: 1,
          borderColor: "divider",
          display: "flex",
          justifyContent: "space-between",
        }}
      >
        <Tabs
          sx={{ width: "90%" }}
          value={selectedTheme}
          onChange={handleChange}
          aria-label="basic tabs example"
        >
          {ThemeNamesMap.map((e) => {
            return <Tab value={e} label={e} {...a11yProps(0)} />;
          })}
        </Tabs>
        <Box
          sx={{
            fontSize: "10px",
            width: "10%",
            display: "flex",
            marginRight: "10px",
            justifyContent: "flex-end",
          }}
        >
          <IconButton sx={{ fontSize: "10px" }} onClick={handleThemeAdd}>
            <Add />
          </IconButton>
        </Box>
      </Box>
      {ThemeNamesMap.map((e, i) => {
        return (
          <CustomTabPanel selectedTheme={selectedTheme} value={e} index={i}>
            <div>
              <div style={{ display: "flex", justifyContent: "space-between" }}>
                <EditableText
                  key={e}
                  displayName={e}
                  updateDisplayNameByBlur={handleUpdateDisplayNameByBlur}
                />
                <div
                  style={{
                    width: "20%",
                    display: "flex",
                    justifyContent: "flex-end",
                  }}
                >
                  <IconButton
                    color="success"
                    onClick={() => {
                      saveHandler(e);
                    }}
                  >
                    <SaveIcon />
                  </IconButton>
                </div>
              </div>
              <CodeEditor
                value={value}
                height="200px"
                onChange={handleOnChangeValue}
                expectValueType={VALIDATION_TYPES.OBJECT}
                modalTitle={t(
                  "editor.data_work_space.global_data_modal.initial_value.label"
                )}
                modalDescription={t(
                  "editor.data_work_space.global_data_modal.initial_value.tooltips"
                )}
                placeholder={t("Please upadte your style here")}
              />
              <div
                style={{
                  justifyContent: "flex-end",
                  gap: 8,
                  display: "flex",
                  marginTop: "10px",
                }}
              >
                <Button
                  color="success"
                  variant="outlined"
                  disabled={e === appliedTheme}
                  startIcon={<ContrastIcon />}
                  onClick={applyThemeHandler}
                >
                  Apply
                </Button>
                <Button
                  color="error"
                  variant="outlined"
                  startIcon={<DeleteIcon />}
                  onClick={deleteThemehandler}
                >
                  Delete
                </Button>
              </div>
            </div>
          </CustomTabPanel>
        );
      })}
      {selectedTheme === null && (
        <EmptySelected
          tip1={"No theme selected"}
          tip2={" Click on a Theme to select it."}
        />
      )}
    </Box>
  );
};

export default Theme;

function a11yProps(index: number) {
  return {
    id: `simple-tab-${index}`,
    "aria-controls": `simple-tabpanel-${index}`,
  };
}
function CustomTabPanel(props: TabPanelProps) {
  const {
    children,
    value,
    selectedTheme,
    index,
    //  onTabClick,
    ...other
  } = props;

  return (
    <div
      role="tabpanel"
      // onClick={() => onTabClick()}
      hidden={value !== selectedTheme}
      id={`simple-tabpanel-${index}`}
      aria-labelledby={`simple-tab-${index}`}
      style={{ height: "350px" }}
      {...other}
    >
      {value === selectedTheme && <Box sx={{ p: 3 }}>{children}</Box>}
    </div>
  );
}
