import styles from './ConfigurationForm.module.css';

import Block from '../../../GBlock/Block';
import Text from '../../../Text/Text';
import PluginState from '../../../../plugin_state';

import { Button, Field, Form, Input } from '@grafana/ui';

import cn from 'classnames/bind';

import { SubmitHandler } from 'react-hook-form';
import React, { FC, useCallback, useState } from 'react';

import { isEmpty } from 'lodash-es';

const cx = cn.bind(styles);

type Props = {
  onSuccessfulSetup: () => void;
  defaultDataExporterApiUrl: string;
};

type FormProps = {
  dataExporterApiUrl: string;
};

/**
 * https://stackoverflow.com/a/43467144
 */
const isValidUrl = (url: string): boolean => {
  try {
    new URL(url);
    return true;
  } catch (_) {
    return false;
  }
};

const FormErrorMessage: FC<{ errorMsg: string }> = ({ errorMsg }) => (
  <>
    <pre>
      <Text type="link">{errorMsg}</Text>
    </pre>
    <Block withBackground className={cx('info-block')}>
      <Text type="secondary">
        Need help?
        <br />- file bugs on our GitHub Issues page{' '}
        <a
          href="https://code.corpglory.net/corpglory/grafana-data-exporter-app/issues"
          target="_blank"
          rel="noreferrer"
        >
          <Text type="link">here</Text>
        </a>
      </Text>
    </Block>
  </>
);

const ConfigurationForm: FC<Props> = ({ onSuccessfulSetup, defaultDataExporterApiUrl }) => {
  const [setupErrorMsg, setSetupErrorMsg] = useState<string | null>(null);
  const [formLoading, setFormLoading] = useState<boolean>(false);

  const setupPlugin: SubmitHandler<FormProps> = useCallback(
    async ({ dataExporterApiUrl }) => {
      setFormLoading(true);

      const errorMsg = await PluginState.installPlugin(dataExporterApiUrl);

      if (!errorMsg) {
        onSuccessfulSetup();
      } else {
        setSetupErrorMsg(errorMsg);
        setFormLoading(false);
      }
    },
    [onSuccessfulSetup]
  );

  return (
    <Form<FormProps> defaultValues={{ dataExporterApiUrl: defaultDataExporterApiUrl }} onSubmit={setupPlugin}>
      {({ register, errors }) => (
        <>
          <div className={cx('info-block')}>
            <p>1. Launch the DataExporter backend</p>
            <Text type="secondary">
              Run hobby, dev or production backend. See{' '}
              <a href="https://code.corpglory.net/corpglory/grafana-data-exporter" target="_blank" rel="noreferrer">
                <Text type="link">here</Text>
              </a>{' '}
              on how to get started.
            </Text>
          </div>

          <div className={cx('info-block')}>
            <p>2. Let us know the base URL of your DataExporter API</p>
            <Text type="secondary">
              The DataExporter backend must be reachable from your Grafana installation. Some examples are:
              <br />
              - http://host.docker.internal:8080
              <br />- http://localhost:8080
            </Text>
          </div>

          <Field label="DataExporter backend URL" invalid={!!errors.dataExporterApiUrl} error="Must be a valid URL">
            <Input
              {...register('dataExporterApiUrl', {
                required: true,
                validate: isValidUrl,
              })}
            />
          </Field>

          {setupErrorMsg && <FormErrorMessage errorMsg={setupErrorMsg} />}

          <Button type="submit" size="md" disabled={formLoading || !isEmpty(errors)}>
            Connect
          </Button>
        </>
      )}
    </Form>
  );
};

export default ConfigurationForm;
