import { LevelPart } from "@/interfaces/exam";
import { useEffect, useRef, useState } from "react";

interface Props {
    part: LevelPart,
    contextWord: string | undefined,
    setContextWordLine: React.Dispatch<React.SetStateAction<number | undefined>>
}

const TextComponent: React.FC<Props> = ({ part, contextWord, setContextWordLine }) => {
    const textRef = useRef<HTMLDivElement>(null);
    const [lineNumbers, setLineNumbers] = useState<number[]>([]);
    const [lineHeight, setLineHeight] = useState<number>(0);

    const calculateLineNumbers = () => {
        if (textRef.current) {
            const computedStyle = window.getComputedStyle(textRef.current);
            const lineHeightValue = parseFloat(computedStyle.lineHeight);
            const containerWidth = textRef.current.clientWidth;
            setLineHeight(lineHeightValue);

            const offscreenElement = document.createElement('div');
            offscreenElement.style.position = 'absolute';
            offscreenElement.style.top = '-9999px';
            offscreenElement.style.left = '-9999px';
            offscreenElement.style.whiteSpace = 'pre-wrap';
            offscreenElement.style.width = `${containerWidth}px`;
            offscreenElement.style.font = computedStyle.font;
            offscreenElement.style.lineHeight = computedStyle.lineHeight;
            offscreenElement.style.wordWrap = 'break-word';
            offscreenElement.style.textAlign = computedStyle.textAlign as CanvasTextAlign;

            const textContent = textRef.current.textContent || '';
            const lines = textContent.split(/\n/).map(line => 
                line.split(/(\s+)/).map(word => {
                    const span = document.createElement('span');
                    span.textContent = word;
                    return span;
                })
            );
    
            // Append all spans to offscreenElement
            lines.forEach(line => {
                line.forEach(span => offscreenElement.appendChild(span));
                offscreenElement.appendChild(document.createElement('br'));
            });

            document.body.appendChild(offscreenElement);

            const processedLines: string[][] = [[]];
            let currentLine = 1;
            let currentLineTop: number | undefined;
            let contextWordLine: number | null = null;

            const firstChild = offscreenElement.firstChild as HTMLElement;
            if (firstChild) {
                currentLineTop = firstChild.getBoundingClientRect().top;
            }

            const spans = offscreenElement.querySelectorAll<HTMLSpanElement>('span');

            spans.forEach(span => {
                const rect = span.getBoundingClientRect();
                const top = rect.top;

                if (currentLineTop !== undefined && top > currentLineTop) {
                    currentLine++;
                    currentLineTop = top;
                    processedLines.push([]);
                }

                processedLines[processedLines.length - 1].push(span.textContent?.trim() || '');

                if (contextWord && contextWordLine === null && span.textContent?.includes(contextWord)) {
                    contextWordLine = currentLine;
                }
            });
            setLineNumbers(processedLines.map((_, index) => index + 1));
            if (contextWordLine) {
                setContextWordLine(contextWordLine);
            }

            document.body.removeChild(offscreenElement);
        }
    };



    useEffect(() => {
        calculateLineNumbers();

        const resizeObserver = new ResizeObserver(() => {
            calculateLineNumbers();
        });

        if (textRef.current) {
            // eslint-disable-next-line react-hooks/exhaustive-deps
            resizeObserver.observe(textRef.current);
        }

        return () => {
            if (textRef.current) {
                // eslint-disable-next-line react-hooks/exhaustive-deps
                resizeObserver.unobserve(textRef.current);
            }
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [part.context, contextWord]);

    /*if (typeof part.showContextLines === "undefined") {
        return (
            <div className="flex flex-col gap-2 w-full">
                <div className="border border-mti-gray-dim w-full rounded-full opacity-10" />
                {!!part.context &&
                    part.context
                        .split(/\n|(\\n)/g)
                        .filter((x) => x && x.length > 0 && x !== "\\n")
                        .map((line, index) => (
                            <Fragment key={index}>
                                <p key={index}>{line}</p>
                            </Fragment>
                        ))}
            </div>
        );
    }*/

    return (
        <div className="flex mt-2">
            <div className="flex-shrink-0 w-8 pr-2">
                {lineNumbers.map(num => (
                    <div key={num} className="text-gray-400 flex justify-end" style={{ lineHeight: `${lineHeight}px` }}>
                        {num}
                    </div>
                ))}
            </div>
            <div ref={textRef} className="h-fit whitespace-pre-wrap ml-2">
                <div dangerouslySetInnerHTML={{ __html: part.context! }} />
            </div>
        </div>
    );
}

export default TextComponent;
