/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { AutoComplete, Button, Col, Drawer, Form, notification, Row } from 'antd';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useIntl } from 'umi';

import { transformLabelValueToKeyValue } from '../../helpers';

type Props = {
  title?: string;
  actionName: string;
  dataSource: string[];
  filterList?: string[];
  fetchLabelList: any;
  disabled: boolean;
  onClose: () => void;
} & Pick<RouteModule.Step1PassProps, 'onChange'>;

const LabelList = (disabled: boolean, labelList: LabelList, filterList: string[] = []) => {
  const { formatMessage } = useIntl();

  const keyOptions = useMemo(
    () =>
      Object.keys(labelList || {})
        .filter((item) => !filterList.includes(item))
        .map((item) => ({ value: item })),
    [labelList, filterList],
  );

  return (
    <Form.List name="labels">
      {(fields, { add, remove }) => {
        return (
          <>
            {fields.map((field, index) => (
              <Form.Item
                key={field.key}
                label={index === 0 && 'Label'}
                labelCol={{ span: index === 0 ? 3 : 0 }}
                wrapperCol={{ offset: index === 0 ? 0 : 3 }}
              >
                <Row style={{ marginBottom: 10 }} gutter={16}>
                  <Col>
                    <Form.Item
                      style={{ marginBottom: 0 }}
                      name={[field.name, 'labelKey']}
                      rules={[
                        {
                          required: true,
                          message: 'Please input key',
                        },
                      ]}
                    >
                      <AutoComplete options={keyOptions} style={{ width: 100 }} />
                    </Form.Item>
                  </Col>
                  <Col>
                    <Form.Item shouldUpdate noStyle>
                      {({ getFieldValue }) => {
                        const key = getFieldValue(['labels', field.name, 'labelKey']);
                        let valueOptions = [{ value: '' }];
                        if (labelList) {
                          valueOptions = (labelList[key] || []).map((item) => ({ value: item }));
                        }

                        return (
                          <Form.Item
                            noStyle
                            name={[field.name, 'labelValue']}
                            fieldKey={[field.fieldKey, 'labelValue']}
                            rules={[
                              {
                                required: true,
                                message: 'Please input value',
                              },
                            ]}
                          >
                            <AutoComplete options={valueOptions} style={{ width: 100 }} />
                          </Form.Item>
                        );
                      }}
                    </Form.Item>
                  </Col>
                  <Col>
                    {!disabled && <MinusCircleOutlined onClick={() => remove(field.name)} />}
                  </Col>
                </Row>
              </Form.Item>
            ))}
            {!disabled && (
              <Form.Item wrapperCol={{ offset: 3 }}>
                <Button type="dashed" onClick={add}>
                  <PlusOutlined />
                  {formatMessage({ id: 'component.global.add' })}
                </Button>
              </Form.Item>
            )}
          </>
        );
      }}
    </Form.List>
  );
};

const LabelsDrawer: React.FC<Props> = ({
  title = '',
  actionName = '',
  disabled = false,
  dataSource = [],
  filterList = [],
  fetchLabelList,
  onClose,
  onChange = () => {},
}) => {
  const { formatMessage } = useIntl();
  const [form] = Form.useForm();
  const [labelList, setLabelList] = useState<LabelList>();

  useEffect(() => {
    fetchLabelList().then(setLabelList);
  }, []);

  useEffect(() => {
    const transformLabel = transformLabelValueToKeyValue(dataSource);
    form.setFieldsValue({ labels: transformLabel });
  }, [form.setFieldsValue, dataSource]);

  const onClick: React.MouseEventHandler<HTMLElement> = useCallback(
    function onClick(e) {
      e.persist();
      form.validateFields().then(({ labels }) => {
        const data = labels.map((item: any) => `${item.labelKey}:${item.labelValue}`);
        // check for duplicates
        if (new Set(data).size !== data.length) {
          notification.warning({
            message: `Config Error`,
            description: 'Please do not enter duplicate labels',
          });
          return;
        }

        onChange({
          action: actionName,
          data,
        });
        onClose();
      });
    },
    [form, actionName, onChange, onClose],
  );

  return (
    <Drawer
      title={title || formatMessage({ id: 'component.label-manager' })}
      placement="right"
      width={512}
      visible
      closable
      onClose={onClose}
      maskClosable={false}
      footer={
        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
          <Button onClick={onClose}>{formatMessage({ id: 'component.global.cancel' })}</Button>
          <Button type="primary" style={{ marginRight: 8, marginLeft: 8 }} onClick={onClick}>
            {formatMessage({ id: 'component.global.confirm' })}
          </Button>
        </div>
      }
    >
      <Form form={form} layout="horizontal">
        {LabelList(disabled, labelList || {}, filterList)}
      </Form>
    </Drawer>
  );
};

export default LabelsDrawer;
