import { useStore } from 'stores/StoreProvider';
import { useEffect, useMemo, useState } from 'react';
import { observer } from 'mobx-react-lite';
import {
  Button,
  Card,
  Checkbox,
  Col,
  Form,
  Input,
  Row,
  Spin,
  Tooltip,
  Upload,
} from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { useSettingsMessages } from './i18n';
import { validationUploads } from './validation';
import {
  openNotificationError,
  openNotificationSuccess,
} from 'components/Messages';

type TFileLists = {
  certificate: undefined | string;
  key: undefined | string;
};

export const TlsCertificate = observer((): JSX.Element => {
  const [form] = Form.useForm();
  const translations = useSettingsMessages();
  const [fileLists, setFileLists] = useState<TFileLists>({
    certificate: undefined,
    key: undefined,
  });
  const [disabledSaveButton, setDisabledSaveButton] = useState<boolean>(false);

  const [fileListCert, setFileListCert] = useState<any[]>([]);
  const [textTooltip, setTextTooltip] = useState<string>('');

  const file = useMemo(() => new FormData(), []);

  const {
    getSettingsTls,
    postSettingsTls,
    settingsTlsObject,
    patchSettingsTls,
    deleteCerts,
    loading,
  } = useStore().settingsUiStore;

  useEffect(() => {
    form.validateFields();
  }, [fileLists]);

  useEffect(() => {
    if (settingsTlsObject?.key && settingsTlsObject.certificate) {
      setDisabledSaveButton(false);
      setTextTooltip('');
    }
    if (
      (fileLists.key && !fileLists.certificate) ||
      (!fileLists.key && fileLists.certificate)
    ) {
      setTextTooltip(translations.notification.tooltipCancelButtonUpload);
      setDisabledSaveButton(true);
    }
    if (fileLists.key && fileLists.certificate) {
      setDisabledSaveButton(false);
      setTextTooltip('');
    }
    if (
      !fileLists.key &&
      !fileLists.certificate &&
      !settingsTlsObject?.key &&
      !settingsTlsObject?.certificate
    ) {
      setDisabledSaveButton(true);
      setTextTooltip(
        translations.notification.tooltipCancelButtonUploadOrCreateNew,
      );
    }
  }, [fileLists, settingsTlsObject]);

  useEffect(() => {
    getSettingsTls();
  }, []);

  useEffect(() => {
    if (settingsTlsObject)
      form.setFieldsValue({ enabled: settingsTlsObject.enabled });
  }, [settingsTlsObject]);

  const onFinish = async (values: any): Promise<void> => {
    await file.append('enabled', form.getFieldValue('enabled'));
    patchSettingsTls(file).then(() => {
      setFileLists({ certificate: undefined, key: undefined });
      openNotificationSuccess({
        messageTitle: translations.notification.savedSuccess,
      });
    });
  };

  const deleteCertificate = async (): Promise<void> => {
    await deleteCerts().then(() => {
      openNotificationSuccess({
        messageTitle: translations.notification.tslDeleted,
      });
    });
  };

  const uploadFile = async (value: any, key: string): Promise<void> => {
    await file.append(key, value.file);
  };

  const createNewCert = (): void => {
    postSettingsTls().then(() => {
      openNotificationSuccess({
        messageTitle: translations.notification.tslCreateNew,
      });
    });
  };

  const handleCancel = (): void => {
    setFileLists({
      certificate: undefined,
      key: undefined,
    });
    file.delete('certificate');
    file.delete('key');
    form.setFieldsValue({ enabled: settingsTlsObject?.enabled });
  };

  const onChangeUploadCert = (fileUpload: any): void => {
    const splittedName = fileUpload.file.name.split('.');
    if (splittedName[splittedName.length - 1] !== 'crt') {
      openNotificationError({
        messageTitle: translations.notification.wrongFormatTitle,
        messageDescription:
          translations.notification.wrongFormatDescriptionCert,
      });
      setFileListCert([]);
    } else
      setFileLists((prevState) => ({
        ...prevState,
        certificate: fileUpload.file.name,
      }));
  };
  const onChangeUploadKey = (fileUpload: any): void => {
    const splittedName = fileUpload.file.name.split('.');
    if (splittedName[splittedName.length - 1] !== 'key') {
      openNotificationError({
        messageTitle: translations.notification.wrongFormatTitle,
        messageDescription: translations.notification.wrongFormatDescriptionKey,
      });
      setFileListCert([]);
    } else
      setFileLists((prevState) => ({
        ...prevState,
        key: fileUpload.file.name,
      }));
  };
  const content = loading ? (
    <Spin />
  ) : (
    <Card
      style={{ borderLeft: 0 }}
      title={
        <div style={{ marginRight: '30px', width: '100%' }}>
          <span>{translations.tls.cardTitleTls}</span>
        </div>
      }
      extra={
        <div style={{ float: 'right' }}>
          <Button onClick={createNewCert} type="primary">
            {translations.button.createNew}
          </Button>
          &nbsp;
          {!settingsTlsObject?.certificate && !settingsTlsObject?.key ? null : (
            <Button onClick={deleteCertificate} type="primary">
              {translations.button.delete}
            </Button>
          )}
        </div>
      }
    >
      <Form layout="vertical" form={form} onFinish={onFinish}>
        <Form.Item key="enabled" name="enabled" valuePropName="checked">
          <Checkbox>{translations.tls.enabledTls}</Checkbox>
        </Form.Item>
        <Row gutter={[12, 12]}>
          <Col className="gutter-row" span={12}>
            <Form.Item
              label={translations.tls.certificate}
              key="certificate"
              name="certificate"
              extra={translations.tls.crtExtra}
              rules={[
                () => ({
                  async validator(_) {
                    await validationUploads(
                      _,
                      fileLists,
                      translations.validation,
                    );
                  },
                }),
              ]}
            >
              <span>{translations.tls.atTheMoment}</span>
              {settingsTlsObject?.certificate ? (
                <a href={settingsTlsObject?.certificate}>certificate.crt</a>
              ) : (
                <span>{translations.tls.certNotUse}</span>
              )}
              <br />
              <span>{translations.tls.edit}</span>
              <br />
              <div style={{ display: 'flex' }}>
                <Input
                  placeholder={translations.tls.selectFile}
                  value={fileLists.certificate}
                  disabled
                />
                <Upload
                  fileList={fileListCert}
                  showUploadList={false}
                  onChange={onChangeUploadCert}
                  customRequest={(value) => uploadFile(value, 'certificate')}
                >
                  <Button icon={<UploadOutlined />}>
                    {translations.tls.review}
                  </Button>
                </Upload>
              </div>
            </Form.Item>
          </Col>
          <Col className="gutter-row" span={12}>
            <Form.Item
              label={translations.tls.key}
              key="key"
              name="key"
              extra={translations.tls.keyExtra}
              rules={[
                () => ({
                  async validator(_) {
                    await validationUploads(
                      _,
                      fileLists,
                      translations.validation,
                    );
                  },
                }),
              ]}
            >
              <span>{translations.tls.atTheMoment}</span>

              {settingsTlsObject?.key ? (
                <a href={settingsTlsObject?.key}>certificate.key</a>
              ) : (
                <span>{translations.tls.keyNotUse}</span>
              )}
              <br />
              <span>{translations.tls.edit}</span>
              <br />
              <div style={{ display: 'flex' }}>
                <Input
                  placeholder={translations.tls.selectFile}
                  disabled
                  value={fileLists.key}
                />
                <Upload
                  showUploadList={false}
                  onChange={onChangeUploadKey}
                  customRequest={(value) => uploadFile(value, 'key')}
                >
                  <Button icon={<UploadOutlined />}>
                    {translations.tls.review}
                  </Button>
                </Upload>
              </div>
            </Form.Item>
          </Col>
        </Row>
        <Form.Item key="submitButton">
          {fileLists.key || fileLists.certificate ? (
            <Button onClick={handleCancel}>{translations.button.cancel}</Button>
          ) : null}
          &nbsp;
          <Tooltip title={textTooltip}>
            <Button
              disabled={disabledSaveButton}
              htmlType="submit"
              type="primary"
            >
              {translations.button.save}
            </Button>
          </Tooltip>
        </Form.Item>
      </Form>
    </Card>
  );
  return loading ? <Spin className="spinnerGlobal">{content}</Spin> : content;
});
