import * as React from 'react';
import { FunctionComponent, useMemo, useContext, CSSProperties } from 'react';
import { CursorPositionContext } from '../../contexts/CursorPositionContext';
import { EditorViewContext } from '../../contexts/EditorViewContext';
import { FontInfoContext } from '../../contexts/FontInfoContext';
import { MouseMonitorContext } from '../../contexts/MouseMonitorContext';
import { from } from '../../utilities';
import { Position } from '../../vs/editor/common/core/position';
import { Range } from '../../vs/editor/common/core/range';

import { ViewLineRenderingData } from '../../vs/editor/common/viewModel/viewModel';
import { WritingMode } from '../editor';
import { IndentGuides } from '../indentGuides';
import { LineDecorations } from '../lineDecorations';
import { ViewSelection } from '../viewSelection';

import './Selections.css';

type P = {};

const Selection: FunctionComponent<P> = () => {
  return <></>;
};

type Props = {};

export const Selections: FunctionComponent<Props> = (props) => {
  const {
    editor,
    renderingContext: ctx,

    selection,
    selectionStart,
    setSelectionStart,
  } = useContext(EditorViewContext);
  const { fontInfo } = useContext(FontInfoContext);

  const lineHeight = useMemo(() => {
    return fontInfo.lineHeight;
  }, [fontInfo]);

  const viewSelection = useMemo(() => {
    // for (const cursor of cursors) {
    if (!selection) {
      return <></>;
    }

    if (selection.isEmpty()) {
      return <></>;
    }

    if (!ctx) {
      return <></>;
    }

    const startPosition = selection.getStartPosition();
    const endPosition = selection.getEndPosition();

    const p1 = ctx.viewportData.convertModelPositionToViewPosition(
      startPosition.lineNumber,
      startPosition.column
    );

    const p2 = ctx.viewportData.convertModelPositionToViewPosition(
      endPosition.lineNumber,
      endPosition.column
    );

    if (!p1) {
      return <></>;
    }

    if (!p2) {
      return <></>;
    }

    const { viewportData } = ctx;
    const [viewStartPosition, viewEndPosition] = [p1, p2].sort(
      Position.compare
    );

    const {
      startLineNumber: viewportStartLineNumber,
      endLineNumber: viewportEndLineNumber,
      relativeVerticalOffset,
    } = viewportData;

    const startLineNumber = Math.max(
      viewStartPosition.lineNumber,
      viewportStartLineNumber
    );
    const startColumn = viewStartPosition.column;

    const endLineNumber = Math.min(
      viewEndPosition.lineNumber,
      viewportEndLineNumber
    );
    const endColumn = viewEndPosition.column;

    const result = [];
    for (
      let lineNumber = startLineNumber;
      lineNumber <= endLineNumber;
      ++lineNumber
    ) {
      const lineIndex = lineNumber - viewportStartLineNumber;
      const viewLineRenderingData =
        viewportData.getViewLineRenderingData(lineNumber);
      if (lineNumber === startLineNumber && lineNumber === endLineNumber) {
        const content = viewLineRenderingData.content.replace(/\s/g, '\xa0');
        return (
          <ViewSelection
            content={content}
            height={lineHeight}
            start={startColumn}
            end={endColumn}
            offset={relativeVerticalOffset[lineIndex]}
          />
        );
      }
      if (lineNumber === startLineNumber) {
        const content = viewLineRenderingData.content.replace(/\s/g, '\xa0');
        // return (
        //   <ViewSelection
        //     content={content}
        //     height={lineHeight}
        //     start={startColumn}
        //     end={content.length}
        //   />
        // );
        result.push(
          <ViewSelection
            content={content}
            height={lineHeight}
            start={startColumn}
            end={content.length}
            offset={relativeVerticalOffset[lineIndex]}
          />
        );
      }

      if (startLineNumber < lineNumber && lineNumber < endLineNumber) {
        const content = viewLineRenderingData.content.replace(/\s/g, '\xa0');
        // return (
        //   <ViewSelection
        //     content={content}
        //     height={lineHeight}
        //     start={1}
        //     end={content.length}
        //   />
        // );
        result.push(
          <ViewSelection
            content={content}
            height={lineHeight}
            start={1}
            end={content.length}
            offset={relativeVerticalOffset[lineIndex]}
          />
        );
      }

      if (lineNumber === endLineNumber) {
        const content = viewLineRenderingData.content.replace(/\s/g, '\xa0');
        // return (
        //   <ViewSelection
        //     content={content}
        //     height={lineHeight}
        //     start={1}
        //     end={endColumn - 1}
        //   />
        // );
        result.push(
          <ViewSelection
            content={content}
            height={lineHeight}
            start={1}
            end={endColumn}
            offset={relativeVerticalOffset[lineIndex]}
          />
        );
      }
    }

    return result;

    return <></>;
  }, [selection, ctx, lineHeight]);

  if (!ctx) {
    return <></>;
  }

  const height = Math.min(ctx.scrollHeight, 1000000);
  const width = ctx.scrollWidth;

  const style: CSSProperties = {
    height: `${height}px`,
    width: `${width}px`,
    position: 'absolute',
  };

  return <div style={style}>{viewSelection}</div>;
};
