import * as React from 'react';
import { rule } from 'nano-theme';
import useWindowSize from 'react-use/lib/useWindowSize';
import useWindowScroll from 'react-use/lib/useWindowScroll';
import { useDebugCtx } from '../context';
import { Anchor } from '../../../../json-crdt-extensions/peritext/rga/constants';
import { useSyncStore } from '../../../web/react/hooks';
import { CharOverlay } from './CharOverlay';
const blockClass = rule({
    pos: 'relative',
    pe: 'none',
    us: 'none',
    w: '0px',
    h: '100%',
    va: 'bottom',
});
export const RenderCaret = (props) => {
    const { children } = props;
    const ctx = useDebugCtx();
    const enabled = useSyncStore(ctx.state.enabled);
    if (!enabled || !ctx.ctx?.dom)
        return children;
    return React.createElement(RenderDebugCaret, { ...props });
};
const RenderDebugCaret = (props) => {
    return (React.createElement("span", { className: blockClass },
        props.children,
        React.createElement(DebugOverlay, { ...props })));
};
const characterOverlayStyles = {
    position: 'fixed',
    display: 'inline-block',
    visibility: 'hidden',
    backgroundColor: 'rgba(0, 0, 255, 0.1)',
    outline: '1px dashed blue',
};
const eolCharacterOverlayStyles = {
    ...characterOverlayStyles,
    outline: '1px dotted blue',
};
const eowCharacterOverlayStyles = {
    ...characterOverlayStyles,
    backgroundColor: 'rgba(127,127,127,.1)',
    outline: '0',
};
const DebugOverlay = ({ point }) => {
    useWindowSize();
    useWindowScroll();
    const { ctx, state } = useDebugCtx();
    const showCursorInfo = useSyncStore(state.showCursorInfo);
    const leftCharRef = React.useRef(null);
    const rightCharRef = React.useRef(null);
    const leftLineEndCharRef = React.useRef(null);
    const rightLineEndCharRef = React.useRef(null);
    const leftPrevLineEndCharRef = React.useRef(null);
    const rightPrevLineEndCharRef = React.useRef(null);
    const leftNextLineEndCharRef = React.useRef(null);
    const rightNextLineEndCharRef = React.useRef(null);
    const wordSkipLeftCharRef = React.useRef(null);
    const wordSkipRightCharRef = React.useRef(null);
    const prevLineCaretRef = React.useRef(null);
    const nextLineCaretRef = React.useRef(null);
    const anchorLeft = point.anchor === Anchor.After;
    React.useEffect(() => {
        leftCharRef.current?.(ctx.events.ui?.getPointRect(point, false));
        rightCharRef.current?.(ctx.events.ui?.getPointRect(point, true));
        const lineInfo = ctx.events.ui?.getLineInfo(point);
        leftLineEndCharRef.current?.(lineInfo?.[0][1]);
        rightLineEndCharRef.current?.(lineInfo?.[1][1]);
        if (lineInfo) {
            const prevLineInfo = ctx.events.ui?.getNextLineInfo(lineInfo, -1);
            const nextLineInfo = ctx.events.ui?.getNextLineInfo(lineInfo);
            leftPrevLineEndCharRef.current?.(prevLineInfo?.[0][1]);
            rightPrevLineEndCharRef.current?.(prevLineInfo?.[1][1]);
            leftNextLineEndCharRef.current?.(nextLineInfo?.[0][1]);
            rightNextLineEndCharRef.current?.(nextLineInfo?.[1][1]);
        }
        const wordJumpLeftPoint = ctx.peritext.editor.skip(point, -1, 'word');
        if (wordJumpLeftPoint)
            wordSkipLeftCharRef.current?.(ctx.events.ui?.getPointRect?.(wordJumpLeftPoint, true));
        const wordJumpRightPoint = ctx.peritext.editor.skip(point, 1, 'word');
        if (wordJumpRightPoint)
            wordSkipRightCharRef.current?.(ctx.events.ui?.getPointRect?.(wordJumpRightPoint, false));
        const pos = ctx.events.ui?.pointX(point);
        const currLine = ctx.events.ui?.getLineInfo(point);
        if (pos && currLine) {
            const targetX = pos[0];
            const prevLine = ctx.events.ui?.getNextLineInfo(currLine, -1);
            const nextLine = ctx.events.ui?.getNextLineInfo(currLine);
            if (prevLine) {
                const prevLinePoint = ctx.events.ui?.findPointAtX(targetX, prevLine);
                if (point.anchor === Anchor.Before)
                    prevLinePoint?.refBefore();
                else
                    prevLinePoint?.refAfter();
                if (prevLinePoint) {
                    const rect = ctx.events.ui?.api.getCharRect?.(prevLinePoint.id);
                    if (rect)
                        prevLineCaretRef.current?.(rect);
                }
            }
            if (nextLine) {
                const prevLinePoint = ctx.events.ui?.findPointAtX(targetX, nextLine);
                if (point.anchor === Anchor.Before)
                    prevLinePoint?.refBefore();
                else
                    prevLinePoint?.refAfter();
                if (prevLinePoint) {
                    const rect = ctx.events.ui?.api.getCharRect?.(prevLinePoint.id);
                    if (rect)
                        nextLineCaretRef.current?.(rect);
                }
            }
        }
    });
    if (!showCursorInfo)
        return null;
    return (React.createElement(React.Fragment, null,
        React.createElement(CharOverlay, { rectRef: leftCharRef, style: {
                ...characterOverlayStyles,
                backgroundColor: anchorLeft ? 'rgba(0,0,255,.2)' : 'rgba(0,0,255,.1)',
                outlineStyle: anchorLeft ? 'solid' : 'dashed',
            } }),
        React.createElement(CharOverlay, { rectRef: rightCharRef, style: {
                ...characterOverlayStyles,
                backgroundColor: !anchorLeft ? 'rgba(0,0,255,.2)' : 'rgba(0,0,255,.1)',
                outlineStyle: !anchorLeft ? 'solid' : 'dashed',
            } }),
        React.createElement(CharOverlay, { rectRef: leftLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid blue' } }),
        React.createElement(CharOverlay, { rectRef: rightLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid blue' } }),
        React.createElement(CharOverlay, { rectRef: leftPrevLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid rgba(127,127,127,.5)' } }),
        React.createElement(CharOverlay, { rectRef: rightPrevLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid rgba(127,127,127,.5)' } }),
        React.createElement(CharOverlay, { rectRef: leftNextLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid rgba(127,127,127,.5)' } }),
        React.createElement(CharOverlay, { rectRef: rightNextLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid rgba(127,127,127,.5)' } }),
        React.createElement(CharOverlay, { rectRef: wordSkipLeftCharRef, style: { ...eowCharacterOverlayStyles, borderLeft: '2px dotted rgba(127,127,127,.7)' } }),
        React.createElement(CharOverlay, { rectRef: wordSkipRightCharRef, style: { ...eowCharacterOverlayStyles, borderRight: '2px dotted rgba(127,127,127,.7)' } }),
        React.createElement(CharOverlay, { rectRef: prevLineCaretRef, style: { ...eowCharacterOverlayStyles, backgroundColor: 'rgba(127,127,127,.2)' } }),
        React.createElement(CharOverlay, { rectRef: nextLineCaretRef, style: { ...eowCharacterOverlayStyles, backgroundColor: 'rgba(127,127,127,.2)' } })));
};
//# sourceMappingURL=index.js.map