import { useMemo } from "react";

interface Props {
  columns: string[];
  rows: unknown[][];
}

function syntaxHighlight(json: string): string {
  return json.replace(
    /("(\\u[\da-fA-F]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g,
    (match) => {
      let cls = "text-info"; // number
      if (match.startsWith('"')) {
        if (match.endsWith(":")) {
          cls = "text-foreground"; // key
        } else {
          cls = "text-success"; // string
        }
      } else if (/true|false/.test(match)) {
        cls = "text-violet"; // boolean
      } else if (match === "null") {
        cls = "text-muted-foreground italic"; // null
      }
      return `<span class="${cls}">${match}</span>`;
    }
  );
}

export function ResultsJsonView({ columns, rows }: Props) {
  const jsonData = useMemo(() => {
    return rows.map((row) => {
      const obj: Record<string, unknown> = {};
      columns.forEach((col, i) => {
        obj[col] = row[i];
      });
      return obj;
    });
  }, [columns, rows]);

  const highlighted = useMemo(
    () => syntaxHighlight(JSON.stringify(jsonData, null, 2)),
    [jsonData]
  );

  return (
    <div className="flex h-full select-text flex-col">
      <div className="border-b px-3 py-1">
        <span className="text-xs text-muted-foreground">
          {rows.length} row{rows.length !== 1 ? "s" : ""}
        </span>
      </div>
      <div className="flex-1 overflow-auto">
        <pre
          className="p-3 text-xs leading-5 font-mono"
          dangerouslySetInnerHTML={{ __html: highlighted }}
        />
      </div>
    </div>
  );
}
