import { Button, Flex, Form, Input, Modal } from "antd";
import HeaderBar from "core/components/Header";
import MyBanner from "shared/components/MyBanner";
import { SaveOutlined } from "@ant-design/icons";
import MyUpload from "shared/components/MyUpload";
import { Constants } from "core/utils/utils";
import ColorPicker from "antd/es/color-picker";
import {
  useGetOrganizationSettingsQuery,
  useIsSubdomainAvailableMutation,
  useUpdateOrganizationSettingsMutation,
  useUpdateSubdomainMutation,
} from "core/services/organization";
import MyErrorResult from "shared/components/MyResult";
import { useForm } from "antd/es/form/Form";
import { useEffect, useRef, useState } from "react";
import { AggregationColor } from "antd/es/color-picker/color";
import { useDispatch, useSelector } from "react-redux";
import {
  bannerUrl,
  logoUrl,
  setBannerUrl,
  setLogoUrl,
  setPrimaryColor,
} from "core/reducers/appSlice";
import MyMiddleCard from "shared/components/MyMiddleCard";
import { OrganizationSettings } from "core/types/organization";
import { useMessage } from "core/context/MessageContext";
import {
  addWebSocketReconnectListener,
  removeWebSocketReconnectListener,
} from "core/services/websocketService";
import { useTranslation } from "react-i18next";

type GeneralFieldType = {
  primaryColor: string | AggregationColor;
  companyName: string;
};

export default function Settings() {
  const { t } = useTranslation();

  const { data, error, isLoading, refetch } = useGetOrganizationSettingsQuery(
    undefined,
    {
      refetchOnMountOrArgChange: true,
    }
  );

  useEffect(() => {
    addWebSocketReconnectListener(refetch);

    return () => removeWebSocketReconnectListener(refetch);
  }, []);

  if (error) return <MyErrorResult />;

  return (
    <>
      <MyBanner
        title={t("organizationSettings.bannerTitle")}
        subtitle={t("common.bannerSubtitle")}
        headerBar={<HeaderBar />}
      />

      <GeneralCard data={data} isLoading={isLoading} />

      <MediaCard isLoading={isLoading} />

      <SubdomainCard data={data} isLoading={isLoading} />
    </>
  );
}

function GeneralCard({
  data,
  isLoading,
}: { data?: OrganizationSettings; isLoading?: boolean } = {}) {
  const { t } = useTranslation();
  const [form] = useForm<GeneralFieldType>();
  const { success, error: errorMessage } = useMessage();

  const dispatch = useDispatch();
  const debounceRef = useRef<null | NodeJS.Timeout>(null);
  const currentPrimaryColor = useRef<string>();

  const [updateOrganizationSettings, { isLoading: isUpdateSettingsLoading }] =
    useUpdateOrganizationSettingsMutation();

  const handleSave = async (values: GeneralFieldType) => {
    const hexColor =
      typeof values.primaryColor === "string"
        ? values.primaryColor
        : values.primaryColor.toHexString().split("#")[1];

    try {
      await updateOrganizationSettings({
        primaryColor: hexColor,
        companyName: values.companyName,
      }).unwrap();

      currentPrimaryColor.current = hexColor;

      success(
        t("organizationSettings.generalCard.messageSettingsSuccessfullyUpdated")
      );
    } catch (error) {
      console.error(error);
      errorMessage(t("common.messageRequestFailed"));
    }
  };

  useEffect(() => {
    if (data) {
      form.setFieldsValue({
        primaryColor: data.PrimaryColor,
        companyName: data.CompanyName,
      });

      currentPrimaryColor.current = data.PrimaryColor;
    }
  }, [data]);

  useEffect(() => {
    return () => {
      dispatch(setPrimaryColor(currentPrimaryColor.current));

      if (debounceRef.current) {
        clearTimeout(debounceRef.current);
      }
    };
  }, []);

  return (
    <Form form={form} onFinish={handleSave} layout="vertical">
      <MyMiddleCard
        styles={{
          body: {
            padding: 16,
          },
        }}
        title={t("organizationSettings.generalCard.title")}
        loading={isLoading}
        extra={
          <Button
            icon={<SaveOutlined />}
            type="text"
            shape="circle"
            size="large"
            htmlType="submit"
            loading={isUpdateSettingsLoading}
          />
        }
      >
        <Flex wrap gap={12}>
          <Form.Item<GeneralFieldType>
            name="primaryColor"
            label={t("organizationSettings.generalCard.primaryColor")}
          >
            <ColorPicker
              size="small"
              showText
              onChange={(color: AggregationColor) => {
                if (debounceRef.current) {
                  clearTimeout(debounceRef.current);
                }

                debounceRef.current = setTimeout(() => {
                  dispatch(setPrimaryColor(color.toHexString().split("#")[1]));
                }, 600);
              }}
            />
          </Form.Item>

          <Form.Item<GeneralFieldType>
            name="companyName"
            label={t("organizationSettings.generalCard.companyName")}
          >
            <Input />
          </Form.Item>
        </Flex>
      </MyMiddleCard>
    </Form>
  );
}

function MediaCard({
  isLoading,
}: { data?: OrganizationSettings; isLoading?: boolean } = {}) {
  const { t } = useTranslation();
  const { success } = useMessage();
  const dispatch = useDispatch();

  const appLogoUrl = useSelector(logoUrl);
  const appBannerUrl = useSelector(bannerUrl);

  return (
    <Form layout="vertical">
      <MyMiddleCard
        title={t("organizationSettings.mediaCard.title")}
        loading={isLoading}
      >
        <Form.Item label={t("organizationSettings.mediaCard.logo")}>
          <MyUpload
            action="/organization/file/logo"
            onChange={(info) => {
              if (info.file.status === "done" && info.file.response.Data) {
                dispatch(setLogoUrl(info.file.response.Data));

                success(
                  t(
                    "organizationSettings.mediaCard.messageLogoSuccessfullyUpdated"
                  )
                );
              }
            }}
            imgCropProps={{
              aspect: 1 / 1,
              children: <></>,
            }}
          >
            <img
              src={`${Constants.STATIC_CONTENT_ADDRESS}/${
                appLogoUrl || Constants.DEMO_LOGO_URL
              }`}
              alt={t("organizationSettings.mediaCard.logo")}
              style={{
                width: 128,
                maxHeight: 128,
                padding: 4,
                borderRadius: 4,
                border: "1px solid #ddd",
              }}
            />
          </MyUpload>
        </Form.Item>

        <Form.Item label={t("organizationSettings.mediaCard.banner")}>
          <MyUpload
            action="/organization/file/banner"
            onChange={(info) => {
              if (info.file.status === "done" && info.file.response.Data) {
                dispatch(setBannerUrl(info.file.response.Data));

                success(
                  t(
                    "organizationSettings.mediaCard.messageBannerSuccessfullyUpdated"
                  )
                );
              }
            }}
            imgCropProps={{
              aspect: 22 / 9,
              children: <></>,
            }}
          >
            <img
              src={`${Constants.STATIC_CONTENT_ADDRESS}/${
                appBannerUrl || Constants.DEMO_BANNER_URL
              }`}
              alt={t("organizationSettings.mediaCard.banner")}
              style={{
                width: "100%",
                height: 228,
                objectFit: "cover",
                padding: 4,
                borderRadius: 4,
                border: "1px solid #ddd",
              }}
            />
          </MyUpload>
        </Form.Item>
      </MyMiddleCard>
    </Form>
  );
}

const subdomainPattern = /^[a-zA-Z0-9-]+$/;

function SubdomainCard({
  data,
  isLoading,
}: { data?: OrganizationSettings; isLoading?: boolean } = {}) {
  const { t } = useTranslation();
  const [form] = useForm();
  const { success, info } = useMessage();

  const [isModalOpen, setIsModalOpen] = useState(false);
  const [reqIsSubdomainAvailable] = useIsSubdomainAvailableMutation();
  const [reqUpdateSubdomain] = useUpdateSubdomainMutation();

  const validateSubdomain = async (rule: any, value: string) => {
    if (value) {
      if (
        value.length < Constants.GLOBALS.MIN_SUBDOMAIN_LENGTH ||
        value.length > Constants.GLOBALS.MAX_SUBDOMAIN_LENGTH ||
        !subdomainPattern.test(value)
      ) {
        return Promise.reject();
      }

      // Check if subdomain is current subdomain

      if (value === window.location.hostname.split(".")[0]) {
        return Promise.resolve();
      }

      try {
        const { data } = await reqIsSubdomainAvailable(value);

        if (!data.Available) {
          return Promise.reject(
            t("organizationSettings.subdomainCard.subdomainAlreadyTaken")
          );
        }

        return Promise.resolve();
      } catch (error) {
        return Promise.reject(
          t("organizationSettings.subdomainCard.subdomainAlreadyTaken")
        );
      }
    }

    return Promise.resolve();
  };

  useEffect(() => {
    if (data) {
      form.setFieldsValue({
        subdomain: data.Subdomain,
      });
    }
  }, [data]);

  return (
    <>
      <Modal
        title={t(
          "organizationSettings.subdomainCard.modalChangeSubdomain.title"
        )}
        open={isModalOpen}
        centered
        onCancel={() => setIsModalOpen(false)}
        okText={t("common.change")}
        onOk={async () => {
          try {
            await reqUpdateSubdomain(form.getFieldValue("subdomain"));

            success(
              t(
                "organizationSettings.subdomainCard.modalChangeSubdomain.messageSubdomainSuccessfullyUpdated"
              )
            );
            info(
              t(
                "organizationSettings.subdomainCard.modalChangeSubdomain.messageRedirect"
              )
            );
            /*
            window.location.href = `https://${form.getFieldValue(
              "subdomain"
            )}.${window.location.hostname.split(".").slice(1).join(".")}`; */
          } catch (error) {
            console.error(error);
          }
        }}
      >
        <p>
          {t("organizationSettings.subdomainCard.modalChangeSubdomain.message")}
        </p>
      </Modal>

      <Form form={form} layout="vertical" requiredMark={false}>
        <MyMiddleCard
          title={t("organizationSettings.subdomainCard.middleCardTitle")}
          loading={isLoading}
          extra={
            <Button
              icon={<SaveOutlined />}
              type="text"
              shape="circle"
              size="large"
              onClick={() => {
                form
                  .validateFields()
                  .then(() => setIsModalOpen(true))
                  .catch(() => {});
              }}
            />
          }
        >
          <Flex>
            <Form.Item
              name="subdomain"
              label={t("organizationSettings.subdomainCard.subdomain")}
              hasFeedback
              validateDebounce={300}
              rules={[
                {
                  required: true,
                  message: t(
                    "organizationSettings.subdomainCard.rules.required"
                  ),
                },
                {
                  pattern: subdomainPattern,
                  message: t("organizationSettings.subdomainCard.rules.valid"),
                },
                {
                  min: Constants.GLOBALS.MIN_SUBDOMAIN_LENGTH,
                  message: t(
                    "organizationSettings.subdomainCard.rules.minLength",
                    {
                      minLength: Constants.GLOBALS.MIN_SUBDOMAIN_LENGTH,
                    }
                  ),
                },
                {
                  max: Constants.GLOBALS.MAX_SUBDOMAIN_LENGTH,
                  message: t(
                    "organizationSettings.subdomainCard.rules.maxLength",
                    {
                      maxLength: Constants.GLOBALS.MAX_SUBDOMAIN_LENGTH,
                    }
                  ),
                },
                {
                  required: true,
                  validator: validateSubdomain,
                },
              ]}
            >
              <Input
                addonBefore="https://"
                addonAfter=". xx.de"
                maxLength={Constants.GLOBALS.MAX_SUBDOMAIN_LENGTH}
              />
            </Form.Item>
          </Flex>
        </MyMiddleCard>
      </Form>
    </>
  );
}
