// Apps
import { Button, Collapse, Form, Select } from 'antd';
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { useStore } from 'stores/StoreProvider';
import {
  NCIRCCNotificationSendConfig,
  NCIRCCNotificationShowConfig,
} from './helpers';
import { useIncidentDashboardMessage } from '../i18n';
import { OPTIONS_NCIRCC_NOTIFICATION, typeCategory } from './constants';
import {
  openNotificationError,
  openNotificationSuccess,
} from 'components/Messages';

// Types
import { RootStore } from 'stores/RootStore';
import {
  NCIRCCNotificationUpdateIncidentAttack,
  NCIRCCNotificationUpdateVulnerability,
  NCIRCCNotifictionRetrive,
  NotificationCategoryEnum,
} from 'myApi';
import { FormFields, TypeCategory } from './types';

import styles from './NCIRCCNotificationForm.module.scss';
import { CardInfoDrawer } from 'components/Modals/CardInfoDrawer/CardInfoDrawer';
import { observer } from 'mobx-react-lite';
import { TypeNCIRCCStatusButtonText } from '../IncidentsCardInfo/types';

// Constants
const { Option } = Select;
const { Panel } = Collapse;
const { Item } = Form;
const DASH = '-------';

export const NCIRCCNotificationForm: FC = observer(() => {
  // Stores
  const rootStore: RootStore = useStore();
  const ncirccStore = rootStore.ncirccStore;
  const incidentsUiStore = rootStore.incidentsUiStore;

  const { incidentById } = incidentsUiStore;

  const [form] = Form.useForm();

  const formItemLayout = {
    labelCol: { span: 10 },
    wrapperCol: { span: 120 },
  };

  const { ncircc } = useIncidentDashboardMessage();

  // States
  const [selectOptionTypeCategory, setSelectOptionTypeCategory] = useState<
    TypeCategory | typeof DASH
  >(DASH);

  const [isDisablesAfterSubmit, setIsDisablesAfterSubmit] =
    useState<boolean>(false);

  const onCategoryNotificationChange = (value: TypeCategory): void => {
    setSelectOptionTypeCategory(value);
  };

  useEffect(() => {
    if (ncirccStore.notification === null) {
      setSelectOptionTypeCategory(DASH);
      form.resetFields();
    }
  }, [form, ncirccStore.notification]);

  const setFormFieldsValue = useCallback(
    (data): void => {
      form.setFieldsValue(data);
    },
    [form],
  );

  const onFinish = async (): Promise<void> => {
    const fields = form.getFieldsValue();
    if (incidentById?.notification_id) {
      const preparePatchData:
        | NCIRCCNotificationUpdateIncidentAttack
        | NCIRCCNotificationUpdateVulnerability =
        selectOptionTypeCategory === '0' || selectOptionTypeCategory === '1'
          ? {
              activity_status: fields.activity_status,
              affected_system_connection: fields.affected_system_connection,
              event_description: fields.event_description,
              integrity_impact: fields.integrity_impact,
              availability_impact: fields.availability_impact,
              confidentiality_impact: fields.confidentiality_impact,
              custom_impact: fields.custom_impact,
              type: fields.type,
              category: fields.category,
            }
          : {
              activity_status: fields.activity_status,
              affected_system_connection: fields.affected_system_connection,
              event_description: fields.event_description,
              vulnerability_id: fields.vulnerability_id,
              product_category: fields.product_category,
              type: fields.type,
              category: fields.category,
            };
      try {
        // Изменение уведомления если требуется дополнение
        await ncirccStore.patchNotification(
          incidentById?.notification_id,
          preparePatchData,
        );
        openNotificationSuccess({
          messageTitle: ncircc.notification.patchNotification.success.title,
        });
        setIsDisablesAfterSubmit(true);
      } catch (e) {
        openNotificationError({
          messageTitle: ncircc.notification.patchNotification.error.title,
          messageDescription:
            ncircc.notification.patchNotification.error.subTitle,
        });
      }
    } else {
      try {
        const preparePostData: NCIRCCNotifictionRetrive = {
          ...fields,
          category: typeCategory[selectOptionTypeCategory as TypeCategory],
          incident: incidentById?.incident_id,
          tlp: fields.tlp,
        };
        await ncirccStore.postNotification(preparePostData);
        ncirccStore.setIsAdditionNotification(TypeNCIRCCStatusButtonText.Show);
        openNotificationSuccess({
          messageTitle: ncircc.notification.postNotification.success.title,
        });
        setIsDisablesAfterSubmit(true);
      } catch (e) {
        openNotificationError({
          messageTitle: ncircc.notification.postNotification.error.subTitle,
          messageDescription:
            ncircc.notification.postNotification.error.subTitle,
        });
      }
    }
  };

  const isSubmitDisabled = (): boolean => {
    return !!(
      selectOptionTypeCategory === DASH ||
      (ncirccStore.notification &&
        ncirccStore.isAdditionNotification !==
          TypeNCIRCCStatusButtonText.Addition)
    );
  };

  const renderNotificationCategory = useMemo((): JSX.Element[] | null => {
    if (selectOptionTypeCategory === DASH) {
      return null;
    } else if (!ncirccStore.notification) {
      return NCIRCCNotificationSendConfig(
        ncircc,
        selectOptionTypeCategory as TypeCategory,
        isDisablesAfterSubmit,
      ).map(({ jsxElem, type, collapsedItems, ...items }) =>
        type && type === 'collapsed' ? (
          <Collapse ghost className={styles['custom-collapse-panel']}>
            <Panel
              header={
                <span className={styles['custom-collapse-panel-label']}>
                  {items.label}
                </span>
              }
              key="1"
            >
              {collapsedItems?.map(({ jsxElem: jsx, ...elems }) => {
                return <Item {...elems}>{jsx}</Item>;
              })}
            </Panel>
          </Collapse>
        ) : (
          <Item {...items}>{jsxElem}</Item>
        ),
      );
    } else {
      return NCIRCCNotificationShowConfig(
        ncircc,
        ncirccStore.isAdditionNotification !==
          TypeNCIRCCStatusButtonText.Addition || isDisablesAfterSubmit,
        selectOptionTypeCategory as TypeCategory,
      ).map(({ jsxElem, ...items }) => <Item {...items}>{jsxElem}</Item>);
    }
  }, [
    isDisablesAfterSubmit,
    ncircc,
    ncirccStore.isAdditionNotification,
    ncirccStore.notification,
    selectOptionTypeCategory,
  ]);

  useEffect(() => {
    if (ncirccStore.notification) {
      const data = ncirccStore.notification;
      switch (data.category) {
        case NotificationCategoryEnum.TypeУведомлениеОКомпьютерномИнциденте:
        case NotificationCategoryEnum.TypeУведомлениеОКомпьютернойАтаке:
          setSelectOptionTypeCategory(
            data.category === 'Уведомление о компьютерном инциденте'
              ? '0'
              : '1',
          );
          setFormFieldsValue({
            category: data.category,
            type: data.type,
            tlp: data.tlp,
            identifier: data.identifier,
            activity_status: data.activity_status,
            affected_system_name: data.affected_system_name,
            affected_system_category: data.affected_system_category,
            event_description: data.event_description,
            affected_system_connection: data.affected_system_connection,
            assistance: data.assistance,
            notification_status: data.notification_status,
            integrity_impact: data.integrity_impact,
            availability_impact: data.availability_impact,
            confidentiality_impact: data.confidentiality_impact,
            custom_impact: data.custom_impact,
          });
          break;
        case 'Уведомление о наличии уязвимости':
          setSelectOptionTypeCategory('2');
          setFormFieldsValue({
            category: data.category,
            identifier: data.identifier,
            type: data.type,
            activity_status: data.activity_status,
            tlp: data.tlp,
            affected_system_name: data.affected_system_name,
            affected_system_category: data.affected_system_category,
            event_description: data.event_description,
            affected_system_connection: data.affected_system_connection,
            assistance: data.assistance,
            notification_status: data.notification_status,
            vulnerability_id: data.vulnerability_id,
            product_category: data.product_category,
          });
      }
    } else {
      form.resetFields();
      switch (selectOptionTypeCategory) {
        case '0':
          setFormFieldsValue({
            category: selectOptionTypeCategory,
            [FormFields.TYPE]:
              'Вовлечение контролируемого ресурса в инфраструктуру ВПО',
            [FormFields.TLP]: 'TLP:GREEN',
            [FormFields.ACTIVITY_STATUS]: 'Меры приняты',
            [FormFields.AFFECTED_SYSTEM_NAME]: '',
            [FormFields.AFFECTED_SYSTEM_CATEGORY]:
              'Информационный ресурс не является объектом КИИ',
            [FormFields.EVENT_DESCRIPTION]: '',
            [FormFields.AFFECTED_SYSTEM_CONNECTION]: false,
            [FormFields.ASSISTANCE]: false,
            [FormFields.INTEGRITY_IMPACT]: 'Отсутствует',
            [FormFields.AVAILABILITY_IMPACT]: 'Отсутствует',
            [FormFields.CONFIDENTIALITY_IMPACT]: 'Отсутствует',
            [FormFields.CUSTOM_IMPACT]: '',
          });

          break;
        case '1':
          setFormFieldsValue({
            category: selectOptionTypeCategory,
            [FormFields.TYPE]: 'DDoS-атака',
            [FormFields.TLP]: 'TLP:GREEN',
            [FormFields.ACTIVITY_STATUS]: 'Меры приняты',
            [FormFields.AFFECTED_SYSTEM_NAME]: '',
            [FormFields.AFFECTED_SYSTEM_CATEGORY]:
              'Информационный ресурс не является объектом КИИ',
            [FormFields.EVENT_DESCRIPTION]: '',
            [FormFields.AFFECTED_SYSTEM_CONNECTION]: false,
            [FormFields.ASSISTANCE]: false,
            [FormFields.INTEGRITY_IMPACT]: 'Отсутствует',
            [FormFields.AVAILABILITY_IMPACT]: 'Отсутствует',
            [FormFields.CONFIDENTIALITY_IMPACT]: 'Отсутствует',
            [FormFields.CUSTOM_IMPACT]: '',
          });

          break;
        case '2':
          setFormFieldsValue({
            category: selectOptionTypeCategory,
            [FormFields.TYPE]: 'Уязвимый ресурс',
            [FormFields.TLP]: 'TLP:GREEN',
            [FormFields.ACTIVITY_STATUS]: 'Меры приняты',
            [FormFields.AFFECTED_SYSTEM_NAME]: '',
            [FormFields.AFFECTED_SYSTEM_CATEGORY]:
              'Информационный ресурс не является объектом КИИ',
            [FormFields.EVENT_DESCRIPTION]: '',
            [FormFields.AFFECTED_SYSTEM_CONNECTION]: false,
            [FormFields.ASSISTANCE]: false,
            [FormFields.VULNERABILITY_ID]: '',
            [FormFields.PRODUCT_CATEGORY]: '',
          });
      }
    }
  }, [
    selectOptionTypeCategory,
    incidentById?.notification_id,
    setFormFieldsValue,
    ncirccStore,
    ncirccStore.notification,
    form,
  ]);

  const onCloseCard = async (): Promise<void> => {
    incidentsUiStore.setNcirccNotificationCard(undefined);
    setIsDisablesAfterSubmit(false);
    setSelectOptionTypeCategory(DASH);
  };

  return (
    <CardInfoDrawer
      title={ncircc.title}
      cardSize={incidentsUiStore.ncirccNotificationCardSize}
      onCloseCard={onCloseCard}
      drawerFooter={null}
    >
      <Form
        form={form}
        name="ncircc_notification"
        onFinish={onFinish}
        labelAlign="left"
        colon={false}
        className={styles['customForm']}
        {...formItemLayout}
      >
        <Item
          style={{ width: '100%' }}
          name="category"
          label={ncircc.formFieldsMessages[FormFields.CATEGORY]}
          rules={[{ required: true, message: 'Выберите тип категории' }]}
        >
          <Select
            style={{ width: '100%' }}
            onChange={onCategoryNotificationChange}
            disabled={!!ncirccStore.notification || isDisablesAfterSubmit}
            placeholder={DASH}
          >
            {OPTIONS_NCIRCC_NOTIFICATION(
              ncircc.formOptionsLabelMessages.optionsNcirccNotificationMessages,
            ).map((notification) => (
              <Option key={notification.value}>{notification.label}</Option>
            ))}
          </Select>
        </Item>

        {renderNotificationCategory}
        <Button
          type="primary"
          htmlType="submit"
          disabled={isSubmitDisabled() || isDisablesAfterSubmit}
        >
          {ncircc.submit}
        </Button>
      </Form>
    </CardInfoDrawer>
  );
});
