"use client"

import React, { useState, useEffect, useCallback } from "react"
import { motion, AnimatePresence } from "framer-motion"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"
import { Button } from "../ui/button"
import { MoonUIBadgePro as Badge } from "../ui/badge"
import { Progress } from "../ui/progress"
import { cn } from "../../lib/utils"
import { 
  Activity, 
  CheckCircle, 
  XCircle, 
  AlertCircle, 
  Clock, 
  Zap, 
  Globe, 
  Database, 
  Server,
  Lock,
  Sparkles,
  RefreshCw,
  TrendingUp,
  Timer
} from "lucide-react"
import { useSubscription } from "../../hooks/use-subscription"

interface HealthCheckEndpoint {
  id: string
  name: string
  url: string
  method: "GET" | "POST" | "PUT" | "DELETE" | "HEAD"
  expectedStatus?: number[]
  timeout?: number
  headers?: Record<string, string>
  body?: string
  critical?: boolean
}

interface HealthCheckResult {
  id: string
  name: string
  status: "healthy" | "unhealthy" | "warning" | "pending"
  responseTime: number
  statusCode?: number
  error?: string
  timestamp: Date
  uptime?: number
}

interface HealthCheckProps {
  endpoints: HealthCheckEndpoint[]
  interval?: number
  autoRefresh?: boolean
  showResponseTime?: boolean
  showUptime?: boolean
  showHistory?: boolean
  maxHistory?: number
  onStatusChange?: (results: HealthCheckResult[]) => void
  className?: string
}

const HealthCheckInternal: React.FC<HealthCheckProps> = ({
  endpoints,
  interval = 30000, // 30 seconds
  autoRefresh = true,
  showResponseTime = true,
  showUptime = true,
  showHistory = true,
  maxHistory = 20,
  onStatusChange,
  className
}) => {
  const [results, setResults] = useState<HealthCheckResult[]>([])
  const [history, setHistory] = useState<Record<string, HealthCheckResult[]>>({})
  const [isChecking, setIsChecking] = useState(false)
  const [lastCheck, setLastCheck] = useState<Date | null>(null)

  const checkEndpoint = async (endpoint: HealthCheckEndpoint): Promise<HealthCheckResult> => {
    const startTime = Date.now()
    
    try {
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), endpoint.timeout || 5000)

      const response = await fetch(endpoint.url, {
        method: endpoint.method,
        headers: {
          'Content-Type': 'application/json',
          ...endpoint.headers
        },
        body: endpoint.body,
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      const responseTime = Date.now() - startTime
      const expectedStatuses = endpoint.expectedStatus || [200, 201, 204]
      
      const isHealthy = expectedStatuses.includes(response.status)
      
      return {
        id: endpoint.id,
        name: endpoint.name,
        status: isHealthy ? "healthy" : "unhealthy",
        responseTime,
        statusCode: response.status,
        timestamp: new Date()
      }
    } catch (error) {
      const responseTime = Date.now() - startTime
      
      return {
        id: endpoint.id,
        name: endpoint.name,
        status: "unhealthy",
        responseTime,
        error: error instanceof Error ? error.message : "Unknown error",
        timestamp: new Date()
      }
    }
  }

  const checkAllEndpoints = useCallback(async () => {
    setIsChecking(true)
    
    try {
      const checks = endpoints.map(endpoint => checkEndpoint(endpoint))
      const newResults = await Promise.all(checks)
      
      setResults(newResults)
      setLastCheck(new Date())
      
      // Update history
      setHistory(prevHistory => {
        const newHistory = { ...prevHistory }
        
        newResults.forEach(result => {
          if (!newHistory[result.id]) {
            newHistory[result.id] = []
          }
          
          newHistory[result.id] = [
            result,
            ...newHistory[result.id].slice(0, maxHistory - 1)
          ]
        })
        
        return newHistory
      })
      
      onStatusChange?.(newResults)
    } catch (error) {
      console.error("Health check failed:", error)
    } finally {
      setIsChecking(false)
    }
  }, [endpoints, maxHistory, onStatusChange])

  // Initial check
  useEffect(() => {
    checkAllEndpoints()
  }, [checkAllEndpoints])

  // Auto refresh
  useEffect(() => {
    if (!autoRefresh) return

    const intervalId = setInterval(checkAllEndpoints, interval)
    return () => clearInterval(intervalId)
  }, [autoRefresh, interval, checkAllEndpoints])

  const getOverallStatus = (): "healthy" | "unhealthy" | "warning" => {
    if (results.length === 0) return "warning"
    
    const criticalEndpoints = endpoints.filter(e => e.critical !== false)
    const criticalResults = results.filter(r => 
      criticalEndpoints.some(e => e.id === r.id)
    )
    
    const hasUnhealthy = criticalResults.some(r => r.status === "unhealthy")
    const hasWarning = results.some(r => r.status === "warning")
    
    if (hasUnhealthy) return "unhealthy"
    if (hasWarning) return "warning"
    return "healthy"
  }

  const getStatusIcon = (status: string) => {
    switch (status) {
      case "healthy":
        return <CheckCircle className="h-4 w-4 text-green-500" />
      case "unhealthy":
        return <XCircle className="h-4 w-4 text-red-500" />
      case "warning":
        return <AlertCircle className="h-4 w-4 text-yellow-500" />
      default:
        return <Clock className="h-4 w-4 text-muted-foreground" />
    }
  }

  const getStatusColor = (status: string) => {
    switch (status) {
      case "healthy":
        return "bg-green-500"
      case "unhealthy":
        return "bg-red-500"
      case "warning":
        return "bg-yellow-500"
      default:
        return "bg-muted-foreground"
    }
  }

  const formatResponseTime = (time: number) => {
    if (time < 1000) return `${time}ms`
    return `${(time / 1000).toFixed(2)}s`
  }

  const calculateUptime = (endpointId: string): number => {
    const endpointHistory = history[endpointId] || []
    if (endpointHistory.length === 0) return 0
    
    const healthyCount = endpointHistory.filter(r => r.status === "healthy").length
    return (healthyCount / endpointHistory.length) * 100
  }

  const overallStatus = getOverallStatus()
  const healthyCount = results.filter(r => r.status === "healthy").length
  const overallUptime = results.length > 0 
    ? results.reduce((acc, result) => acc + calculateUptime(result.id), 0) / results.length
    : 0

  return (
    <Card className={cn("w-full", className)}>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="flex items-center gap-2">
              <Activity className="h-6 w-6" />
              <div>
                <CardTitle className="flex items-center gap-2">
                  System Health
                  <Badge 
                    variant={overallStatus === "healthy" ? "secondary" : "destructive"}
                    className={cn(
                      "text-white",
                      overallStatus === "healthy" && "bg-green-500",
                      overallStatus === "warning" && "bg-yellow-500",
                      overallStatus === "unhealthy" && "bg-red-500"
                    )}
                  >
                    {overallStatus.toUpperCase()}
                  </Badge>
                </CardTitle>
                {lastCheck && (
                  <CardDescription>
                    Last checked: {lastCheck.toLocaleTimeString()}
                  </CardDescription>
                )}
              </div>
            </div>
          </div>
          
          <div className="flex items-center gap-2">
            {showUptime && (
              <div className="text-right">
                <div className="text-sm font-medium">{overallUptime.toFixed(1)}%</div>
                <div className="text-xs text-muted-foreground">Uptime</div>
              </div>
            )}
            
            <Button
              onClick={checkAllEndpoints}
              disabled={isChecking}
              variant="outline"
              size="sm"
            >
              <RefreshCw className={cn("h-4 w-4", isChecking && "animate-spin")} />
            </Button>
          </div>
        </div>

        {/* Overall Stats */}
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mt-4">
          <div className="text-center">
            <div className="text-2xl font-bold text-green-500">{healthyCount}</div>
            <div className="text-xs text-muted-foreground">Healthy</div>
          </div>
          <div className="text-center">
            <div className="text-2xl font-bold text-red-500">
              {results.filter(r => r.status === "unhealthy").length}
            </div>
            <div className="text-xs text-muted-foreground">Unhealthy</div>
          </div>
          {showResponseTime && (
            <div className="text-center">
              <div className="text-lg font-bold">
                {results.length > 0 
                  ? formatResponseTime(
                      results.reduce((acc, r) => acc + r.responseTime, 0) / results.length
                    )
                  : "0ms"
                }
              </div>
              <div className="text-xs text-muted-foreground">Avg Response</div>
            </div>
          )}
          <div className="text-center">
            <div className="text-lg font-bold">{results.length}</div>
            <div className="text-xs text-muted-foreground">Services</div>
          </div>
        </div>
      </CardHeader>

      <CardContent>
        <div className="space-y-4">
          <AnimatePresence>
            {results.map((result, index) => (
              <motion.div
                key={result.id}
                initial={{ opacity: 0, x: -20 }}
                animate={{ opacity: 1, x: 0 }}
                exit={{ opacity: 0, x: 20 }}
                transition={{ delay: index * 0.05 }}
              >
                <Card>
                  <CardContent className="p-4">
                    <div className="flex items-center justify-between">
                      <div className="flex items-center gap-3">
                        {getStatusIcon(result.status)}
                        <div>
                          <div className="font-medium">{result.name}</div>
                          {result.error && (
                            <div className="text-sm text-red-500">{result.error}</div>
                          )}
                          {result.statusCode && (
                            <div className="text-xs text-muted-foreground">
                              HTTP {result.statusCode}
                            </div>
                          )}
                        </div>
                      </div>
                      
                      <div className="flex items-center gap-4 text-sm">
                        {showResponseTime && (
                          <div className="text-right">
                            <div className="font-medium">
                              {formatResponseTime(result.responseTime)}
                            </div>
                            <div className="text-xs text-muted-foreground">Response</div>
                          </div>
                        )}
                        
                        {showUptime && (
                          <div className="text-right">
                            <div className="font-medium">
                              {calculateUptime(result.id).toFixed(1)}%
                            </div>
                            <div className="text-xs text-muted-foreground">Uptime</div>
                          </div>
                        )}
                      </div>
                    </div>
                    
                    {/* Mini history chart */}
                    {showHistory && history[result.id] && (
                      <div className="mt-3">
                        <div className="flex items-center gap-1 h-2">
                          {history[result.id].slice(0, 20).reverse().map((historyResult, i) => (
                            <div
                              key={i}
                              className={cn(
                                "flex-1 h-full rounded-sm",
                                getStatusColor(historyResult.status)
                              )}
                            />
                          ))}
                        </div>
                        <div className="text-xs text-muted-foreground mt-1">
                          Last {Math.min(history[result.id].length, 20)} checks
                        </div>
                      </div>
                    )}
                  </CardContent>
                </Card>
              </motion.div>
            ))}
          </AnimatePresence>

          {results.length === 0 && !isChecking && (
            <div className="text-center py-8">
              <Server className="h-12 w-12 mx-auto mb-4 text-muted-foreground" />
              <p className="text-muted-foreground">No endpoints configured</p>
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  )
}

export const HealthCheck: React.FC<HealthCheckProps> = ({ className, ...props }) => {
  // Check if we're in docs mode or have pro access
  const { hasProAccess, isLoading } = useSubscription()
  
  // In docs mode, always show the component
  
  // If not in docs mode and no pro access, show upgrade prompt
  if (!isLoading && !hasProAccess) {
    return (
      <Card className={cn("w-fit", className)}>
        <CardContent className="py-6 text-center">
          <div className="space-y-4">
            <div className="rounded-full bg-purple-100 dark:bg-purple-900/30 p-3 w-fit mx-auto">
              <Lock className="h-6 w-6 text-purple-600 dark:text-purple-400" />
            </div>
            <div>
              <h3 className="font-semibold text-sm mb-2">Pro Feature</h3>
              <p className="text-muted-foreground text-xs mb-4">
                Health Check is available exclusively to MoonUI Pro subscribers.
              </p>
              <a href="/pricing">
                <Button size="sm">
                  <Sparkles className="mr-2 h-4 w-4" />
                  Upgrade to Pro
                </Button>
              </a>
            </div>
          </div>
        </CardContent>
      </Card>
    )
  }

  return <HealthCheckInternal className={className} {...props} />
}

export type { HealthCheckEndpoint, HealthCheckResult, HealthCheckProps }