import type React from "react";
import { useState } from "react";

type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
type JsonObject = { [key: string]: JsonValue };
type JsonArray = JsonValue[];

const isJsonString = (str: string): boolean => {
  if (typeof str !== "string") return false;
  const trimmed = str.trim();

  // Check if it looks like JSON (starts with { or [)
  if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return false;

  try {
    const parsed = JSON.parse(trimmed);
    // Ensure it's actually an object or array, not just a primitive
    console.log("JSON parse successful:", parsed);
    return typeof parsed === "object" && parsed !== null;
  } catch (error) {
    console.log("JSON parse failed:", error);
    return false;
  }
};

const JsonCollapsible: React.FC<{ data: JsonValue; isString?: boolean }> = ({
  data,
  isString = false,
}) => {
  const [isCollapsed, setIsCollapsed] = useState(true);

  let jsonData: JsonValue;
  try {
    jsonData = isString ? JSON.parse(data as string) : data;
  } catch {
    // If parsing fails, display as string
    return (
      <pre className="text-sm text-gray-300 whitespace-pre-wrap overflow-auto">
        {String(data)}
      </pre>
    );
  }

  const isObject = typeof jsonData === "object" && jsonData !== null;

  if (!isObject) {
    return <span className="text-gray-300">{JSON.stringify(jsonData)}</span>;
  }

  const keys = Object.keys(jsonData as JsonObject);
  const preview = Array.isArray(jsonData)
    ? `[${jsonData.length} items]`
    : `{${keys.length} keys}`;

  return (
    <div className="json-collapsible">
      <button
        onClick={() => setIsCollapsed(!isCollapsed)}
        className="flex items-center gap-1 text-blue-400 hover:text-blue-300 transition-colors text-sm font-mono"
      >
        <span
          className="transform transition-transform duration-200"
          style={{
            transform: isCollapsed ? "rotate(-90deg)" : "rotate(0deg)",
          }}
        >
          ▼
        </span>
        {isCollapsed ? preview : Array.isArray(jsonData) ? "[" : "{"}
      </button>
      {!isCollapsed && (
        <div className="ml-4 mt-1">
          <pre className="text-sm text-gray-300 whitespace-pre-wrap overflow-auto">
            {JSON.stringify(jsonData, null, 2)}
          </pre>
          <div className="text-blue-400 font-mono text-sm">
            {Array.isArray(jsonData) ? "]" : "}"}
          </div>
        </div>
      )}
    </div>
  );
};

const ResultBlock: React.FC<{ error?: string; result?: unknown }> = ({
  error,
  result,
}) => {
  console.log("ResultBlock component rendered with:", {
    error,
    result,
    type: typeof result,
  });

  const renderContent = () => {
    console.log("ResultBlock Debug:", {
      result,
      type: typeof result,
      isString: typeof result === "string",
      isArray: Array.isArray(result),
      startsWithBracket:
        typeof result === "string" && result.trim().startsWith("["),
      isJsonString: typeof result === "string" ? isJsonString(result) : false,
    });

    // Handle objects and arrays directly
    if (typeof result === "object" && result !== null) {
      console.log("Rendering as object/array with JsonCollapsible");
      return <JsonCollapsible data={result as JsonValue} />;
    }

    // Handle string that might be JSON
    if (typeof result === "string") {
      const trimmed = result.trim();
      if (isJsonString(trimmed)) {
        console.log("Rendering string as JSON with JsonCollapsible");
        return <JsonCollapsible data={trimmed} isString={true} />;
      }
    }

    // Fallback to plain text display
    console.log("Rendering as plain text fallback");
    return (
      <pre className="text-sm text-gray-300 whitespace-pre-wrap overflow-auto">
        {String(result)}
      </pre>
    );
  };

  return (
    <div
      className={
        error
          ? "bg-red-900 border border-red-600 rounded p-3"
          : "bg-gray-700 border border-gray-600 rounded p-3"
      }
    >
      {error ? <p className="text-red-300 text-sm">Error: {error}</p> : null}
      <div className="mt-2">{renderContent()}</div>
    </div>
  );
};

export default ResultBlock;
