// Libs
// -----------------------------------------------------------------------------
import React, { ComponentType, FC, Fragment } from 'react';
import { Button, Dropdown, Form, Menu, FormInstance, Popconfirm } from 'antd';
import { DownOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';

// App
// -----------------------------------------------------------------------------
import { useStore } from 'stores/StoreProvider';
import { FormFieldsBlock } from 'components';
import {
  CorrelationRulesRecord,
  CorrelationRulesActionRecord,
} from 'types/default';
import { makeNewCorrelationRuleAction } from './makeNewCorrelationRuleAction';
import {
  BashActionForm,
  HttpActionForm,
  SyslogActionForm,
  AssetActionForm,
  IncidentActionForm,
  ExecActionForm,
  FirewallActionForm,
} from './actionForms';
import { useCorrelationRulesTemplateMessages } from '../i18n';
import { RootStore } from 'stores/RootStore';
import { CommonActionFormProps } from './actionForms/CommonActionFormProps';

// Props
// -----------------------------------------------------------------------------
type CorrelationRulesActionsEditorProps = {
  form: FormInstance<CorrelationRulesRecord>;
};

export const CorrelationRulesActionsEditor: FC<
  CorrelationRulesActionsEditorProps
> = ({ form }) => {
  const rootStore: RootStore = useStore();
  const pageStore = rootStore.correlationRulesUiStore;

  const locale = useCorrelationRulesTemplateMessages();
  const actionCreationMenuLabels =
    locale.actionsRuleMessage.generalSelectMessage;

  const actionCreationMenuItems: Array<{
    key: CorrelationRulesActionRecord['type'];
    label: string;
    disabled?: boolean;
  }> = [
    { key: 'bash', label: actionCreationMenuLabels.bash },
    { key: 'syslog', label: actionCreationMenuLabels.sysLog },
    {
      key: 'incident',
      label: actionCreationMenuLabels.incident,
    },
    { key: 'http', label: actionCreationMenuLabels.http },
    {
      key: 'exec',
      label: actionCreationMenuLabels.runExecutableFile,
    },
    {
      key: 'asset',
      label: actionCreationMenuLabels.newAssets,
    },
    {
      key: 'firewall',
      label: actionCreationMenuLabels.fireWall,
    },
  ];

  const actionTitles: Record<CorrelationRulesActionRecord['type'], string> = {
    bash: actionCreationMenuLabels.bash,
    syslog: actionCreationMenuLabels.sysLog,
    incident: actionCreationMenuLabels.incident,
    http: actionCreationMenuLabels.http,
    exec: actionCreationMenuLabels.runExecutableFile,
    asset: actionCreationMenuLabels.newAssets,
    firewall: actionCreationMenuLabels.fireWall,
  };

  const actionForms: Record<
    CorrelationRulesActionRecord['type'],
    ComponentType<CommonActionFormProps>
  > = {
    bash: BashActionForm,
    syslog: SyslogActionForm,
    incident: IncidentActionForm,
    http: HttpActionForm,
    exec: ExecActionForm,
    asset: AssetActionForm,
    firewall: FirewallActionForm,
  };

  return (
    <Form.List
      name="actions_json"
      rules={[
        {
          validator: async (_, names) => {
            if (!names.length) {
              return Promise.reject();
            }
          },
        },
      ]}
    >
      {(fields, { add, remove }) => (
        <FormFieldsBlock
          title={locale.actionsRuleMessage.title}
          headerExtra={
            <Dropdown
              overlay={
                <Menu
                  items={actionCreationMenuItems}
                  onClick={({ key }) => {
                    add(
                      makeNewCorrelationRuleAction(
                        key as CorrelationRulesActionRecord['type'],
                      ),
                    );
                  }}
                />
              }
              disabled={pageStore.isFormDisabled}
            >
              <Button icon={<PlusOutlined />}>
                {locale.actionsRuleMessage.add} <DownOutlined />
              </Button>
            </Dropdown>
          }
        >
          {fields.length > 0 ? (
            fields.map(({ key, name }, index) => {
              const action: CorrelationRulesActionRecord = form.getFieldValue([
                'actions_json',
                name,
              ]);

              const actionFormProps = {
                form,
                name,
                isDisabled: pageStore.isFormDisabled,
                cardSize: pageStore.cardSize,
              };

              const FormComponent = actionForms[action.type];

              return (
                <Fragment key={key}>
                  <FormFieldsBlock.SubBlock
                    title={actionTitles[action.type]}
                    headerExtra={
                      <Popconfirm
                        title={locale.actionsRuleMessage.deleteConfirm}
                        onConfirm={() => {
                          remove(name);
                        }}
                        okText={locale.actionsRuleMessage.deleteOk}
                        cancelText={locale.actionsRuleMessage.deleteCancel}
                        disabled={pageStore.isFormDisabled}
                        placement="bottomRight"
                      >
                        <Button
                          icon={<DeleteOutlined />}
                          type="text"
                          disabled={pageStore.isFormDisabled}
                          title={locale.actionsRuleMessage.deleteAction}
                          size="small"
                        />
                      </Popconfirm>
                    }
                  >
                    <FormComponent {...actionFormProps} />
                  </FormFieldsBlock.SubBlock>

                  {index < fields.length - 1 ? (
                    <FormFieldsBlock.Divider />
                  ) : null}
                </Fragment>
              );
            })
          ) : (
            <div style={{ color: 'red' }}>
              {locale.actionsRuleMessage.mustSelectActions}
            </div>
          )}
        </FormFieldsBlock>
      )}
    </Form.List>
  );
};
