import { DeleteOutlined, ExclamationCircleOutlined, PlusOutlined } from "@ant-design/icons";
import { useMutation } from "@apollo/client/react";
import { Button, Form, Input, Modal, Popconfirm, Popover, Select, Space } from "antd";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { UPDATE_ACTIVE_PROD_LIST_VIEW } from "../../graphql/associations.queries";
import { UPDATE_SHOP } from "../../graphql/bodyshop.queries";
import ProductionListColumns from "../production-list-columns/production-list-columns.data";
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { isFunction } from "lodash";
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";

const { confirm } = Modal;

export function ProductionListConfigManager({
  refetch,
  bodyshop,
  technician,
  currentUser,
  state,
  data,
  columns,
  setColumns,
  setState,
  onSave,
  hasUnsavedChanges,
  setHasUnsavedChanges
}) {
  const { t } = useTranslation();
  const [updateDefaultProdView] = useMutation(UPDATE_ACTIVE_PROD_LIST_VIEW);
  const [updateShop] = useMutation(UPDATE_SHOP);
  const [loading, setLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const [isAddingNewProfile, setIsAddingNewProfile] = useState(false);
  const [form] = Form.useForm();
  const notification = useNotification();

  const [activeView, setActiveView] = useState(() => {
    const assoc = bodyshop.associations.find((a) => a.useremail === currentUser.email);
    return assoc?.default_prod_list_view;
  });

  const defaultState = {
    sortedInfo: {
      columnKey: "ro_number",
      order: null
    },
    filteredInfo: {}
  };

  const ensureDefaultState = (state) => {
    return {
      sortedInfo: state?.sortedInfo || defaultState.sortedInfo,
      filteredInfo: state?.filteredInfo || defaultState.filteredInfo,
      ...state
    };
  };

  const createDefaultView = async () => {
    const defaultConfig = {
      name: t("production.constants.main_profile"),
      columns: {
        columnKeys: [
          { key: "ro_number", width: 100 },
          { key: "ownr", width: 100 },
          { key: "vehicle", width: 100 },
          { key: "ins_co_nm", width: 100 },
          { key: "actual_in", width: 100 },
          { key: "scheduled_completion", width: 100 },
          { key: "labhrs", width: 100 },
          { key: "employee_body", width: 100 },
          { key: "larhrs", width: 100 },
          { key: "employee_refinish", width: 100 },
          { key: "tt", width: 100 },
          { key: "status", width: 100 },
          { key: "sublets", width: 100 },
          { key: "viewdetail", width: 100 }
        ],
        tableState: ensureDefaultState(state)
      }
    };

    const result = await updateShop({
      variables: {
        id: bodyshop.id,
        shop: {
          production_config: [defaultConfig]
        }
      }
    });

    if (!result.errors) {
      await updateActiveProdView(t("production.constants.main_profile"));
      window.location.reload(); // Reload the page
    } else {
      notification.error({
        title: t("bodyshop.errors.creatingdefaultview", {
          error: JSON.stringify(result.errors)
        })
      });
    }
  };

  const {
    treatments: { Enhanced_Payroll }
  } = useTreatmentsWithConfig({
    attributes: {},
    names: ["Enhanced_Payroll"],
    splitKey: bodyshop.imexshopid
  });

  const updateActiveProdView = async (viewName) => {
    const assoc = bodyshop.associations.find((a) => a.useremail === currentUser.email);
    if (assoc) {
      await updateDefaultProdView({
        variables: { assocId: assoc.id, view: viewName },
        update(cache) {
          cache.modify({
            id: cache.identify(bodyshop),
            fields: {
              associations(existingAssociations) {
                return existingAssociations.map((a) => {
                  if (a.useremail !== currentUser.email) return a;
                  return { ...a, default_prod_list_view: viewName };
                });
              }
            }
          });
        }
      });
      setActiveView(viewName);
      setHasUnsavedChanges(false);
    }
  };

  const handleSelect = async (value) => {
    if (hasUnsavedChanges) {
      confirm({
        title: t("general.labels.unsavedchanges"),
        icon: <ExclamationCircleOutlined />,
        content: t("general.messages.unsavedchangespopup"),
        onOk: () => proceedWithSelect(value),
        onCancel() {
          // Do nothing if canceled
        }
      });
    } else {
      await proceedWithSelect(value);
    }
  };

  const proceedWithSelect = async (value) => {
    if (value === "add_new") {
      setIsAddingNewProfile(true);
      setOpen(true);
      return;
    }

    const selectedConfig = bodyshop.production_config.find((pc) => pc.name === value);

    // If the selected profile doesn't exist, revert to the main profile
    if (!selectedConfig) {
      const mainProfileConfig = bodyshop.production_config.find(
        (pc) => pc.name === t("production.constants.main_profile")
      );

      if (mainProfileConfig) {
        await updateActiveProdView(t("production.constants.main_profile"));
        setColumns(
          mainProfileConfig.columns.columnKeys.map((k) => {
            return {
              ...ProductionListColumns({
                bodyshop,
                refetch,
                technician,
                state: ensureDefaultState(state),
                data: data,
                activeStatuses: bodyshop.md_ro_statuses.active_statuses,
                treatments: { Enhanced_Payroll }
              }).find((e) => e.key === k.key),
              width: k.width
            };
          })
        );
        const newState = ensureDefaultState(mainProfileConfig.columns.tableState);
        setState(newState);

        if (onSave && isFunction(onSave)) {
          onSave();
        }
        return;
      }
    }

    // If the selected profile exists, proceed as normal
    if (selectedConfig) {
      const newColumns = selectedConfig.columns.columnKeys.map((k) => {
        return {
          ...ProductionListColumns({
            bodyshop,
            refetch,
            technician,
            state: ensureDefaultState(state),
            data: data,
            activeStatuses: bodyshop.md_ro_statuses.active_statuses,
            treatments: { Enhanced_Payroll }
          }).find((e) => e.key === k.key),
          width: k.width
        };
      });
      setColumns(newColumns);
      const newState = ensureDefaultState(selectedConfig.columns.tableState);
      setState(newState);

      await updateActiveProdView(value);
      if (onSave && isFunction(onSave)) {
        onSave();
      }
    }
  };

  const handleTrash = async (name) => {
    if (name === t("production.constants.main_profile")) return;

    const remainingConfigs = bodyshop.production_config.filter((b) => b.name !== name);

    await updateShop({
      variables: {
        id: bodyshop.id,
        shop: {
          production_config: remainingConfigs
        }
      },
      awaitRefetchQueries: true
    });

    if (name === activeView) {
      // Only switch profiles if the deleted profile was the active profile
      if (remainingConfigs.length > 0) {
        const nextConfig = remainingConfigs[0];
        await updateActiveProdView(nextConfig.name);
        setColumns(
          nextConfig.columns.columnKeys.map((k) => {
            return {
              ...ProductionListColumns({
                bodyshop,
                technician,
                state: ensureDefaultState(state),
                refetch,
                data: data,
                activeStatuses: bodyshop.md_ro_statuses.active_statuses,
                treatments: { Enhanced_Payroll }
              }).find((e) => e.key === k.key),
              width: k.width
            };
          })
        );
        setState(ensureDefaultState(nextConfig.columns.tableState));
      } else {
        await updateActiveProdView(null);
        setColumns([]);
        setState(defaultState);
      }
    } else {
      // Revert back to the active view and load its columns and state
      const activeConfig = bodyshop.production_config.find((pc) => pc.name === activeView);
      if (activeConfig) {
        await updateActiveProdView(activeView);
        setColumns(
          activeConfig.columns.columnKeys.map((k) => {
            return {
              ...ProductionListColumns({
                bodyshop,
                technician,
                state: ensureDefaultState(state),
                refetch,
                data: data,
                activeStatuses: bodyshop.md_ro_statuses.active_statuses,
                treatments: { Enhanced_Payroll }
              }).find((e) => e.key === k.key),
              width: k.width
            };
          })
        );
        setState(ensureDefaultState(activeConfig.columns.tableState));
      }
    }
  };

  const handleSaveConfig = async (values) => {
    logImEXEvent("production_save_config");
    setLoading(true);

    const profileName = isAddingNewProfile ? values.name : activeView;

    const result = await updateShop({
      variables: {
        id: bodyshop.id,
        shop: {
          production_config: [
            ...bodyshop.production_config.filter((b) => b.name !== profileName),
            {
              name: profileName,
              columns: {
                columnKeys: columns.map((i) => ({ key: i.key, width: i.width })),
                tableState: ensureDefaultState(state)
              }
            }
          ]
        }
      }
    });

    if (!result.errors) {
      notification.success({ title: t("bodyshop.successes.save") });
      if (isAddingNewProfile) {
        await updateActiveProdView(profileName);
      }
      if (onSave && isFunction(onSave)) {
        onSave();
      }
      setHasUnsavedChanges(false);
    } else {
      notification.error({
        title: t("bodyshop.errors.saving", {
          error: JSON.stringify(result.errors)
        })
      });
    }

    form.resetFields();
    setOpen(false);
    setLoading(false);
    setIsAddingNewProfile(false);
  };

  useEffect(() => {
    const validateAndSetDefaultView = () => {
      const configExists = bodyshop.production_config.some((pc) => pc.name === activeView);

      if (!configExists) {
        // If the default view doesn't exist, revert to the main profile
        const mainProfileConfig = bodyshop.production_config.find(
          (pc) => pc.name === t("production.constants.main_profile")
        );

        if (mainProfileConfig) {
          setActiveView(t("production.constants.main_profile"));

          setColumns(
            mainProfileConfig.columns.columnKeys.map((k) => {
              return {
                ...ProductionListColumns({
                  bodyshop,
                  refetch,
                  technician,
                  state: ensureDefaultState(state),
                  data: data,
                  activeStatuses: bodyshop.md_ro_statuses.active_statuses,
                  treatments: { Enhanced_Payroll }
                }).find((e) => e.key === k.key),
                width: k.width
              };
            })
          );
          setState(ensureDefaultState(mainProfileConfig.columns.tableState));

          updateActiveProdView(t("production.constants.main_profile"));
        }
      } else {
        // If the default view exists, set it as active
        setActiveView(activeView);
      }
    };

    if (!bodyshop.production_config || bodyshop.production_config.length === 0) {
      createDefaultView().catch(() => {
        console.error("Something went wrong saving the production list view Config.");
      });
    } else {
      validateAndSetDefaultView();
    }
  }, [activeView, bodyshop.production_config]);

  const popMenu = (
    <div>
      <Form layout="vertical" form={form} onFinish={handleSaveConfig}>
        {isAddingNewProfile && (
          <Form.Item
            label={t("production.labels.viewname")}
            name="name"
            rules={[
              { required: true, message: t("production.errors.name_required") },
              {
                validator: (_, value) => {
                  if (!value) {
                    return Promise.resolve();
                  }
                  const nameExists = bodyshop.production_config.some((pc) => pc.name === value);
                  if (nameExists) {
                    return Promise.reject(new Error(t("production.errors.name_exists")));
                  }
                  return Promise.resolve();
                }
              }
            ]}
          >
            <Input />
          </Form.Item>
        )}
        <Space wrap>
          <Button
            type="primary"
            danger
            onClick={() => form.submit()}
            loading={loading}
            disabled={form.getFieldsError().some(({ errors }) => errors.length)}
          >
            {t("general.actions.save")}
          </Button>
          {!isAddingNewProfile && (
            <Button
              type="default"
              onClick={() => {
                setIsAddingNewProfile(true);
                setOpen(true);
              }}
            >
              {t("general.actions.saveas")}
            </Button>
          )}
          <Button
            onClick={() => {
              setIsAddingNewProfile(false);
              setOpen(false);
            }}
          >
            {t("general.actions.cancel")}
          </Button>
        </Space>
      </Form>
    </div>
  );

  return (
    <Space>
      <Button loading={loading} onClick={() => setOpen(true)} disabled={isAddingNewProfile || !hasUnsavedChanges}>
        {t("production.actions.saveconfig")}
      </Button>
      <Popover open={open} content={popMenu} placement="bottom">
        <Select
          style={{
            minWidth: "150px"
          }}
          onSelect={handleSelect}
          placeholder={t("production.labels.selectview")}
          popupMatchSelectWidth={false}
          value={activeView}
          disabled={open || isAddingNewProfile} // Disable the Select box when the popover is open or adding a new profile
          optionLabelProp="label"
        >
          {bodyshop?.production_config &&
            bodyshop.production_config
              .slice()
              .sort((a, b) =>
                a.name === t("production.constants.main_profile")
                  ? -1
                  : b.name === t("production.constants.main_profile")
                    ? 1
                    : 0
              ) //
              .map((config) => (
                <Select.Option key={config.name} label={config.name}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                    <span
                      style={{
                        flex: 1,
                        maxWidth: "80%",
                        marginRight: "1rem",
                        textOverflow: "ellipsis"
                      }}
                    >
                      {config.name}
                    </span>
                    {config.name !== t("production.constants.main_profile") && (
                      <Popconfirm
                        placement="right"
                        title={t("general.labels.areyousure")}
                        onConfirm={() => handleTrash(config.name)}
                        onCancel={(e) => e.stopPropagation()}
                      >
                        <DeleteOutlined onClick={(e) => e.stopPropagation()} />
                      </Popconfirm>
                    )}
                  </div>
                </Select.Option>
              ))}
          <Select.Option key="add_new" label={t("production.labels.addnewprofile")}>
            <div style={{ display: "flex", alignItems: "center" }}>
              <PlusOutlined style={{ marginRight: "0.5rem" }} />
              {t("production.labels.addnewprofile")}
            </div>
          </Select.Option>
        </Select>
      </Popover>
    </Space>
  );
}
