import { useState, useCallback } from 'react'
import { motion } from 'framer-motion'
import { Shield, ShieldCheck, ShieldAlert, ShieldX, Play, RotateCw, Wifi, Lock, Unlock, Server, Globe, AlertCircle } from 'lucide-react'
import clsx from 'clsx'

// DNS leak test using multiple public APIs to detect DNS resolver info
const DNS_CHECK_APIS = [
  {
    id: 'dnsleaktest',
    name: 'DNS Leak Test (ipleak.net)',
    url: 'https://ipleak.net/json/dnsleak/',
    extract: (data) => {
      if (Array.isArray(data)) {
        return data.map(item => ({
          ip: item.ip || item.dns_ip || '',
          country: item.country || '',
          isp: item.isp || item.asn || '',
        }))
      }
      return []
    },
    type: 'dns_resolvers',
  },
  {
    id: 'browserleaks',
    name: 'BrowserLeaks (DNS)',
    url: 'https://ipleak.net/json/dnsleak/',
    extract: (data) => {
      if (Array.isArray(data)) {
        return data.map(item => ({
          ip: item.ip || item.dns_ip || '',
          country: item.country || '',
          isp: item.isp || item.asn || '',
        }))
      }
      return []
    },
    type: 'dns_resolvers',
  },
]

// IP check for comparison
const IP_CHECK_APIS = [
  { id: 'ipinfo', name: 'IPInfo.io', url: 'https://ipinfo.io/json' },
  { id: 'ipapi', name: 'IPAPI.co', url: 'https://ipapi.co/json/' },
]

// WebRTC leak detection
function detectWebRTCLeak() {
  return new Promise((resolve) => {
    const ips = new Set()
    const timeout = setTimeout(() => {
      try { window.RTCPeerConnection = null } catch (e) { /* ignore */ }
      resolve({ ips: [...ips], leaked: ips.size > 0 })
    }, 5000)

    try {
      const pc = new RTCPeerConnection({
        iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
      })
      pc.createDataChannel('')
      pc.createOffer().then(offer => pc.setLocalDescription(offer)).catch(() => {})

      pc.onicecandidate = (e) => {
        if (!e.candidate) {
          clearTimeout(timeout)
          pc.close()
          resolve({ ips: [...ips], leaked: ips.size > 0 })
          return
        }
        const parts = e.candidate.candidate.split(' ')
        const ip = parts[4]
        if (ip && !ips.has(ip)) {
          // Filter out mDNS addresses
          if (!ip.endsWith('.local') && ip !== '0.0.0.0') {
            ips.add(ip)
          }
        }
      }
    } catch (e) {
      clearTimeout(timeout)
      resolve({ ips: [], leaked: false, error: 'WebRTC 不可用' })
    }
  })
}

// Step component
function CheckStep({ step, isActive, isDone, status }) {
  const statusIcon = {
    pending: <div className="w-5 h-5 rounded-full border-2 border-slate-300" />,
    active: <div className="w-5 h-5 rounded-full border-2 border-primary-500 animate-pulse" />,
    success: <div className="w-5 h-5 rounded-full bg-secondary-500 flex items-center justify-center"><ShieldCheck className="w-3 h-3 text-white" /></div>,
    warning: <div className="w-5 h-5 rounded-full bg-accent-500 flex items-center justify-center"><AlertCircle className="w-3 h-3 text-white" /></div>,
    error: <div className="w-5 h-5 rounded-full bg-red-500 flex items-center justify-center"><ShieldX className="w-3 h-3 text-white" /></div>,
  }

  return (
    <div className={clsx('flex items-center gap-3 py-2', !isActive && !isDone && 'opacity-50')}>
      {statusIcon[status] || statusIcon.pending}
      <div className="flex-1">
        <span className={clsx('text-sm font-medium', isActive ? 'text-primary-700' : 'text-foreground')}>
          {step}
        </span>
      </div>
      {isActive && (
        <div className="flex gap-1">
          <div className="w-1.5 h-1.5 rounded-full bg-primary-500 animate-bounce" style={{ animationDelay: '0ms' }} />
          <div className="w-1.5 h-1.5 rounded-full bg-primary-500 animate-bounce" style={{ animationDelay: '150ms' }} />
          <div className="w-1.5 h-1.5 rounded-full bg-primary-500 animate-bounce" style={{ animationDelay: '300ms' }} />
        </div>
      )}
    </div>
  )
}

// DNS resolver card
function ResolverCard({ resolver, index }) {
  return (
    <motion.div
      initial={{ opacity: 0, x: -10 }}
      animate={{ opacity: 1, x: 0 }}
      transition={{ delay: index * 0.1 }}
      className="flex items-center gap-3 p-3 rounded-lg bg-white border border-border"
    >
      <Server className="w-4 h-4 text-muted-foreground shrink-0" />
      <div className="flex-1 min-w-0">
        <div className="font-mono text-sm text-foreground">{resolver.ip}</div>
        {resolver.isp && <div className="text-xs text-muted-foreground truncate">{resolver.isp}</div>}
        {resolver.country && <div className="text-xs text-muted-foreground">{resolver.country}</div>}
      </div>
      <Lock className="w-4 h-4 text-secondary-500" />
    </motion.div>
  )
}

// Result summary card
function ResultSummary({ type, title, status, description, icon: Icon }) {
  const config = {
    safe: { bg: 'bg-secondary-50', border: 'border-secondary-200', iconColor: 'text-secondary-500', badge: 'bg-secondary-100 text-secondary-700' },
    warning: { bg: 'bg-accent-50', border: 'border-accent-200', iconColor: 'text-accent-500', badge: 'bg-accent-100 text-accent-700' },
    danger: { bg: 'bg-red-50', border: 'border-red-200', iconColor: 'text-red-500', badge: 'bg-red-100 text-red-700' },
    pending: { bg: 'bg-slate-50', border: 'border-slate-200', iconColor: 'text-slate-400', badge: 'bg-slate-100 text-slate-600' },
  }
  const c = config[status] || config.pending

  return (
    <motion.div
      initial={{ opacity: 0, y: 10 }}
      animate={{ opacity: 1, y: 0 }}
      className={clsx('rounded-xl border p-4', c.bg, c.border)}
    >
      <div className="flex items-start gap-3">
        <Icon className={clsx('w-5 h-5 shrink-0 mt-0.5', c.iconColor)} />
        <div className="flex-1">
          <div className="flex items-center gap-2 mb-1">
            <h4 className="font-semibold text-sm text-foreground">{title}</h4>
            <span className={clsx('px-2 py-0.5 rounded-full text-[10px] font-medium', c.badge)}>
              {status === 'safe' ? '安全' : status === 'warning' ? '注意' : status === 'danger' ? '泄漏' : '待检测'}
            </span>
          </div>
          <p className="text-xs text-muted-foreground">{description}</p>
        </div>
      </div>
    </motion.div>
  )
}

export default function DNSLeak() {
  const [isRunning, setIsRunning] = useState(false)
  const [hasRun, setHasRun] = useState(false)
  const [currentStep, setCurrentStep] = useState(-1)

  // Results
  const [dnsResolvers, setDnsResolvers] = useState([])
  const [webRTCResult, setWebRTCResult] = useState(null)
  const [publicIPs, setPublicIPs] = useState([])
  const [errors, setErrors] = useState([])

  // DNS leak analysis
  const [dnsLeakStatus, setDnsLeakStatus] = useState('pending')
  const [webRTCLeakStatus, setWebRTCLeakStatus] = useState('pending')
  const [ipConsistencyStatus, setIpConsistencyStatus] = useState('pending')

  const runCheck = useCallback(async () => {
    setIsRunning(true)
    setHasRun(true)
    setDnsResolvers([])
    setWebRTCResult(null)
    setPublicIPs([])
    setErrors([])
    setDnsLeakStatus('pending')
    setWebRTCLeakStatus('pending')
    setIpConsistencyStatus('pending')

    // Step 1: Check DNS resolvers
    setCurrentStep(0)
    try {
      const response = await fetch('https://ipleak.net/json/dnsleak/', {
        signal: AbortSignal.timeout(10000),
      })
      if (response.ok) {
        const data = await response.json()
        if (Array.isArray(data) && data.length > 0) {
          const resolvers = data.map(item => ({
            ip: item.ip || '',
            country: item.country || '',
            isp: item.isp || item.asn || '',
          })).filter(r => r.ip)
          setDnsResolvers(resolvers)
          setDnsLeakStatus('safe')
        } else {
          setDnsLeakStatus('warning')
        }
      } else {
        setDnsLeakStatus('warning')
        setErrors(prev => [...prev, 'DNS 查询 API 返回异常'])
      }
    } catch (e) {
      setDnsLeakStatus('warning')
      setErrors(prev => [...prev, `DNS 查询失败: ${e.message}`])
    }

    // Step 2: WebRTC leak detection
    setCurrentStep(1)
    const webrtc = await detectWebRTCLeak()
    setWebRTCResult(webrtc)
    if (webrtc.error) {
      setWebRTCLeakStatus('pending')
    } else if (webrtc.leaked) {
      setWebRTCLeakStatus('danger')
    } else {
      setWebRTCLeakStatus('safe')
    }

    // Step 3: IP consistency check
    setCurrentStep(2)
    const ipResults = []
    for (const api of IP_CHECK_APIS) {
      try {
        const resp = await fetch(api.url, { signal: AbortSignal.timeout(8000) })
        if (resp.ok) {
          const data = await resp.json()
          const ip = data.ip || data.query
          if (ip) ipResults.push(ip)
        }
      } catch (e) {
        // ignore
      }
    }
    setPublicIPs(ipResults)
    const uniqueIPs = [...new Set(ipResults)]
    if (uniqueIPs.length <= 1) {
      setIpConsistencyStatus('safe')
    } else {
      setIpConsistencyStatus('warning')
    }

    setCurrentStep(3)
    setIsRunning(false)
  }, [])

  // Determine overall status
  const overallStatus = hasRun && !isRunning
    ? [dnsLeakStatus, webRTCLeakStatus, ipConsistencyStatus].includes('danger')
      ? 'danger'
      : [dnsLeakStatus, webRTCLeakStatus, ipConsistencyStatus].includes('warning')
        ? 'warning'
        : 'safe'
    : 'pending'

  const steps = [
    '检测 DNS 递归解析服务器',
    '检测 WebRTC 本地 IP 泄漏',
    '检测出口 IP 一致性',
  ]

  return (
    <div className="space-y-6 animate-fade-in">
      {/* Hero */}
      <div className="text-center py-4 sm:py-8">
        <motion.div
          initial={{ opacity: 0, y: -10 }}
          animate={{ opacity: 1, y: 0 }}
          className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-accent-50 text-accent-700 text-xs font-medium mb-4"
        >
          <Shield className="w-3.5 h-3.5" />
          隐私安全检测
        </motion.div>
        <h2 className="text-2xl sm:text-3xl font-bold text-foreground">DNS 泄漏检查</h2>
        <p className="mt-2 text-sm sm:text-base text-muted-foreground max-w-lg mx-auto">
          检测您的 DNS 查询是否通过安全通道，是否存在 WebRTC 泄漏和 IP 一致性问题
        </p>
      </div>

      {/* Action Button */}
      <div className="flex justify-center">
        <button
          onClick={runCheck}
          disabled={isRunning}
          className={`
            flex items-center gap-2.5 px-8 py-3 rounded-xl text-base font-semibold
            transition-all duration-200 shadow-lg hover:shadow-xl active:scale-95
            ${isRunning
              ? 'bg-accent-300 text-white cursor-wait'
              : 'bg-gradient-to-r from-accent-500 to-accent-600 text-white hover:from-accent-600 hover:to-accent-700'
            }
          `}
        >
          {isRunning ? (
            <>
              <RotateCw className="w-5 h-5 animate-spin" />
              检测中...
            </>
          ) : hasRun ? (
            <>
              <RotateCw className="w-5 h-5" />
              重新检测
            </>
          ) : (
            <>
              <Play className="w-5 h-5" />
              开始检测
            </>
          )}
        </button>
      </div>

      {/* Overall Status */}
      {hasRun && !isRunning && (
        <motion.div
          initial={{ opacity: 0, scale: 0.95 }}
          animate={{ opacity: 1, scale: 1 }}
          className={clsx(
            'rounded-xl border-2 p-5 text-center',
            overallStatus === 'safe' && 'bg-secondary-50 border-secondary-300',
            overallStatus === 'warning' && 'bg-accent-50 border-accent-300',
            overallStatus === 'danger' && 'bg-red-50 border-red-300',
          )}
        >
          <div className="flex items-center justify-center gap-3 mb-2">
            {overallStatus === 'safe' && <ShieldCheck className="w-8 h-8 text-secondary-500" />}
            {overallStatus === 'warning' && <ShieldAlert className="w-8 h-8 text-accent-500" />}
            {overallStatus === 'danger' && <ShieldX className="w-8 h-8 text-red-500" />}
            <span className={clsx(
              'text-xl font-bold',
              overallStatus === 'safe' && 'text-secondary-700',
              overallStatus === 'warning' && 'text-accent-700',
              overallStatus === 'danger' && 'text-red-700',
            )}>
              {overallStatus === 'safe' ? '未检测到 DNS 泄漏' : overallStatus === 'warning' ? '存在潜在风险' : '检测到 DNS 泄漏！'}
            </span>
          </div>
          <p className="text-sm text-muted-foreground">
            {overallStatus === 'safe'
              ? '您的 DNS 查询看起来是安全的，未发现明显泄漏'
              : overallStatus === 'warning'
                ? '部分检测项目存在异常，建议进一步检查'
                : '您的 DNS 查询可能正在泄漏，请检查 VPN/代理配置'}
          </p>
        </motion.div>
      )}

      {/* Steps Progress */}
      {isRunning && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          className="card p-5"
        >
          <h3 className="font-semibold text-foreground mb-3">检测进度</h3>
          <div className="space-y-1">
            {steps.map((step, i) => (
              <CheckStep
                key={i}
                step={step}
                isActive={currentStep === i}
                isDone={currentStep > i}
                status={currentStep > i ? 'success' : currentStep === i ? 'active' : 'pending'}
              />
            ))}
          </div>
        </motion.div>
      )}

      {/* Results */}
      {hasRun && !isRunning && (
        <div className="space-y-4">
          {/* Result summaries */}
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
            <ResultSummary
              type="dns"
              title="DNS 解析器"
              status={dnsLeakStatus}
              description={dnsResolvers.length > 0
                ? `检测到 ${dnsResolvers.length} 个 DNS 解析服务器`
                : '未能获取 DNS 解析服务器信息'}
              icon={Server}
            />
            <ResultSummary
              type="webrtc"
              title="WebRTC 泄漏"
              status={webRTCLeakStatus}
              description={webRTCResult?.error
                ? webRTCResult.error
                : webRTCResult?.leaked
                  ? `检测到 ${webRTCResult.ips.length} 个本地 IP 泄漏`
                  : '未检测到 WebRTC IP 泄漏'}
              icon={webRTCLeakStatus === 'safe' ? Lock : Unlock}
            />
            <ResultSummary
              type="ip"
              title="出口 IP 一致性"
              status={ipConsistencyStatus}
              description={publicIPs.length > 0
                ? `检测到 ${[...new Set(publicIPs)].length} 个不同出口 IP`
                : '未能获取出口 IP 信息'}
              icon={Globe}
            />
          </div>

          {/* DNS Resolvers Detail */}
          {dnsResolvers.length > 0 && (
            <motion.div
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              className="card p-5"
            >
              <h3 className="font-semibold text-foreground mb-3 flex items-center gap-2">
                <Server className="w-4 h-4 text-muted-foreground" />
                DNS 解析服务器列表
              </h3>
              <div className="space-y-2">
                {dnsResolvers.map((resolver, i) => (
                  <ResolverCard key={i} resolver={resolver} index={i} />
                ))}
              </div>
              <p className="mt-3 text-xs text-muted-foreground">
                如果 DNS 解析服务器与您的 VPN/代理出口 IP 所属的 ISP 不同，可能存在 DNS 泄漏
              </p>
            </motion.div>
          )}

          {/* WebRTC IPs */}
          {webRTCResult?.leaked && (
            <motion.div
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              className="rounded-xl border-2 border-red-200 bg-red-50 p-5"
            >
              <h3 className="font-semibold text-red-700 mb-3 flex items-center gap-2">
                <Unlock className="w-4 h-4" />
                WebRTC 泄漏的本地 IP
              </h3>
              <div className="space-y-2">
                {webRTCResult.ips.map(ip => (
                  <div key={ip} className="flex items-center gap-2 px-3 py-2 rounded-lg bg-white border border-red-200">
                    <span className="font-mono text-sm text-red-700">{ip}</span>
                  </div>
                ))}
              </div>
              <p className="mt-3 text-xs text-red-600">
                这些 IP 地址通过 WebRTC 泄漏，可能暴露您的真实网络位置。建议在浏览器中禁用 WebRTC
              </p>
            </motion.div>
          )}

          {/* Errors */}
          {errors.length > 0 && (
            <motion.div
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              className="rounded-xl border border-accent-200 bg-accent-50 p-4"
            >
              <h4 className="font-semibold text-accent-700 text-sm mb-2">检测过程中的提示</h4>
              <ul className="space-y-1">
                {errors.map((err, i) => (
                  <li key={i} className="text-xs text-accent-600 flex items-start gap-1.5">
                    <AlertCircle className="w-3 h-3 shrink-0 mt-0.5" />
                    {err}
                  </li>
                ))}
              </ul>
            </motion.div>
          )}
        </div>
      )}

      {/* Explanation */}
      {!hasRun && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ delay: 0.3 }}
          className="card p-5 sm:p-6"
        >
          <h3 className="font-semibold text-foreground mb-3">什么是 DNS 泄漏？</h3>
          <div className="space-y-2 text-sm text-muted-foreground">
            <p>
              当您使用 VPN 或代理时，DNS 查询应该通过加密隧道发送。如果 DNS 请求被发送到了 ISP 的 DNS 服务器，
              而非 VPN 提供商的服务器，就发生了 DNS 泄漏。
            </p>
            <p>
              DNS 泄漏会导致：<br />
              <strong className="text-foreground">ISP 可以追踪</strong>：您的互联网服务提供商可以看到您访问的所有域名<br />
              <strong className="text-foreground">位置暴露</strong>：DNS 服务器的地理位置可能暴露您的真实位置<br />
              <strong className="text-foreground">WebRTC 泄漏</strong>：浏览器的 WebRTC 功能可能绕过 VPN 暴露真实 IP
            </p>
          </div>

          <div className="mt-4 grid grid-cols-1 sm:grid-cols-3 gap-3">
            <div className="p-3 rounded-lg bg-slate-50 border border-border">
              <Server className="w-5 h-5 text-primary-500 mb-2" />
              <h4 className="text-xs font-semibold text-foreground">DNS 解析器检测</h4>
              <p className="text-xs text-muted-foreground mt-1">检测正在使用的 DNS 服务器</p>
            </div>
            <div className="p-3 rounded-lg bg-slate-50 border border-border">
              <Wifi className="w-5 h-5 text-accent-500 mb-2" />
              <h4 className="text-xs font-semibold text-foreground">WebRTC 泄漏检测</h4>
              <p className="text-xs text-muted-foreground mt-1">检测浏览器是否泄漏本地 IP</p>
            </div>
            <div className="p-3 rounded-lg bg-slate-50 border border-border">
              <Globe className="w-5 h-5 text-secondary-500 mb-2" />
              <h4 className="text-xs font-semibold text-foreground">出口 IP 一致性</h4>
              <p className="text-xs text-muted-foreground mt-1">检测多个出口 IP 是否一致</p>
            </div>
          </div>
        </motion.div>
      )}
    </div>
  )
}
