import React, { useCallback, useState } from 'react';
import styled from 'styled-components';

import { Editor } from '@app/entityV2/shared/tabs/Documentation/components/editor/Editor';
import { Button, Tooltip } from '@src/alchemy-components';

const LINE_HEIGHT = 1.5;

const ShowMoreWrapper = styled.div`
    align-items: start;
    justify-content: center;
    display: flex;
    flex-direction: column;
`;

const MarkdownContainer = styled.div<{ lineLimit?: number | null }>`
    max-width: 100%;
    position: relative;
    flex: 1;
    ${(props) =>
        props.lineLimit &&
        props.lineLimit <= 1 &&
        ` 
        display: flex;
        align-items: center;
        gap: 4px;
    `}
`;

const CustomButton = styled(Button)`
    padding: 8px 0px;
`;

const MarkdownViewContainer = styled.div<{ scrollableY: boolean }>`
    display: block;
    overflow-wrap: break-word;
    word-wrap: break-word;
    overflow-x: hidden;
    overflow-y: ${(props) => (props.scrollableY ? 'auto' : 'hidden')};
    flex: 1;
`;

const CompactEditor = styled(Editor)<{ limit: number | null; customStyle?: React.CSSProperties }>`
    .remirror-theme {
        max-width: 100%;
    }
    .remirror-editor.ProseMirror {
        ${({ limit }) => limit && `max-height: ${limit * LINE_HEIGHT}em;`}
        h1 {
            font-size: 1.4em;
        }

        h2 {
            font-size: 1.3em;
        }

        h3 {
            font-size: 1.2em;
        }

        h4 {
            font-size: 1.1em;
        }

        h5,
        h6 {
            font-size: 1em;
        }

        p {
            ${(props) => props?.customStyle?.fontSize && `font-size: ${props?.customStyle?.fontSize}`};
            margin-bottom: 0;
        }

        padding: 0;
    }
`;

const FixedLineHeightEditor = styled(CompactEditor)<{ customStyle?: React.CSSProperties }>`
    .remirror-editor.ProseMirror {
        * {
            line-height: ${LINE_HEIGHT};
            font-size: 1em !important;
            margin-top: 0;
            margin-bottom: 0;
        }
        p {
            font-size: ${(props) => (props?.customStyle?.fontSize ? props?.customStyle?.fontSize : '1em')} !important;
        }
    }
`;

const MoreIndicator = styled.span`
    break-word: normal;
`;

export type Props = {
    content: string;
    lineLimit?: number | null;
    fixedLineHeight?: boolean;
    customStyle?: React.CSSProperties;
    scrollableY?: boolean; // Whether the viewer is vertically scrollable.
    handleShowMore?: () => void;
    hideShowMore?: boolean;
};

export default function CompactMarkdownViewer({
    content,
    lineLimit = 4,
    fixedLineHeight = false,
    customStyle = {},
    scrollableY = true,
    handleShowMore,
    hideShowMore,
}: Props) {
    const [isShowingMore, setIsShowingMore] = useState(false);
    const [isTruncated, setIsTruncated] = useState(false);

    const measuredRef = useCallback((node: HTMLDivElement | null) => {
        if (node !== null) {
            const resizeObserver = new ResizeObserver(() => {
                setIsTruncated(node.scrollHeight > node.clientHeight + 1);
            });
            resizeObserver.observe(node);
        }
    }, []);

    const StyledEditor = fixedLineHeight ? FixedLineHeightEditor : CompactEditor;

    return (
        <MarkdownContainer lineLimit={lineLimit}>
            <MarkdownViewContainer scrollableY={scrollableY} ref={measuredRef}>
                <StyledEditor
                    customStyle={customStyle}
                    limit={isShowingMore ? null : lineLimit}
                    content={content}
                    readOnly
                />
            </MarkdownViewContainer>
            {hideShowMore && isTruncated && (
                <Tooltip title={content}>
                    <MoreIndicator>...</MoreIndicator>
                </Tooltip>
            )}

            {!hideShowMore &&
                (isShowingMore || isTruncated) && ( // "show more" when isTruncated, "show less" when isShowingMore
                    <ShowMoreWrapper>
                        <CustomButton
                            variant="text"
                            size={lineLimit && lineLimit <= 1 ? 'sm' : undefined}
                            onClick={(e) => {
                                if (handleShowMore) {
                                    handleShowMore();
                                } else {
                                    setIsShowingMore(!isShowingMore);
                                }
                                e.stopPropagation();
                            }}
                        >
                            {isShowingMore ? 'show less' : 'show more'}
                        </CustomButton>
                    </ShowMoreWrapper>
                )}
        </MarkdownContainer>
    );
}
