import React from "react";
import { Card, Text, Button, TabGroup, TabList, Tab, TabPanel, TabPanels } from "@tremor/react";
import { CheckCircleIcon, XCircleIcon, ClipboardCopyIcon } from "@heroicons/react/outline";
import { ResponseTimeIndicator } from "./response_time_indicator";

// Helper function to deep-parse a JSON string if possible
const deepParse = (input: any) => {
  let parsed = input;
  if (typeof parsed === "string") {
    try {
      parsed = JSON.parse(parsed);
    } catch {
      return parsed;
    }
  }
  return parsed;
};

// TableClickableErrorField component with copy-to-clipboard functionality
const TableClickableErrorField: React.FC<{ label: string; value: string | null | undefined }> = ({
  label,
  value,
}) => {
  const [isExpanded, setIsExpanded] = React.useState(false);
  const [copied, setCopied] = React.useState(false);
  const safeValue = value?.toString() || "N/A";
  const truncated = safeValue.length > 50 ? safeValue.substring(0, 50) + "..." : safeValue;

  const handleCopy = () => {
    navigator.clipboard.writeText(safeValue);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <tr className="hover:bg-gray-50">
      <td className="px-4 py-2 align-top" colSpan={2}>
        <div className="flex items-center justify-between group">
          <div className="flex items-center flex-1">
            <button
              onClick={() => setIsExpanded(!isExpanded)}
              className="text-gray-400 hover:text-gray-600 mr-2"
            >
              {isExpanded ? "▼" : "▶"}
            </button>
            <div>
              <div className="text-sm text-gray-600">{label}</div>
              <pre className="mt-1 text-sm font-mono text-gray-800 whitespace-pre-wrap">
                {isExpanded ? safeValue : truncated}
              </pre>
            </div>
          </div>
          <button
            onClick={handleCopy}
            className="opacity-0 group-hover:opacity-100 text-gray-400 hover:text-gray-600"
          >
            <ClipboardCopyIcon className="h-4 w-4" />
          </button>
        </div>
      </td>
    </tr>
  );
};

// Add new interface for Redis details
interface RedisDetails {
  redis_host?: string;
  redis_port?: string;
  redis_version?: string;
  startup_nodes?: string;
  namespace?: string;
}

// Add new interface for Error Details
interface ErrorDetails {
  message: string;
  traceback: string;
  litellm_params?: any;
  health_check_cache_params?: any;
}

// Update HealthCheckDetails component to handle errors
const HealthCheckDetails: React.FC<{ response: any }> = ({ response }) => {
  // Initialize with safe default values
  let errorDetails: ErrorDetails | null = null;
  let parsedLitellmParams: any = {};
  let parsedRedisParams: any = {};

  try {
    if (response?.error) {
      try {
        const errorMessage = typeof response.error.message === 'string' 
          ? JSON.parse(response.error.message)
          : response.error.message;

        errorDetails = {
          message: errorMessage?.message || 'Unknown error',
          traceback: errorMessage?.traceback || 'No traceback available',
          litellm_params: errorMessage?.litellm_cache_params || {},
          health_check_cache_params: errorMessage?.health_check_cache_params || {}
        };
        
        parsedLitellmParams = deepParse(errorDetails.litellm_params) || {};
        parsedRedisParams = deepParse(errorDetails.health_check_cache_params) || {};
      } catch (e) {
        console.warn("Error parsing error details:", e);
        errorDetails = {
          message: String(response.error.message || 'Unknown error'),
          traceback: 'Error parsing details',
          litellm_params: {},
          health_check_cache_params: {}
        };
      }
    } else {
      parsedLitellmParams = deepParse(response?.litellm_cache_params) || {};
      parsedRedisParams = deepParse(response?.health_check_cache_params) || {};
    }
  } catch (e) {
    console.warn("Error in response parsing:", e);
    // Provide safe fallback values
    parsedLitellmParams = {};
    parsedRedisParams = {};
  }

  // Safely extract Redis details with fallbacks
  const redisDetails: RedisDetails = {
    redis_host: parsedRedisParams?.redis_client?.connection_pool?.connection_kwargs?.host ||
                parsedRedisParams?.redis_async_client?.connection_pool?.connection_kwargs?.host ||
                parsedRedisParams?.connection_kwargs?.host ||
                parsedRedisParams?.host ||
                "N/A",
    
    redis_port: parsedRedisParams?.redis_client?.connection_pool?.connection_kwargs?.port ||
                parsedRedisParams?.redis_async_client?.connection_pool?.connection_kwargs?.port ||
                parsedRedisParams?.connection_kwargs?.port ||
                parsedRedisParams?.port ||
                "N/A",
    
    redis_version: parsedRedisParams?.redis_version || "N/A",
    
    startup_nodes: (() => {
      try {
        if (parsedRedisParams?.redis_kwargs?.startup_nodes) {
          return JSON.stringify(parsedRedisParams.redis_kwargs.startup_nodes);
        }
        const host = parsedRedisParams?.redis_client?.connection_pool?.connection_kwargs?.host ||
                    parsedRedisParams?.redis_async_client?.connection_pool?.connection_kwargs?.host;
        const port = parsedRedisParams?.redis_client?.connection_pool?.connection_kwargs?.port ||
                    parsedRedisParams?.redis_async_client?.connection_pool?.connection_kwargs?.port;
        return host && port ? JSON.stringify([{ host, port }]) : "N/A";
      } catch (e) {
        return "N/A";
      }
    })(),

    namespace: parsedRedisParams?.namespace || "N/A",
  };

  return (
    <div className="bg-white rounded-lg shadow">
      <TabGroup>
        <TabList className="border-b border-gray-200 px-4">
          <Tab className="px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-800">Summary</Tab>
          <Tab className="px-4 py-2 text-sm font-medium text-gray-600 hover:text-gray-800">Raw Response</Tab>
        </TabList>

        <TabPanels>
          <TabPanel className="p-4">
            <div>
              <div className="flex items-center mb-6">
                {(response?.status === "healthy") ? (
                  <CheckCircleIcon className="h-5 w-5 text-green-500 mr-2" />
                ) : (
                  <XCircleIcon className="h-5 w-5 text-red-500 mr-2" />
                )}
                <Text className={`text-sm font-medium ${response?.status === "healthy" ? "text-green-500" : "text-red-500"}`}>
                  Cache Status: {response?.status || "unhealthy"}
                </Text>
              </div>

              <table className="w-full border-collapse">
                <tbody>
                  {/* Show error message if present */}
                  {errorDetails && (
                    <>
                      <tr><td colSpan={2} className="pt-4 pb-2 font-semibold text-red-600">Error Details</td></tr>
                      <TableClickableErrorField
                        label="Error Message"
                        value={errorDetails.message}
                      />
                      <TableClickableErrorField
                        label="Traceback"
                        value={errorDetails.traceback}
                      />
                    </>
                  )}

                  {/* Always show cache details, regardless of error state */}
                  <tr><td colSpan={2} className="pt-4 pb-2 font-semibold">Cache Details</td></tr>
                  <TableClickableErrorField
                    label="Cache Configuration"
                    value={String(parsedLitellmParams?.type)}
                  />
                  <TableClickableErrorField
                    label="Ping Response"
                    value={String(response.ping_response)}
                  />
                  <TableClickableErrorField
                    label="Set Cache Response"
                    value={response.set_cache_response || "N/A"}
                  />
                  <TableClickableErrorField
                    label="litellm_settings.cache_params"
                    value={JSON.stringify(parsedLitellmParams, null, 2)}
                  />
                  
                  {/* Redis Details Section */}
                  {parsedLitellmParams?.type === "redis" && (
                    <>
                      <tr><td colSpan={2} className="pt-4 pb-2 font-semibold">Redis Details</td></tr>
                      <TableClickableErrorField
                        label="Redis Host"
                        value={redisDetails.redis_host || "N/A"}
                      />
                      <TableClickableErrorField
                        label="Redis Port"
                        value={redisDetails.redis_port || "N/A"}
                      />
                      <TableClickableErrorField
                        label="Redis Version"
                        value={redisDetails.redis_version || "N/A"}
                      />
                      <TableClickableErrorField
                        label="Startup Nodes"
                        value={redisDetails.startup_nodes || "N/A"}
                      />
                      <TableClickableErrorField
                        label="Namespace"
                        value={redisDetails.namespace || "N/A"}
                      />
                    </>
                  )}
                </tbody>
              </table>
            </div>
          </TabPanel>

          <TabPanel className="p-4">
            <div className="bg-gray-50 rounded-md p-4 font-mono text-sm">
              <pre className="whitespace-pre-wrap break-words overflow-auto max-h-[500px]">
                {(() => {
                  try {
                    const data = {
                      ...response,
                      litellm_cache_params: parsedLitellmParams,
                      health_check_cache_params: parsedRedisParams
                    };
                    // First parse any string JSON values
                    const prettyData = JSON.parse(JSON.stringify(data, (key, value) => {
                      if (typeof value === 'string') {
                        try {
                          return JSON.parse(value);
                        } catch {
                          return value;
                        }
                      }
                      return value;
                    }));
                    // Then stringify with proper formatting
                    return JSON.stringify(prettyData, null, 2);
                  } catch (e) {
                    return "Error formatting JSON: " + (e as Error).message;
                  }
                })()}
              </pre>
            </div>
          </TabPanel>
        </TabPanels>
      </TabGroup>
    </div>
  );
};

export const CacheHealthTab: React.FC<{ 
  accessToken: string | null;
  healthCheckResponse: any;
  runCachingHealthCheck: () => void;
  responseTimeMs?: number | null;
}> = ({ accessToken, healthCheckResponse, runCachingHealthCheck, responseTimeMs }) => {
  const [localResponseTimeMs, setLocalResponseTimeMs] = React.useState<number | null>(null);
  const [isLoading, setIsLoading] = React.useState<boolean>(false);

  const handleHealthCheck = async () => {
    setIsLoading(true);
    const startTime = performance.now();
    await runCachingHealthCheck();
    const endTime = performance.now();
    setLocalResponseTimeMs(endTime - startTime);
    setIsLoading(false);
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <Button 
          onClick={handleHealthCheck}
          disabled={isLoading}
          className="bg-indigo-600 hover:bg-indigo-700 disabled:bg-indigo-400 text-white text-sm px-4 py-2 rounded-md"
        >
          {isLoading ? "Running Health Check..." : "Run Health Check"}
        </Button>
        <ResponseTimeIndicator responseTimeMs={localResponseTimeMs} />
      </div>

      {healthCheckResponse && (
        <HealthCheckDetails response={healthCheckResponse} />
      )}
    </div>
  );
}; 