import { memo, useState, useMemo, useCallback } from "react";
import CodeBlock from "./codeBlock";
import styles from "./collapsibleCodeBlock.module.css";

interface CollapsibleCodeBlockProps {
  source: string;
  language: string;
  previewLines?: number;
}

const CollapsibleCodeBlock = memo(
  ({ source, language, previewLines = 5 }: CollapsibleCodeBlockProps) => {
    const [isExpanded, setIsExpanded] = useState(false);

    const { hasMoreLines, totalLines, collapsedHeight } = useMemo(() => {
      const lines = source.split("\n");
      const totalLines = lines.length;
      const hasMoreLines = totalLines > previewLines;
      const collapsedHeight = previewLines * 20 + 24;

      return { hasMoreLines, totalLines, collapsedHeight };
    }, [source, previewLines]);

    const stopAllPropagation = useCallback((e: React.SyntheticEvent) => {
      e.stopPropagation();
    }, []);

    const handleToggle = useCallback((e: React.MouseEvent) => {
      e.stopPropagation();
      e.preventDefault();
      setIsExpanded((prev) => !prev);
    }, []);

    const handleCodeBlockClick = useCallback(
      (e: React.MouseEvent) => {
        e.stopPropagation();
        // Only collapse when expanded and user is not selecting text
        if (isExpanded && window.getSelection()?.toString() === "") {
          setIsExpanded(false);
        }
      },
      [isExpanded],
    );

    if (!hasMoreLines) {
      return (
        <div
          onClick={stopAllPropagation}
          onMouseDown={stopAllPropagation}
          onPointerDown={stopAllPropagation}
        >
          <CodeBlock source={source} language={language} />
        </div>
      );
    }

    return (
      <div
        className={styles.collapsibleCodeBlockContainer}
        onClick={stopAllPropagation}
        onMouseDown={stopAllPropagation}
        onPointerDown={stopAllPropagation}
      >
        <div
          className={`${styles.codeWrapper} ${!isExpanded ? styles.collapsed : styles.expanded}`}
          style={
            !isExpanded ? { maxHeight: `${collapsedHeight}px` } : undefined
          }
          onClick={handleCodeBlockClick}
        >
          <CodeBlock source={source} language={language} />
          {!isExpanded && <div className={styles.gradientOverlay} />}
        </div>
        <button
          type="button"
          className={styles.toggleButton}
          onMouseDown={stopAllPropagation}
          onPointerDown={stopAllPropagation}
          onClick={handleToggle}
        >
          <span
            className={`codicon ${isExpanded ? "codicon-chevron-up" : "codicon-chevron-down"}`}
          />
          <span>
            {isExpanded
              ? "Show less"
              : `See more (${totalLines - previewLines} more lines)`}
          </span>
        </button>
      </div>
    );
  },
);

export default CollapsibleCodeBlock;
