// SelectionApp.tsx
import React, { useState, useRef } from "react";

interface Span {
  span_text: string;
  start: number;
  end: number;
}

const SelectionApp: React.FC = () => {
  const [spans, setSpans] = useState<Span[]>([]);
  const [keySpan, setKeySpan] = useState<string>("span_text");
  const [keyStart, setKeyStart] = useState<string>("start");
  const [keyEnd, setKeyEnd] = useState<string>("end");
  const [lastText, setLastText] = useState<string>("");

  const inputRef = useRef<HTMLDivElement>(null);

  const getNormalizedText = (container: HTMLElement): string => {
    let html = container.innerHTML;
    html = html.replace(/<div><br><\/div>/gi, '\n');
    html = html.replace(/<div>/gi, '\n').replace(/<\/div>/gi, '');
    html = html.replace(/<br\s*\/?>/gi, '\n');
    html = html.replace(/&nbsp;/g, ' ');
    html = html.replace(/<[^>]+>/g, '');
    return html;
  };

  const getSelectionIndices = () => {
    if (!inputRef.current) return;
    const container = inputRef.current;
    const selection = window.getSelection();
    if (!selection || !selection.rangeCount) return;

    const range = selection.getRangeAt(0);
    if (!container.contains(range.startContainer) || !container.contains(range.endContainer))
      return;

    const selectedText = selection.toString();
    if (!selectedText) return;

    const preRange = range.cloneRange();
    preRange.selectNodeContents(container);
    preRange.setEnd(range.startContainer, range.startOffset);

    const tempDiv = document.createElement("div");
    tempDiv.appendChild(preRange.cloneContents());
    const preText = getNormalizedText(tempDiv);

    const start = preText.length;
    const end = start + selectedText.length;

    const newSpan: Span = { span_text: selectedText, start, end };
    setSpans((prev) => [newSpan, ...prev]);
  };

  const renderSpans = () => {
    return spans.map((s) => ({
      [keySpan]: s.span_text,
      [keyStart]: s.start,
      [keyEnd]: s.end,
    }));
  };

  const handleInput = (e: React.FormEvent<HTMLDivElement>) => {
    const currentText = getNormalizedText(e.currentTarget);
    if (currentText !== lastText) {
      setSpans([]);
      setLastText(currentText);
    }
  };

  return (
    <div
      style={{
        maxWidth: "900px",
        margin: "40px auto",
        fontFamily: "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif",
        color: "#333",
      }}
    >
      <h2 style={{ textAlign: "center", marginBottom: "25px", color: "#1a73e8" }}>
        Span Annotation App
      </h2>

      {/* Settings Panel */}
      <div
        style={{
          marginBottom: "20px",
          padding: "15px 20px",
          borderRadius: "10px",
          background: "#f9f9f9",
          boxShadow: "0 2px 6px rgba(0,0,0,0.1)",
          display: "flex",
          flexWrap: "wrap",
          gap: "10px",
          alignItems: "center",
        }}
      >
        <strong>Key Names:</strong>
        <label>
          Span Text:
          <input
            value={keySpan}
            onChange={(e) => setKeySpan(e.target.value)}
            style={{ marginLeft: "5px", padding: "4px 8px", borderRadius: "4px", border: "1px solid #ccc" }}
          />
        </label>
        <label>
          Start:
          <input
            value={keyStart}
            onChange={(e) => setKeyStart(e.target.value)}
            style={{ marginLeft: "5px", padding: "4px 8px", borderRadius: "4px", border: "1px solid #ccc" }}
          />
        </label>
        <label>
          End:
          <input
            value={keyEnd}
            onChange={(e) => setKeyEnd(e.target.value)}
            style={{ marginLeft: "5px", padding: "4px 8px", borderRadius: "4px", border: "1px solid #ccc" }}
          />
        </label>
      </div>

      {/* Editable Div */}
      <div
        ref={inputRef}
        contentEditable
        onInput={handleInput}
        style={{
          width: "100%",
          minHeight: "180px",
          maxHeight: "450px",
          border: "1px solid #ccc",
          borderRadius: "10px",
          padding: "12px",
          whiteSpace: "pre-wrap",
          overflowWrap: "break-word",
          overflowY: "auto",
          resize: "vertical",
          boxShadow: "inset 0 2px 6px rgba(0,0,0,0.05)",
          fontSize: "16px",
          lineHeight: "1.5",
        }}
      ></div>

      <button
        onClick={getSelectionIndices}
        style={{
          marginTop: "15px",
          padding: "10px 20px",
          backgroundColor: "#1a73e8",
          color: "#fff",
          border: "none",
          borderRadius: "6px",
          cursor: "pointer",
          boxShadow: "0 2px 6px rgba(0,0,0,0.2)",
        }}
      >
        Get Selection JSON
      </button>

      {/* Display JSON */}
      <pre
        style={{
          marginTop: "20px",
          fontFamily: "monospace",
          background: "#f4f4f4",
          padding: "15px",
          borderRadius: "10px",
          border: "1px solid #ddd",
          whiteSpace: "pre-wrap",
          userSelect: "text",
          boxShadow: "inset 0 2px 4px rgba(0,0,0,0.05)",
        }}
      >
        {spans.length ? JSON.stringify(renderSpans(), null, 2) : ""}
      </pre>
    </div>
  );
};

export default SelectionApp;
