import {
  CancelIcon,
  CheckCircleIcon,
  EditIcon,
} from "@app/assets/images/icons";
import Button from "@app/components/button/Button";
import CardContent from "@app/components/card-content/CardContent";
import CardHeader from "@app/components/card-header/CardHeader";
import CardFooter from "@app/components/card-footer/CardFooter";
import { CardHeaderProps, MenuOption } from "@app/models/components";
import { useSettings } from "@settings/contexts/SettingsContext";
import React, { useEffect, useState } from "react";
import "./configuration-list-styles.scss";
import CardSection from "@app/components/card-section/CardSection";
import Modal from "@app/components/modal/Modal";
import { extractAPIKeyFromURL } from "@app/services/utilities";
import { NavLink, useNavigate } from "react-router-dom";
import { saveApiKey, resetPlugin } from "@app/services/api";
import { useBlockNavigation } from "@settings/contexts/NavigationContext";
import InputField from "@app/components/input-field/InputField";

const ConfigurationList = () => {
  const [isOpenDeleteConfigModal, setIsOpenDeleteConfigModal] = useState(false);
  const [isDeletingConfig, setIsDeletingConfig] = useState(false);

  const apiKeyFromParam = extractAPIKeyFromURL(window.location.href);
  const localization = sfsyncI18n.data;
  const { initialSettings, setInitialSettings, showNotification } = useSettings();
  const { setIsNavBlocked } = useBlockNavigation();
  const [isVerifyingAPIKey, setIsVerifyingAPIKey] = useState(false);
  const [showCheck, setShowCheck] = useState(false);
  const [verifyResult, setVerifyResult] = useState(false);
  const [apiKey, setApiKey] = useState<string>(
    apiKeyFromParam
      ? apiKeyFromParam
      : initialSettings.api_key ?? apiKeyFromParam ?? ""
  );
  const [changeVerifyState, setChangeVerifyState] = useState(
    initialSettings.api_key === ""
  );
  const [concealedKey, setConcealedKey] = useState(concealKey(apiKey));
  const navigate = useNavigate();

  function concealKey(key: string) {
    if (!key) {
      return "";
    }
    return key.slice(0, 5) + "*".repeat(key.length - 5);
  }

  const handleVerifyAPI = async (inBackground: boolean = true) => {
    if (!inBackground) {
      setIsVerifyingAPIKey(true);
      setIsNavBlocked(true);
    } else {
      setShowCheck(true);
    }

    // Validates the key, persists settings, and upserts each linked
    // account's config + WP page server-side (see WP-4403).
    const saveApiKeyResp = await saveApiKey(apiKey);

    if (saveApiKeyResp?.error) {
      setIsVerifyingAPIKey(false);
      setVerifyResult(true);
      setShowCheck(false);
      setIsNavBlocked(false);
      if (!inBackground) {
        showNotification("error", localization.saving_settings_message);
      }
      if (saveApiKeyResp.status === 404 || saveApiKeyResp.status === 401) {
        const deleteConfig = await handleDeleteConfig(false);
        if (deleteConfig) {
          setVerifyResult(false);
        }
      }
      return;
    }

    setConcealedKey(concealKey(concealedKey));

    setInitialSettings({
      ...initialSettings,
      api_key: apiKey,
      api_key_verified: saveApiKeyResp.api_key_verified ?? true,
      selected_config: saveApiKeyResp.selected_config ?? initialSettings.selected_config,
      config_list: {
        ...(initialSettings.config_list || {}),
        ...(saveApiKeyResp.config_list || {}),
      },
    });

    if (!inBackground) {
      setShowCheck(true);
      setVerifyResult(true);
      setChangeVerifyState(false);
    }
    setIsVerifyingAPIKey(false);
    setIsNavBlocked(false);
  };

  useEffect(() => {
    if (apiKey) {
      handleVerifyAPI(
        !apiKeyFromParam ||
          (!!apiKeyFromParam && apiKeyFromParam === initialSettings.api_key)
      );
    }
  }, []);

  const navigateToDashboard = (getAPI = false) => {
    navigate("/dashboard/overview", {
      replace: true,
      state: {
        getAPI: getAPI,
      },
    });
  };

  const headerProps: CardHeaderProps = {
    title: localization.configuration,
    subtitle: (
      <>
        {localization.add_your_api_key_from_your}{" "}
        <NavLink to="/dashboard/overview">dashboard</NavLink>{" "}
        {localization.to_activate_this_plugin}
      </>
    ),
  };

  const handleDeleteConfig = async (
    showLoader: boolean | null = true
  ): Promise<boolean> => {
    if (showLoader) {
      setIsDeletingConfig(true);
    }
    const resetResp = await resetPlugin();

    setIsDeletingConfig(false);
    if (resetResp?.error) {
      return false;
    }
    setConcealedKey("");
    setChangeVerifyState(true);
    setInitialSettings({
      ...initialSettings,
      config_list: {},
      selected_config: "",
      api_key: "",
      api_key_verified: false,
    });
    handleModalClose();
    return true;
  };

  const handleEditClick = (id: string) => () => {
    navigate(`/configuration/${id}`);
  };

  const handleModalClose = () => {
    setIsOpenDeleteConfigModal(false);
  };

  const getMenuOptions = (id: string): MenuOption[] => [
    {
      label: localization.edit,
      icon: EditIcon,
      onClick: handleEditClick(id),
    },
  ];

  const configSectionProps: { [key: string]: any } = {
    "api-key-verification": {
      key: "api-key-verification",
      sectionID: "api-key-verification",
    },
  };

  const configSectionContent: { [key: string]: any[] } = {
    "api-key-verification": [
      <div className="configuration-api-key-container">
        {" "}
        <div className="configuration-api-key">
          <div className="configuration-api-key-verification">
            {" "}
            <InputField
              containerID="configuration-api-key-input"
              name="api-key"
              value={concealedKey}
              onChange={(name, value) => {
                setConcealedKey(value);
                setApiKey(value);
                setVerifyResult(false);
              }}
              disabled={
                initialSettings.api_key !== undefined &&
                initialSettings.api_key !== "" &&
                !changeVerifyState
              }
            />
            {!changeVerifyState &&
              initialSettings.api_key !== undefined &&
              initialSettings.api_key.trim() !== "" &&
              showCheck && (
                <div className="configuration-checkIcon">{CheckCircleIcon}</div>
              )}
            {verifyResult && !showCheck && (
              <div className="configuration-checkIcon">{CancelIcon}</div>
            )}
          </div>

          <div className="configuration-buttonIcon-container">
            {changeVerifyState || initialSettings.api_key == undefined ? (
              <Button
                text={"Verify"}
                onClickHandler={() => handleVerifyAPI(false)}
                id="configuration-verifyButton"
                variant="ghost"
                isLoading={isVerifyingAPIKey}
                disabled={concealedKey === "" || isVerifyingAPIKey}
              />
            ) : (
              verifyResult &&
              !showCheck && (
                <Button
                  text={"Change"}
                  id="configuration-verifyButton"
                  variant="ghost"
                  onClickHandler={() => {
                    setChangeVerifyState(true);
                    setVerifyResult(false);
                    setConcealedKey("");
                  }}
                />
              )
            )}
          </div>
        </div>
        {(changeVerifyState ||
          initialSettings.api_key == undefined ||
          isVerifyingAPIKey) && (
          <a
            onClick={() => {
              navigateToDashboard(true);
            }}
            rel="noopener noreferrer"
            className="configuration-api-key-link"
          >
            {localization.get_your_api_key_here}
          </a>
        )}
      </div>,
    ],
  };

  return (
    <React.Fragment>
      <CardHeader {...headerProps} />

      <CardContent>
        <>
          {Object.keys(configSectionProps).map((key: string) => (
            <CardSection {...configSectionProps[key]}>
              {configSectionContent[key]}
            </CardSection>
          ))}
        </>
      </CardContent>
      {initialSettings.api_key && (
        <CardFooter>
          <Button
            isDestructive
            text={
              isDeletingConfig
                ? localization.resetting_plugin
                : localization.reset_plugin
            }
            variant="tertiary"
            onClickHandler={() => setIsOpenDeleteConfigModal(true)}
            disabled={isDeletingConfig}
          />
        </CardFooter>
      )}
      <Modal
        isOpen={isOpenDeleteConfigModal}
        onClose={() => setIsOpenDeleteConfigModal(false)}
        title={localization.reset_plugin}
        modalActions={[
          {
            text: localization.reset,
            type: "button",
            isDestructive: true,
            isLoading: isDeletingConfig,
            onClickHandler: () => handleDeleteConfig(true),
            disabled: isDeletingConfig,
          },
          {
            text: localization.cancel,
            variant: "secondary",
            type: "button",
            onClickHandler: () => setIsOpenDeleteConfigModal(false),
          },
        ]}
      >
        <p className="sfsyncGridManager-modalDescription">
          {localization.reset_plugin_modal}
        </p>
      </Modal>
    </React.Fragment>
  );
};

export default ConfigurationList;
