import { useEffect, useState } from 'react';
import * as React from 'react';
import { useDebounce } from 'react-use';

import { type QueryEditorProps, getDefaultTimeRange, toOption } from '@grafana/data';
import { EditorField, EditorRows } from '@grafana/plugin-ui';
import { Input } from '@grafana/ui';

import { type TimeSeriesList, QueryType } from '../dataquery.gen';
import type CloudMonitoringDatasource from '../datasource';
import { type CloudMonitoringQuery } from '../types/query';
import { type CloudMonitoringOptions } from '../types/types';

import { AnnotationsHelp } from './AnnotationsHelp';
import { MetricQueryEditor, defaultTimeSeriesList } from './MetricQueryEditor';

export type Props = QueryEditorProps<CloudMonitoringDatasource, CloudMonitoringQuery, CloudMonitoringOptions>;

export const defaultQuery: (datasource: CloudMonitoringDatasource) => TimeSeriesList = (datasource) => ({
  ...defaultTimeSeriesList(datasource),
  title: '',
  text: '',
});

export const AnnotationQueryEditor = (props: Props) => {
  const { datasource, query, onRunQuery, data, onChange, range } = props;
  const meta = data?.series.length ? data?.series[0].meta : {};
  const customMetaData = meta?.custom ?? {};
  const timeSeriesList = { ...defaultQuery(datasource), ...query.timeSeriesList };
  const [title, setTitle] = useState(timeSeriesList.title || '');
  const [text, setText] = useState(timeSeriesList.text || '');
  const variableOptionGroup = {
    label: 'Template Variables',
    options: datasource.getVariables().map(toOption),
  };

  const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setTitle(e.target.value);
  };
  const handleTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value);
  };

  useDebounce(
    () => {
      onChange({ ...query, timeSeriesList: { ...timeSeriesList, title } });
    },
    1000,
    [title, onChange]
  );
  useDebounce(
    () => {
      onChange({ ...query, timeSeriesList: { ...timeSeriesList, text } });
    },
    1000,
    [text, onChange]
  );

  // Use a known query type
  useEffect(() => {
    if (!query.queryType || !Object.values(QueryType).includes(query.queryType)) {
      onChange({ ...query, queryType: QueryType.TIME_SERIES_LIST });
    }
  });

  return (
    <EditorRows>
      <>
        <MetricQueryEditor
          refId={query.refId}
          variableOptionGroup={variableOptionGroup}
          customMetaData={customMetaData}
          onChange={onChange}
          onRunQuery={onRunQuery}
          datasource={datasource}
          query={query}
          range={range || getDefaultTimeRange()}
        />
        <EditorField label="Title" htmlFor="annotation-query-title">
          <Input id="annotation-query-title" value={title} onChange={handleTitleChange} />
        </EditorField>
        <EditorField label="Text" htmlFor="annotation-query-text">
          <Input id="annotation-query-text" value={text} onChange={handleTextChange} />
        </EditorField>
      </>
      <AnnotationsHelp />
    </EditorRows>
  );
};
