import { Component } from 'preact';
import type { IAnnotationWithSource } from '../storage/Annotation';
import { RpcClient } from 'webextension-rpc';
import { describeTextQuote } from '@apache-annotator/dom';
import type { WebAnnotation } from 'web-annotation-utils';
import type { backgroundRpcServer } from '../background';

const backgroundRpc = new RpcClient<typeof backgroundRpcServer>();
const createAnnotation = backgroundRpc.func('createAnnotation');

export async function annotateSelection() {
  // TODO Use something else than document, so the page’s own scripts cannot observe the reader’s annotation activity.
  document.dispatchEvent(new CustomEvent('createAnnotation'));
}

function deselect() {
  const selection = window.getSelection();
  if (selection) selection.removeAllRanges();
}

interface AnnotationCreationHelperProps {
  onAnnotationCreated: (annotation: IAnnotationWithSource) => void;
}

interface AnnotationCreationHelperState {}

export class AnnotationCreationHelper extends Component<
  AnnotationCreationHelperProps,
  AnnotationCreationHelperState
> {
  state: AnnotationCreationHelperState = {};

  constructor() {
    super();
    this.onCreateAnnotation = this.onCreateAnnotation.bind(this);
  }

  override componentDidMount(): void {
    document.addEventListener('createAnnotation', this.onCreateAnnotation);
  }

  override componentWillUnmount(): void {
    document.removeEventListener('createAnnotation', this.onCreateAnnotation);
  }

  async onCreateAnnotation() {
    const target: WebAnnotation['target'] = {
      source: document.URL.split('#')[0],
    };
    const selection = window.getSelection();
    if (selection && !selection.isCollapsed) {
      const range = selection.getRangeAt(0);
      const selector = await describeTextQuote(range);
      target.selector = selector;
      deselect();
    }
    let createdAnnotation;
    const annotationStub = { target }
    try {
      createdAnnotation = await createAnnotation(annotationStub);
    } catch (error: any) {
      const newError = new Error(`Error creating the annotation: ${error.message}`)
      alert(newError.message);
      throw newError;
    }
    this.props.onAnnotationCreated(createdAnnotation);
  }

  render() {
    return undefined;
  }
}
