import React from 'react';

import { ServiceLabels } from '@grafana/labels';
import { Button, Stack } from '@grafana/ui';
import { GENERIC_ERROR } from 'helpers/consts';
import { openErrorNotification } from 'helpers/helpers';

import { splitToGroups } from 'models/label/label.helpers';
import { components } from 'network/oncall-api/autogenerated-api.types';
import { useStore } from 'state/useStore';

interface RouteLabelsDisplayProps {
  labels: Array<components['schemas']['LabelPair']>;
  labelErrors: any;
  onChange: (value: Array<components['schemas']['LabelPair']>) => void;
}

const INPUT_WIDTH = 280;
const DUPLICATE_ERROR = 'Duplicate values are not allowed';

export const RouteLabelsDisplay: React.FC<RouteLabelsDisplayProps> = ({ labels, labelErrors, onChange }) => {
  const { labelsStore } = useStore();

  const onLabelAdd = () => {
    onChange([
      ...labels,
      {
        key: { id: undefined, name: undefined, prescribed: false },
        value: { id: undefined, name: undefined, prescribed: false },
      },
    ]);
  };

  const onLoadKeys = async (search?: string) => {
    const result = await labelsStore.loadKeys(search);
    return splitToGroups(result);
  };

  const onLoadValuesForKey = async (key: string, search?: string) => {
    if (!key) {
      return [];
    }

    const { values } = await labelsStore.loadValuesForKey(key, search);
    return splitToGroups(values);
  };

  return (
    <Stack direction="column">
      <ServiceLabels
        isAddingDisabled
        loadById
        inputWidth={INPUT_WIDTH}
        errors={labelErrors}
        value={labels}
        onLoadKeys={onLoadKeys}
        onLoadValuesForKey={onLoadValuesForKey}
        onCreateKey={labelsStore.createKey}
        onUpdateKey={labelsStore.updateKey}
        onCreateValue={labelsStore.createValue}
        onUpdateValue={labelsStore.updateKeyValue}
        onUpdateError={(res) => {
          if (res?.response?.status === 409) {
            openErrorNotification(DUPLICATE_ERROR);
          } else {
            openErrorNotification(GENERIC_ERROR);
          }
        }}
        renderValue={(option, index, renderValueDefault) => renderValueDefault(option, index)}
        onDataUpdate={(value) => {
          onChange([...value]);
        }}
        getIsKeyEditable={(option) => !option.prescribed}
        getIsValueEditable={(option) => !option.prescribed}
      />

      <Button variant="secondary" icon="plus" disabled={getIsAddBtnDisabled(labels)} onClick={onLabelAdd}>
        Add label
      </Button>
    </Stack>
  );
};

const getIsAddBtnDisabled = (labels: Array<components['schemas']['LabelPair']> = []) => {
  const lastItem = labels?.at(-1);
  return lastItem && (lastItem.key?.id === undefined || lastItem.value?.id === undefined);
};
