import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useState, useRef } from 'react'
import { useBreadcrumb } from '../hooks/useBreadcrumb'
import { breadcrumbConfig } from '../config/breadcrumbConfig'
import {
  Globe,
  Shield,
  Cookie,
  RefreshCw,
  CheckCircle,
  XCircle,
  AlertTriangle,
  Clock,
  Upload,
  Trash2,
  ChevronDown,
  ChevronUp,
  ExternalLink,
  Server,
  Instagram,
  Camera,
  Video,
  Eye,
  EyeOff,
  MessageSquare,
  Download,
  Bot,
  Code,
  Save,
  X,
  Key,
  Lock,
  Loader2,
} from 'lucide-react'
import { api, getErrorMessage, type PlatformCredential } from '../lib/api'
import { formatRelativeTime } from '../lib/utils'

interface Scraper {
  id: string
  name: string
  type: string
  module: string | null
  base_url: string | null
  target_platform: string | null
  enabled: boolean
  proxy_enabled: boolean
  proxy_url: string | null
  flaresolverr_required: boolean
  cookies_count?: number
  cookies_fresh?: boolean
  cookies_updated_at: string | null
  last_test_at: string | null
  last_test_status: string | null
  last_test_message: string | null
  settings_json: string | null
  created_at: string
  updated_at: string
}

function StatusBadge({ status }: { status: 'success' | 'error' | 'pending' | 'unknown' }) {
  const styles = {
    success: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-400',
    error: 'bg-red-100 text-red-700 dark:bg-red-500/20 dark:text-red-400',
    pending: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-400',
    unknown: 'bg-slate-100 text-slate-700 dark:bg-slate-500/20 dark:text-slate-400',
  }

  const icons = {
    success: CheckCircle,
    error: XCircle,
    pending: AlertTriangle,
    unknown: Clock,
  }

  const labels = {
    success: 'OK',
    error: 'Failed',
    pending: 'Pending',
    unknown: 'Not Tested',
  }

  const Icon = icons[status]

  return (
    <span className={`inline-flex items-center space-x-1 px-2 py-0.5 text-xs font-medium rounded-full ${styles[status]}`}>
      <Icon className="w-3 h-3" />
      <span>{labels[status]}</span>
    </span>
  )
}

function TypeBadge({ type }: { type: string }) {
  const styles: Record<string, string> = {
    direct: 'bg-blue-100 text-blue-700 dark:bg-blue-500/20 dark:text-blue-400',
    proxy: 'bg-purple-100 text-purple-700 dark:bg-purple-500/20 dark:text-purple-400',
    api: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-400',
    forum: 'bg-orange-100 text-orange-700 dark:bg-orange-500/20 dark:text-orange-400',
    cli_tool: 'bg-cyan-100 text-cyan-700 dark:bg-cyan-500/20 dark:text-cyan-400',
  }

  const labels: Record<string, string> = {
    direct: 'Direct',
    proxy: 'Proxy Service',
    api: 'Authenticated API',
    forum: 'Forum',
    cli_tool: 'CLI Tool',
  }

  return (
    <span className={`px-2 py-0.5 text-xs font-medium rounded ${styles[type] || styles.direct}`}>
      {labels[type] || type}
    </span>
  )
}

function getScraperIcon(scraper: Scraper) {
  if (scraper.target_platform === 'instagram') return Instagram
  if (scraper.target_platform === 'snapchat') return Camera
  if (scraper.target_platform === 'tiktok') return Video
  if (scraper.type === 'forum') return MessageSquare
  if (scraper.type === 'cli_tool') return Download
  return Globe
}

function ScraperCard({
  scraper,
  onUpdate,
  onTest,
  onUploadCookies,
  onUploadCookiesJson,
  onClearCookies,
  isUpdating,
  isTesting,
  platformCredential,
}: {
  scraper: Scraper
  onUpdate: (id: string, updates: any) => void
  onTest: (id: string) => void
  onUploadCookies: (id: string, file: File) => void
  onUploadCookiesJson: (id: string, jsonText: string) => void
  onClearCookies: (id: string) => void
  isUpdating: boolean
  isTesting: boolean
  platformCredential?: PlatformCredential
}) {
  const queryClient = useQueryClient()
  const [expanded, setExpanded] = useState(false)
  const [baseUrl, setBaseUrl] = useState(scraper.base_url || '')
  const [cookiesJson, setCookiesJson] = useState('')
  const [showCookiesTextarea, setShowCookiesTextarea] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const Icon = getScraperIcon(scraper)

  const monitoringMutation = useMutation({
    mutationFn: (enabled: boolean) => api.togglePlatformMonitoring(scraper.id, enabled),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['platform-credentials'] })
      queryClient.invalidateQueries({ queryKey: ['cookie-health'] })
    },
  })

  // YouTube API key state (only used for ytdlp scraper)
  const [youtubeApiKey, setYoutubeApiKey] = useState(() => {
    if (scraper.id === 'ytdlp' && scraper.settings_json) {
      try {
        const settings = JSON.parse(scraper.settings_json)
        return settings.youtube_api_key || ''
      } catch { return '' }
    }
    return ''
  })
  const [showApiKey, setShowApiKey] = useState(false)

  // Parse existing proxy URL into components
  const parseProxyUrl = (url: string | null): { protocol: string; host: string; port: string; username: string; password: string } => {
    if (!url) return { protocol: 'socks5', host: '', port: '', username: '', password: '' }
    try {
      // Format: protocol://user:pass@host:port or protocol://host:port
      const match = url.match(/^(https?|socks[45]?):\/\/(?:([^:]+):([^@]+)@)?([^:]+):(\d+)$/)
      if (match) {
        return {
          protocol: match[1] || 'socks5',
          username: match[2] || '',
          password: match[3] || '',
          host: match[4] || '',
          port: match[5] || '',
        }
      }
    } catch (e) {
      // Failed to parse proxy URL, return defaults
      console.debug('Failed to parse proxy URL:', e)
    }
    return { protocol: 'socks5', host: '', port: '', username: '', password: '' }
  }

  const initialProxy = parseProxyUrl(scraper.proxy_url)
  const [proxyProtocol, setProxyProtocol] = useState(initialProxy.protocol)
  const [proxyHost, setProxyHost] = useState(initialProxy.host)
  const [proxyPort, setProxyPort] = useState(initialProxy.port)
  const [proxyUsername, setProxyUsername] = useState(initialProxy.username)
  const [proxyPassword, setProxyPassword] = useState(initialProxy.password)
  const [showPassword, setShowPassword] = useState(false)

  // Build proxy URL from components
  const buildProxyUrl = (): string | null => {
    if (!proxyHost || !proxyPort) return null
    if (proxyUsername && proxyPassword) {
      return `${proxyProtocol}://${proxyUsername}:${proxyPassword}@${proxyHost}:${proxyPort}`
    }
    return `${proxyProtocol}://${proxyHost}:${proxyPort}`
  }

  const currentProxyUrl = buildProxyUrl()
  const proxyChanged = currentProxyUrl !== scraper.proxy_url

  // Use cookies_count from API (cookies_json is not sent to frontend)
  const cookieCount = scraper.cookies_count || 0

  // Status logic: success if tested successfully OR has valid cookies
  const testStatus = scraper.last_test_status === 'success'
    ? 'success'
    : scraper.last_test_status === 'error' || scraper.last_test_status === 'failed'
    ? 'error'
    : cookieCount > 0
    ? 'success'  // Has cookies = valid status
    : scraper.last_test_at
    ? 'pending'
    : 'unknown'

  const handleProxySave = () => {
    onUpdate(scraper.id, {
      proxy_url: currentProxyUrl,
    })
  }

  const handleBaseUrlSave = () => {
    onUpdate(scraper.id, {
      base_url: baseUrl || null,
    })
  }

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) {
      onUploadCookies(scraper.id, file)
      if (fileInputRef.current) {
        fileInputRef.current.value = ''
      }
    }
  }

  return (
    <div className="card-glass-hover rounded-xl">
      {/* Header */}
      <div
        className="p-3 md:p-4 cursor-pointer hover:bg-secondary/50 transition-colors rounded-t-xl"
        onClick={() => setExpanded(!expanded)}
      >
        {/* Mobile: Stack layout, Desktop: Row layout */}
        <div className="flex items-start md:items-center justify-between gap-3">
          <div className="flex items-center space-x-3 md:space-x-4 min-w-0 flex-1">
            <div className="p-2 rounded-xl bg-secondary flex-shrink-0">
              <Icon className="w-5 h-5 text-muted-foreground" />
            </div>
            <div className="min-w-0 flex-1">
              <div className="flex flex-wrap items-center gap-1.5 md:gap-2">
                <h3 className="font-medium text-foreground">{scraper.name}</h3>
                <TypeBadge type={scraper.type} />
                {scraper.target_platform && (
                  <span className="text-xs text-muted-foreground hidden sm:inline">
                    → {scraper.target_platform}
                  </span>
                )}
              </div>
              <div className="flex flex-wrap items-center gap-2 md:gap-3 mt-1 text-sm text-muted-foreground">
                {scraper.base_url && (
                  <span className="flex items-center space-x-1 hidden md:flex">
                    <ExternalLink className="w-3 h-3" />
                    <span className="truncate max-w-[200px]">{scraper.base_url}</span>
                  </span>
                )}
                {/* Mobile: Show status indicators inline with name */}
                <div className="flex items-center gap-2 md:hidden">
                  {scraper.flaresolverr_required && (
                    <span className="flex items-center space-x-1 text-xs text-amber-600 dark:text-amber-400" title="Requires FlareSolverr">
                      <Shield className="w-3.5 h-3.5" />
                    </span>
                  )}
                  {scraper.proxy_enabled && scraper.proxy_url && (
                    <span className="flex items-center space-x-1 text-xs text-purple-600 dark:text-purple-400" title="Using Proxy">
                      <Server className="w-3.5 h-3.5" />
                    </span>
                  )}
                  {cookieCount > 0 && (
                    <span className="flex items-center space-x-1 text-xs text-blue-600 dark:text-blue-400" title={`${cookieCount} cookies`}>
                      <Cookie className="w-3.5 h-3.5" />
                      <span>{cookieCount}</span>
                    </span>
                  )}
                </div>
              </div>
            </div>
          </div>

          <div className="flex items-center space-x-2 md:space-x-4 flex-shrink-0">
            {/* Desktop: Status indicators */}
            <div className="hidden md:flex items-center space-x-2">
              {scraper.flaresolverr_required && (
                <span className="flex items-center space-x-1 text-xs text-amber-600 dark:text-amber-400" title="Requires FlareSolverr">
                  <Shield className="w-3.5 h-3.5" />
                  <span>CF</span>
                </span>
              )}
              {scraper.proxy_enabled && scraper.proxy_url && (
                <span className="flex items-center space-x-1 text-xs text-purple-600 dark:text-purple-400" title="Using Proxy">
                  <Server className="w-3.5 h-3.5" />
                  <span>Proxy</span>
                </span>
              )}
              {cookieCount > 0 && (
                <span className="flex items-center space-x-1 text-xs text-blue-600 dark:text-blue-400" title={`${cookieCount} cookies`}>
                  <Cookie className="w-3.5 h-3.5" />
                  <span>{cookieCount}</span>
                </span>
              )}
            </div>

            <StatusBadge status={testStatus} />

            {platformCredential && (
              <button
                onClick={(e) => {
                  e.stopPropagation()
                  monitoringMutation.mutate(!platformCredential.monitoring_enabled)
                }}
                className={`p-1.5 rounded-md transition-colors ${
                  platformCredential.monitoring_enabled
                    ? 'text-emerald-600 dark:text-emerald-400 hover:bg-emerald-50 dark:hover:bg-emerald-900/20'
                    : 'text-slate-400 dark:text-slate-500 hover:bg-slate-100 dark:hover:bg-slate-800'
                }`}
                title={platformCredential.monitoring_enabled ? 'Monitoring enabled - click to disable' : 'Monitoring disabled - click to enable'}
              >
                {platformCredential.monitoring_enabled ? <Eye className="w-4 h-4" /> : <EyeOff className="w-4 h-4" />}
              </button>
            )}

            {expanded ? (
              <ChevronUp className="w-5 h-5 text-muted-foreground" />
            ) : (
              <ChevronDown className="w-5 h-5 text-muted-foreground" />
            )}
          </div>
        </div>
      </div>

      {/* Expanded content */}
      {expanded && (
        <div className="px-3 md:px-4 pb-4 pt-2 border-t border-border space-y-4">
          {/* Test status */}
          {scraper.last_test_at && (
            <div className="text-sm">
              <span className="text-muted-foreground">Last test: </span>
              <span className="text-foreground">
                {formatRelativeTime(scraper.last_test_at)}
              </span>
              {scraper.last_test_message && (
                <span className={`ml-2 ${scraper.last_test_status === 'error' ? 'text-red-600 dark:text-red-400' : 'text-muted-foreground'}`}>
                  - {scraper.last_test_message}
                </span>
              )}
            </div>
          )}

          {/* Proxy configuration */}
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <label className="flex items-center space-x-2 text-sm font-medium text-foreground">
                <Server className="w-4 h-4" />
                <span>Proxy Configuration</span>
              </label>
              <button
                onClick={(e) => {
                  e.stopPropagation()
                  onUpdate(scraper.id, { proxy_enabled: !scraper.proxy_enabled })
                }}
                disabled={isUpdating}
                className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
                  scraper.proxy_enabled ? 'bg-blue-600' : 'bg-slate-300 dark:bg-slate-600'
                } ${isUpdating ? 'opacity-50' : ''}`}
              >
                <span
                  className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
                    scraper.proxy_enabled ? 'translate-x-6' : 'translate-x-1'
                  }`}
                />
              </button>
            </div>

            {scraper.proxy_enabled && (
              <div className="space-y-3">
                {/* Protocol and Host/Port row - stacks on mobile */}
                <div className="flex flex-col sm:flex-row gap-2">
                  <select
                    value={proxyProtocol}
                    onChange={(e) => setProxyProtocol(e.target.value)}
                    onClick={(e) => e.stopPropagation()}
                    className="w-full sm:w-28 px-2 py-2 text-sm border border-border rounded-lg bg-background text-foreground"
                  >
                    <option value="socks5">SOCKS5</option>
                    <option value="socks4">SOCKS4</option>
                    <option value="http">HTTP</option>
                    <option value="https">HTTPS</option>
                  </select>
                  <div className="flex gap-2 flex-1">
                    <input
                      type="text"
                      value={proxyHost}
                      onChange={(e) => setProxyHost(e.target.value)}
                      placeholder="Host"
                      className="flex-1 min-w-0 px-3 py-2 text-sm border border-border rounded-lg bg-background text-foreground placeholder-muted-foreground"
                      onClick={(e) => e.stopPropagation()}
                    />
                    <input
                      type="text"
                      value={proxyPort}
                      onChange={(e) => setProxyPort(e.target.value.replace(/\D/g, ''))}
                      placeholder="Port"
                      className="w-20 sm:w-24 px-3 py-2 text-sm border border-border rounded-lg bg-background text-foreground placeholder-muted-foreground"
                      onClick={(e) => e.stopPropagation()}
                    />
                  </div>
                </div>

                {/* Username/Password row - stacks on mobile */}
                <div className="flex flex-col sm:flex-row gap-2">
                  <input
                    type="text"
                    value={proxyUsername}
                    onChange={(e) => setProxyUsername(e.target.value)}
                    placeholder="Username (optional)"
                    className="flex-1 px-3 py-2 text-sm border border-border rounded-lg bg-background text-foreground placeholder-muted-foreground"
                    onClick={(e) => e.stopPropagation()}
                  />
                  <div className="flex-1 relative">
                    <input
                      type={showPassword ? 'text' : 'password'}
                      value={proxyPassword}
                      onChange={(e) => setProxyPassword(e.target.value)}
                      placeholder="Password (optional)"
                      className="w-full px-3 py-2 pr-10 text-sm border border-border rounded-lg bg-background text-foreground placeholder-muted-foreground"
                      onClick={(e) => e.stopPropagation()}
                    />
                    <button
                      type="button"
                      onClick={(e) => {
                        e.stopPropagation()
                        setShowPassword(!showPassword)
                      }}
                      className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
                    >
                      {showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                    </button>
                  </div>
                </div>

                {/* Action buttons - full width on mobile */}
                <div className="flex flex-col sm:flex-row gap-2">
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      handleProxySave()
                    }}
                    disabled={isUpdating || !proxyChanged || !currentProxyUrl}
                    className="flex-1 sm:flex-none px-4 py-2 text-sm bg-primary hover:bg-primary/90 disabled:bg-muted text-primary-foreground rounded-xl transition-colors"
                  >
                    Save Proxy
                  </button>
                  {scraper.proxy_url && (
                    <button
                      onClick={(e) => {
                        e.stopPropagation()
                        setProxyHost('')
                        setProxyPort('')
                        setProxyUsername('')
                        setProxyPassword('')
                        onUpdate(scraper.id, { proxy_enabled: false, proxy_url: null })
                      }}
                      disabled={isUpdating}
                      className="flex-1 sm:flex-none px-3 py-2 text-sm bg-red-600 hover:bg-red-700 disabled:bg-muted text-white rounded-xl transition-colors"
                    >
                      Clear Proxy
                    </button>
                  )}
                </div>

                {/* Warning if fields incomplete */}
                {!currentProxyUrl && (proxyHost || proxyPort) && (
                  <div className="text-xs text-amber-600 dark:text-amber-400">
                    Both host and port are required
                  </div>
                )}

                {/* Preview of constructed URL */}
                {currentProxyUrl && (
                  <div className="text-xs text-muted-foreground font-mono bg-secondary px-2 py-1 rounded-lg">
                    {proxyUsername ? currentProxyUrl.replace(`:${proxyPassword}@`, ':****@') : currentProxyUrl}
                  </div>
                )}
              </div>
            )}
          </div>

          {/* Base URL (if applicable) */}
          {scraper.type === 'proxy' && (
            <div className="space-y-2">
              <label className="flex items-center space-x-2 text-sm font-medium text-foreground">
                <Globe className="w-4 h-4" />
                <span>Base URL</span>
              </label>
              <div className="flex space-x-2">
                <input
                  type="text"
                  value={baseUrl}
                  onChange={(e) => setBaseUrl(e.target.value)}
                  placeholder="https://example.com"
                  className="flex-1 px-3 py-2 text-sm border border-border rounded-lg bg-background text-foreground placeholder-muted-foreground"
                  onClick={(e) => e.stopPropagation()}
                />
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    handleBaseUrlSave()
                  }}
                  disabled={isUpdating || baseUrl === (scraper.base_url || '')}
                  className="px-3 py-2 text-sm bg-primary hover:bg-primary/90 disabled:bg-muted text-primary-foreground rounded-xl transition-colors"
                >
                  Save
                </button>
              </div>
            </div>
          )}

          {/* Cookie management */}
          <div className="space-y-2">
            <label className="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm font-medium text-foreground">
              <Cookie className="w-4 h-4" />
              <span>Cookies</span>
              {cookieCount > 0 && (
                <span className="text-muted-foreground text-xs sm:text-sm">
                  ({cookieCount} cookies
                  {scraper.cookies_updated_at && (
                    <span className="hidden sm:inline">, updated {formatRelativeTime(scraper.cookies_updated_at)}</span>
                  )})
                </span>
              )}
            </label>
            <div className="flex flex-col sm:flex-row gap-2">
              <input
                type="file"
                ref={fileInputRef}
                accept=".json"
                onChange={handleFileUpload}
                className="hidden"
              />
              <button
                onClick={(e) => {
                  e.stopPropagation()
                  fileInputRef.current?.click()
                }}
                disabled={isUpdating}
                className="flex items-center justify-center space-x-2 px-3 py-2 text-sm border border-border hover:bg-secondary rounded-xl transition-colors"
              >
                <Upload className="w-4 h-4" />
                <span>Upload File</span>
              </button>
              <button
                onClick={(e) => {
                  e.stopPropagation()
                  setShowCookiesTextarea(!showCookiesTextarea)
                }}
                disabled={isUpdating}
                className={`flex items-center justify-center space-x-2 px-3 py-2 text-sm border rounded-xl transition-colors ${
                  showCookiesTextarea
                    ? 'border-primary bg-primary/10 text-primary'
                    : 'border-border hover:bg-secondary'
                }`}
              >
                <Code className="w-4 h-4" />
                <span>Paste JSON</span>
              </button>
              {cookieCount > 0 && (
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    if (confirm('Are you sure you want to clear all cookies for this scraper?')) {
                      onClearCookies(scraper.id)
                    }
                  }}
                  disabled={isUpdating}
                  className="flex items-center justify-center space-x-2 px-3 py-2 text-sm text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-xl transition-colors"
                >
                  <Trash2 className="w-4 h-4" />
                  <span>Clear</span>
                </button>
              )}
            </div>

            {/* JSON textarea for pasting cookies */}
            {showCookiesTextarea && (
              <div className="space-y-2 mt-2">
                <textarea
                  value={cookiesJson}
                  onChange={(e) => setCookiesJson(e.target.value)}
                  onClick={(e) => e.stopPropagation()}
                  placeholder='Paste cookies JSON here...&#10;&#10;Supports formats:&#10;- Array: [{"name": "...", "value": "...", ...}]&#10;- Object: {"cookies": [...], "user_agent": "..."}'
                  className="w-full h-32 px-3 py-2 text-sm font-mono border border-border rounded-xl bg-background text-foreground focus:ring-2 focus:ring-primary focus:border-primary"
                />
                <div className="flex gap-2">
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      if (cookiesJson.trim()) {
                        onUploadCookiesJson(scraper.id, cookiesJson)
                        setCookiesJson('')
                        setShowCookiesTextarea(false)
                      }
                    }}
                    disabled={isUpdating || !cookiesJson.trim()}
                    className="flex items-center justify-center space-x-2 px-3 py-2 text-sm bg-primary hover:bg-primary/90 disabled:bg-muted text-primary-foreground rounded-xl transition-colors"
                  >
                    <Save className="w-4 h-4" />
                    <span>Save Cookies</span>
                  </button>
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      setCookiesJson('')
                      setShowCookiesTextarea(false)
                    }}
                    className="flex items-center justify-center space-x-2 px-3 py-2 text-sm border border-border hover:bg-secondary rounded-xl transition-colors"
                  >
                    <X className="w-4 h-4" />
                    <span>Cancel</span>
                  </button>
                </div>
              </div>
            )}
          </div>

          {/* YouTube Data API Key (only for yt-dlp scraper) */}
          {scraper.id === 'ytdlp' && (
            <div className="space-y-2">
              <label className="flex items-center space-x-2 text-sm font-medium text-foreground">
                <Key className="w-4 h-4" />
                <span>YouTube Data API Key</span>
              </label>
              <p className="text-xs text-muted-foreground">
                Optional. Speeds up channel video listing from 20+ minutes to seconds using the YouTube Data API v3.
              </p>
              <div className="flex space-x-2">
                <div className="flex-1 relative">
                  <input
                    type={showApiKey ? 'text' : 'password'}
                    value={youtubeApiKey}
                    onChange={(e) => setYoutubeApiKey(e.target.value)}
                    placeholder="AIza..."
                    className="w-full px-3 py-2 pr-10 text-sm border border-border rounded-lg bg-background text-foreground placeholder-muted-foreground"
                    onClick={(e) => e.stopPropagation()}
                  />
                  <button
                    type="button"
                    onClick={(e) => {
                      e.stopPropagation()
                      setShowApiKey(!showApiKey)
                    }}
                    className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors"
                  >
                    {showApiKey ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                  </button>
                </div>
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    const existingSettings = scraper.settings_json ? JSON.parse(scraper.settings_json) : {}
                    onUpdate(scraper.id, {
                      settings_json: JSON.stringify({ ...existingSettings, youtube_api_key: youtubeApiKey || undefined }),
                    })
                  }}
                  disabled={isUpdating || youtubeApiKey === (() => {
                    if (scraper.settings_json) {
                      try { return JSON.parse(scraper.settings_json).youtube_api_key || '' } catch { return '' }
                    }
                    return ''
                  })()}
                  className="px-3 py-2 text-sm bg-primary hover:bg-primary/90 disabled:bg-muted text-primary-foreground rounded-xl transition-colors"
                >
                  Save
                </button>
              </div>
            </div>
          )}

          {/* Actions - full width on mobile */}
          <div className="flex flex-col sm:flex-row sm:justify-end gap-2 pt-2">
            <button
              onClick={(e) => {
                e.stopPropagation()
                onTest(scraper.id)
              }}
              disabled={isTesting}
              className="flex items-center justify-center space-x-2 px-4 py-2 text-sm bg-emerald-600 hover:bg-emerald-700 disabled:bg-muted text-white rounded-xl transition-colors"
            >
              {isTesting ? (
                <RefreshCw className="w-4 h-4 animate-spin" />
              ) : (
                <RefreshCw className="w-4 h-4" />
              )}
              <span>{isTesting ? 'Testing...' : 'Test Connection'}</span>
            </button>
          </div>
        </div>
      )}
    </div>
  )
}

const SERVICE_ICONS: Record<string, typeof Globe> = {
  onlyfans_direct: Key,
  fansly_direct: Key,
  coomer: Globe,
  kemono: Globe,
  twitch: Video,
  bellazon: Camera,
  reddit: MessageSquare,
}

function ServiceCard({ platform }: { platform: PlatformCredential }) {
  const queryClient = useQueryClient()
  const [expanded, setExpanded] = useState(false)
  const [inputValue, setInputValue] = useState('')
  const [showPasteArea, setShowPasteArea] = useState(false)
  const [parseError, setParseError] = useState('')
  const [isVerifying, setIsVerifying] = useState(false)
  const [verifyResult, setVerifyResult] = useState<{ valid: boolean; username?: string } | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const Icon = SERVICE_ICONS[platform.id] || Globe

  const isConfigured = platform.has_credentials || (platform.cookies_count && platform.cookies_count > 0)

  const monitoringMutation = useMutation({
    mutationFn: (enabled: boolean) => api.togglePlatformMonitoring(platform.id, enabled),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['platform-credentials'] })
      queryClient.invalidateQueries({ queryKey: ['cookie-health'] })
    },
  })

  const updateSessionMutation = useMutation({
    mutationFn: (sessionValue: string) => api.paidContent.updateSession(platform.id, sessionValue),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['platform-credentials'] })
      queryClient.invalidateQueries({ queryKey: ['paid-content-services'] })
      setInputValue('')
      setExpanded(false)
    },
    onError: (error: unknown) => setParseError(getErrorMessage(error)),
  })

  const uploadRedditMutation = useMutation({
    mutationFn: (cookiesJson: string) => api.privateGallery.uploadRedditCookies(cookiesJson),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['platform-credentials'] })
      setInputValue('')
      setExpanded(false)
    },
    onError: (error: unknown) => setParseError(getErrorMessage(error)),
  })

  const deleteRedditMutation = useMutation({
    mutationFn: () => api.privateGallery.deleteRedditCookies(),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['platform-credentials'] })
    },
  })

  const getSessionValue = (raw: string): string => {
    const trimmed = raw.trim()
    if (!trimmed) return ''

    if (trimmed.startsWith('[')) {
      try {
        const cookies = JSON.parse(trimmed)

        if (platform.id === 'onlyfans_direct') {
          const creds: Record<string, string> = {}
          for (const cookie of cookies) {
            const name = (cookie.name || '').toLowerCase()
            if (name === 'sess') creds.sess = cookie.value || ''
            else if (name === 'auth_id') creds.auth_id = cookie.value || ''
            else if (name === 'auth_uid' || name.startsWith('auth_uid_')) creds.auth_uid = cookie.value || ''
          }
          if (creds.sess && creds.auth_id) return JSON.stringify(creds)
          setParseError(`Could not find "sess" and "auth_id" cookies. Found: ${cookies.map((c: any) => c.name).filter(Boolean).join(', ')}`)
          return ''
        }

        if (platform.id === 'fansly_direct') {
          const authCookie = cookies.find((c: any) => c.name === 'fansly-session-id')
          if (authCookie) return authCookie.value
          setParseError(`No "fansly-session-id" cookie found. Found: ${cookies.map((c: any) => c.name).filter(Boolean).join(', ')}`)
          return ''
        }

        const sessionCookie = cookies.find((c: any) => c.name === 'session')
        if (sessionCookie) return sessionCookie.value
        setParseError('No "session" cookie found in JSON')
        return ''
      } catch {
        setParseError('Invalid JSON format')
        return ''
      }
    }

    return trimmed
  }

  const handleSavePaidContent = () => {
    setParseError('')
    const sessionValue = getSessionValue(inputValue)
    if (!sessionValue) return
    updateSessionMutation.mutate(sessionValue)
  }

  const handleSaveRedditCookies = () => {
    setParseError('')
    if (!inputValue.trim()) return
    try {
      const parsed = JSON.parse(inputValue)
      if (!Array.isArray(parsed)) {
        setParseError('Cookies must be a JSON array')
        return
      }
      uploadRedditMutation.mutate(inputValue)
    } catch {
      setParseError('Invalid JSON')
    }
  }

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    setParseError('')

    if (platform.id === 'onlyfans_direct') {
      const reader = new FileReader()
      reader.onload = (ev) => {
        try {
          const raw = ev.target?.result as string
          const parsed = JSON.parse(raw)

          if (Array.isArray(parsed)) {
            let sess = '', authId = '', authUid = ''
            for (const cookie of parsed) {
              const name = (cookie.name || '').toLowerCase()
              if (name === 'sess') sess = cookie.value || ''
              else if (name === 'auth_id') authId = cookie.value || ''
              else if (name === 'auth_uid' || name.startsWith('auth_uid_')) authUid = cookie.value || ''
            }
            if (sess && authId) {
              const creds: any = { sess, auth_id: authId }
              if (authUid) creds.auth_uid = authUid
              setInputValue(JSON.stringify(creds))
              setParseError('')
            } else {
              setParseError('Could not find "sess" and "auth_id" cookies.')
            }
          } else if (parsed?.log?.entries) {
            let sess = '', authId = '', xBc = '', ua = ''
            for (const entry of parsed.log.entries) {
              const url = entry.request?.url || ''
              if (!url.includes('onlyfans.com')) continue
              for (const h of entry.request?.headers || []) {
                const hname = h.name.toLowerCase()
                if (hname === 'cookie') {
                  for (const c of h.value.split(';')) {
                    const t = c.trim()
                    if (t.startsWith('sess=')) sess = t.substring(5)
                    if (t.startsWith('auth_id=')) authId = t.substring(8)
                  }
                }
                if (hname === 'x-bc') xBc = h.value
                if (hname === 'user-agent') ua = h.value
              }
              if (sess && authId) break
            }
            if (sess && authId) {
              const creds: any = { sess, auth_id: authId }
              if (xBc) creds.x_bc = xBc
              if (ua) creds.user_agent = ua
              setInputValue(JSON.stringify(creds))
              setParseError('')
            } else {
              setParseError('Could not find OnlyFans cookies in HAR file.')
            }
          } else {
            setParseError('Unrecognized file format.')
          }
        } catch {
          setParseError('Could not parse file.')
        }
      }
      reader.readAsText(file)
    } else if (platform.source === 'private_gallery') {
      const reader = new FileReader()
      reader.onload = (ev) => {
        setInputValue(ev.target?.result as string || '')
      }
      reader.readAsText(file)
    }
    e.target.value = ''
  }

  const isBusy = updateSessionMutation.isPending || uploadRedditMutation.isPending || deleteRedditMutation.isPending

  const typeBadgeLabel = platform.source === 'private_gallery' ? 'Private Gallery' : 'Paid Content'
  const typeBadgeStyle = platform.source === 'private_gallery'
    ? 'bg-violet-100 text-violet-700 dark:bg-violet-500/20 dark:text-violet-400'
    : 'bg-pink-100 text-pink-700 dark:bg-pink-500/20 dark:text-pink-400'

  const credentialStatus = isConfigured ? 'success' : 'unknown'

  return (
    <div className="card-glass-hover rounded-xl">
      {/* Header */}
      <div
        className={`p-3 md:p-4 transition-colors rounded-t-xl ${
          platform.source === 'private_gallery' && platform.gallery_locked
            ? 'cursor-not-allowed opacity-60'
            : 'cursor-pointer hover:bg-secondary/50'
        }`}
        onClick={() => {
          if (platform.source === 'private_gallery' && platform.gallery_locked) return
          setExpanded(!expanded)
          setParseError('')
          setVerifyResult(null)
        }}
      >
        <div className="flex items-start md:items-center justify-between gap-3">
          <div className="flex items-center space-x-3 md:space-x-4 min-w-0 flex-1">
            <div className="p-2 rounded-xl bg-secondary flex-shrink-0">
              <Icon className="w-5 h-5 text-muted-foreground" />
            </div>
            <div className="min-w-0 flex-1">
              <div className="flex flex-wrap items-center gap-1.5 md:gap-2">
                <h3 className="font-medium text-foreground">{platform.name}</h3>
                <span className={`px-2 py-0.5 text-xs font-medium rounded ${typeBadgeStyle}`}>
                  {typeBadgeLabel}
                </span>
              </div>
              <div className="flex flex-wrap items-center gap-2 md:gap-3 mt-1 text-sm text-muted-foreground">
                {platform.base_url && (
                  <span className="flex items-center space-x-1 hidden md:flex">
                    <ExternalLink className="w-3 h-3" />
                    <span className="truncate max-w-[200px]">{platform.base_url}</span>
                  </span>
                )}
                {/* Mobile: Show status indicators inline */}
                <div className="flex items-center gap-2 md:hidden">
                  {platform.source === 'private_gallery' && platform.gallery_locked && (
                    <span className="flex items-center space-x-1 text-xs text-amber-600 dark:text-amber-400">
                      <Lock className="w-3.5 h-3.5" />
                    </span>
                  )}
                  {platform.cookies_count && platform.cookies_count > 0 ? (
                    <span className="flex items-center space-x-1 text-xs text-blue-600 dark:text-blue-400" title={`${platform.cookies_count} cookies`}>
                      <Cookie className="w-3.5 h-3.5" />
                      <span>{platform.cookies_count}</span>
                    </span>
                  ) : isConfigured ? (
                    <span className="flex items-center space-x-1 text-xs text-emerald-600 dark:text-emerald-400" title="Configured">
                      <CheckCircle className="w-3.5 h-3.5" />
                    </span>
                  ) : null}
                </div>
              </div>
            </div>
          </div>

          <div className="flex items-center space-x-2 md:space-x-4 flex-shrink-0">
            {/* Desktop: Status indicators */}
            <div className="hidden md:flex items-center space-x-2">
              {platform.source === 'private_gallery' && platform.gallery_locked && (
                <span className="flex items-center space-x-1 text-xs text-amber-600 dark:text-amber-400" title="Gallery locked">
                  <Lock className="w-3.5 h-3.5" />
                  <span>Locked</span>
                </span>
              )}
              {platform.cookies_count && platform.cookies_count > 0 ? (
                <span className="flex items-center space-x-1 text-xs text-blue-600 dark:text-blue-400" title={`${platform.cookies_count} cookies`}>
                  <Cookie className="w-3.5 h-3.5" />
                  <span>{platform.cookies_count}</span>
                </span>
              ) : isConfigured ? (
                <span className="flex items-center space-x-1 text-xs text-emerald-600 dark:text-emerald-400" title="Configured">
                  <CheckCircle className="w-3.5 h-3.5" />
                </span>
              ) : null}
            </div>

            <StatusBadge status={credentialStatus} />

            <button
              onClick={(e) => {
                e.stopPropagation()
                monitoringMutation.mutate(!platform.monitoring_enabled)
              }}
              className={`p-1.5 rounded-md transition-colors ${
                platform.monitoring_enabled
                  ? 'text-emerald-600 dark:text-emerald-400 hover:bg-emerald-50 dark:hover:bg-emerald-900/20'
                  : 'text-slate-400 dark:text-slate-500 hover:bg-slate-100 dark:hover:bg-slate-800'
              }`}
              title={platform.monitoring_enabled ? 'Monitoring enabled - click to disable' : 'Monitoring disabled - click to enable'}
            >
              {platform.monitoring_enabled ? <Eye className="w-4 h-4" /> : <EyeOff className="w-4 h-4" />}
            </button>

            {expanded ? (
              <ChevronUp className="w-5 h-5 text-muted-foreground" />
            ) : (
              <ChevronDown className="w-5 h-5 text-muted-foreground" />
            )}
          </div>
        </div>
      </div>

      {/* Expanded content */}
      {expanded && (
        <div className="px-3 md:px-4 pb-4 pt-2 border-t border-border space-y-4">
          <input type="file" ref={fileInputRef} accept=".json,.har,.txt" className="hidden" onChange={handleFileUpload} />

          {/* Credentials section - matches ScraperCard cookie layout */}
          <div className="space-y-2">
            <label className="flex flex-wrap items-center gap-x-2 gap-y-1 text-sm font-medium text-foreground">
              <Key className="w-4 h-4" />
              <span>Credentials</span>
              {isConfigured && (
                <span className="text-muted-foreground text-xs sm:text-sm">
                  (configured{platform.updated_at && (
                    <span className="hidden sm:inline">, updated {formatRelativeTime(platform.updated_at)}</span>
                  )})
                </span>
              )}
            </label>

            {/* Button row: Upload | Paste | Clear/Delete */}
            <div className="flex flex-col sm:flex-row gap-2">
              {(platform.id === 'onlyfans_direct' || platform.source === 'private_gallery') && (
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    fileInputRef.current?.click()
                  }}
                  disabled={isBusy}
                  className="flex items-center justify-center space-x-2 px-3 py-2 text-sm border border-border hover:bg-secondary rounded-xl transition-colors"
                >
                  <Upload className="w-4 h-4" />
                  <span>Upload File</span>
                </button>
              )}
              <button
                onClick={(e) => {
                  e.stopPropagation()
                  setShowPasteArea(!showPasteArea)
                }}
                disabled={isBusy}
                className={`flex items-center justify-center space-x-2 px-3 py-2 text-sm border rounded-xl transition-colors ${
                  showPasteArea
                    ? 'border-primary bg-primary/10 text-primary'
                    : 'border-border hover:bg-secondary'
                }`}
              >
                <Code className="w-4 h-4" />
                <span>Paste</span>
              </button>
              {isConfigured && platform.source === 'private_gallery' && (
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    if (confirm('Delete stored Reddit cookies?')) {
                      deleteRedditMutation.mutate()
                    }
                  }}
                  disabled={isBusy}
                  className="flex items-center justify-center space-x-2 px-3 py-2 text-sm text-red-600 dark:text-red-400 border border-red-300 dark:border-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-xl transition-colors"
                >
                  <Trash2 className="w-4 h-4" />
                  <span>Delete</span>
                </button>
              )}
            </div>

            {/* Paste area - hidden behind toggle, like ScraperCard */}
            {showPasteArea && (
              <div className="space-y-2 mt-2">
                <textarea
                  value={inputValue}
                  onChange={(e) => { setInputValue(e.target.value); setParseError(''); setVerifyResult(null) }}
                  onClick={(e) => e.stopPropagation()}
                  placeholder={
                    platform.id === 'onlyfans_direct'
                      ? 'Paste cookie string, JSON cookie array, or HAR file content...\n\nFormats:\n- Cookie string: sess=VALUE; auth_id=VALUE\n- JSON array: [{"name": "sess", "value": "..."}]\n- JSON object: {"sess": "...", "auth_id": "..."}'
                      : platform.id === 'fansly_direct'
                      ? 'Paste Authorization header value or JSON cookie array...\n\nFormats:\n- Auth token directly\n- JSON array: [{"name": "fansly-session-id", "value": "..."}]'
                      : platform.source === 'private_gallery'
                      ? 'Paste cookies JSON here...\n\n[{"name": "reddit_session", "value": "...", "domain": ".reddit.com", ...}]'
                      : 'Paste session cookie value or JSON cookie export...\n\nFormats:\n- Session value directly\n- JSON array: [{"name": "session", "value": "..."}]'
                  }
                  className="w-full h-32 px-3 py-2 text-sm font-mono border border-border rounded-xl bg-background text-foreground focus:ring-2 focus:ring-primary focus:border-primary"
                />

                {/* Platform-specific help text */}
                {platform.id === 'onlyfans_direct' && (
                  <p className="text-xs text-muted-foreground">
                    <strong>Easiest:</strong> Install "Cookie-Editor" extension, go to onlyfans.com, Export, upload the file above.<br />
                    <strong>Or:</strong> Paste as: <code className="bg-muted px-1 rounded">sess=VALUE; auth_id=VALUE</code>
                  </p>
                )}
                {platform.id === 'fansly_direct' && (
                  <p className="text-xs text-muted-foreground">
                    F12, Network tab, Reload, Click any request, Headers, Copy "Authorization" value
                  </p>
                )}
                {platform.source === 'paid_content' && !['onlyfans_direct', 'fansly_direct'].includes(platform.id) && (
                  <p className="text-xs text-muted-foreground">
                    Paste the session cookie value directly, or paste the full JSON cookie export.
                  </p>
                )}
                {platform.source === 'private_gallery' && (
                  <p className="text-xs text-muted-foreground">
                    Upload browser cookies (JSON array) for accessing age-gated or restricted content. Stored encrypted.
                  </p>
                )}

                {/* Verify result */}
                {verifyResult && (
                  <div className={`text-xs p-2 rounded ${verifyResult.valid ? 'bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300' : 'bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-300'}`}>
                    {platform.id === 'onlyfans_direct'
                      ? (verifyResult.valid ? `Verified! Connected as: ${verifyResult.username}` : 'Invalid credentials. Please check and try again.')
                      : (verifyResult.valid ? `Verified! Connected as: ${verifyResult.username}` : 'Invalid token. Please check and try again.')}
                  </div>
                )}

                {/* Action buttons */}
                <div className="flex gap-2">
                  {/* Verify button for OnlyFans */}
                  {platform.id === 'onlyfans_direct' && (
                    <button
                      onClick={async (e) => {
                        e.stopPropagation()
                        if (!inputValue.trim()) return
                        setIsVerifying(true)
                        setVerifyResult(null)
                        setParseError('')
                        try {
                          let creds: any
                          const input = inputValue.trim()
                          if (input.startsWith('{')) {
                            creds = JSON.parse(input)
                          } else if (input.startsWith('[')) {
                            const cookies = JSON.parse(input)
                            creds = { sess: '', auth_id: '' }
                            for (const cookie of cookies) {
                              const name = (cookie.name || '').toLowerCase()
                              if (name === 'sess') creds.sess = cookie.value || ''
                              else if (name === 'auth_id') creds.auth_id = cookie.value || ''
                              else if (name === 'auth_uid' || name.startsWith('auth_uid_')) creds.auth_uid = cookie.value || ''
                            }
                          } else {
                            creds = { sess: '', auth_id: '' }
                            input.split(';').forEach((c: string) => {
                              const t = c.trim()
                              if (t.startsWith('sess=')) creds.sess = t.substring(5)
                              if (t.startsWith('auth_id=')) creds.auth_id = t.substring(8)
                            })
                          }
                          if (!creds.sess || !creds.auth_id) {
                            setParseError('Could not find sess and auth_id.')
                            return
                          }
                          const result = await api.paidContent.verifyOnlyFansAuth(creds)
                          setVerifyResult(result)
                          if (result.valid) setInputValue(JSON.stringify(creds))
                        } catch {
                          setVerifyResult({ valid: false })
                        } finally {
                          setIsVerifying(false)
                        }
                      }}
                      disabled={isVerifying || !inputValue.trim()}
                      className="flex items-center justify-center space-x-2 px-3 py-2 text-sm border border-border hover:bg-secondary rounded-xl transition-colors"
                    >
                      {isVerifying ? <Loader2 className="w-4 h-4 animate-spin" /> : <CheckCircle className="w-4 h-4" />}
                      <span>Verify</span>
                    </button>
                  )}

                  {/* Verify button for Fansly */}
                  {platform.id === 'fansly_direct' && (
                    <button
                      onClick={async (e) => {
                        e.stopPropagation()
                        if (!inputValue.trim()) return
                        setIsVerifying(true)
                        setVerifyResult(null)
                        try {
                          const result = await api.paidContent.verifyFanslyAuth(getSessionValue(inputValue))
                          setVerifyResult(result)
                        } catch {
                          setVerifyResult({ valid: false })
                        } finally {
                          setIsVerifying(false)
                        }
                      }}
                      disabled={isVerifying || !inputValue.trim()}
                      className="flex items-center justify-center space-x-2 px-3 py-2 text-sm border border-border hover:bg-secondary rounded-xl transition-colors"
                    >
                      {isVerifying ? <Loader2 className="w-4 h-4 animate-spin" /> : <CheckCircle className="w-4 h-4" />}
                      <span>Verify</span>
                    </button>
                  )}

                  {/* Save button */}
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      if (platform.source === 'private_gallery') {
                        handleSaveRedditCookies()
                      } else {
                        handleSavePaidContent()
                      }
                    }}
                    disabled={isBusy || !inputValue.trim()}
                    className="flex items-center justify-center space-x-2 px-3 py-2 text-sm bg-primary hover:bg-primary/90 disabled:bg-muted text-primary-foreground rounded-xl transition-colors"
                  >
                    {(updateSessionMutation.isPending || uploadRedditMutation.isPending) ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
                    <span>{platform.source === 'private_gallery' ? 'Save Cookies' : 'Save'}</span>
                  </button>

                  {/* Cancel button */}
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      setInputValue('')
                      setShowPasteArea(false)
                      setParseError('')
                      setVerifyResult(null)
                    }}
                    className="flex items-center justify-center space-x-2 px-3 py-2 text-sm border border-border hover:bg-secondary rounded-xl transition-colors"
                  >
                    <X className="w-4 h-4" />
                    <span>Cancel</span>
                  </button>
                </div>
              </div>
            )}
          </div>

          {parseError && (
            <p className="text-xs text-red-500">{parseError}</p>
          )}
        </div>
      )}
    </div>
  )
}

export default function Scrapers() {
  useBreadcrumb(breadcrumbConfig['/scrapers'])
  const queryClient = useQueryClient()
  const [testingId, setTestingId] = useState<string | null>(null)
  const [notification, setNotification] = useState<{ type: 'success' | 'error'; message: string } | null>(null)

  const { data, isLoading, error } = useQuery({
    queryKey: ['scrapers'],
    queryFn: () => api.getScrapers(),
  })

  const { data: credentialsData } = useQuery({
    queryKey: ['platform-credentials'],
    queryFn: () => api.getPlatformCredentials(),
  })

  const globalMonitoringMutation = useMutation({
    mutationFn: (enabled: boolean) => api.toggleGlobalMonitoring(enabled),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['platform-credentials'] })
      queryClient.invalidateQueries({ queryKey: ['cookie-health'] })
    },
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, updates }: { id: string; updates: any }) => api.updateScraper(id, updates),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['scrapers'] })
      showNotification('success', 'Scraper updated successfully')
    },
    onError: (error: Error) => {
      showNotification('error', error.message)
    },
  })

  const testMutation = useMutation({
    mutationFn: (id: string) => api.testScraper(id),
    onMutate: (id) => {
      setTestingId(id)
    },
    onSuccess: (result) => {
      queryClient.invalidateQueries({ queryKey: ['scrapers'] })
      if (result.success) {
        showNotification('success', `Test passed: ${result.message}`)
      } else {
        showNotification('error', `Test failed: ${result.message}`)
      }
    },
    onError: (error: Error) => {
      showNotification('error', error.message)
    },
    onSettled: () => {
      setTestingId(null)
    },
  })

  const uploadCookiesMutation = useMutation({
    mutationFn: async ({ id, file }: { id: string; file: File }) => {
      const text = await file.text()
      const data = JSON.parse(text)
      // Support both { cookies: [...] } and [...] formats
      const cookies = Array.isArray(data) ? data : data.cookies
      const userAgent = data.user_agent || data.userAgent
      return api.uploadScraperCookies(id, cookies, userAgent)
    },
    onSuccess: (result) => {
      queryClient.invalidateQueries({ queryKey: ['scrapers'] })
      showNotification('success', `${result.cookies_count} cookies uploaded successfully`)
    },
    onError: (error: Error) => {
      showNotification('error', error.message)
    },
  })

  const uploadCookiesJsonMutation = useMutation({
    mutationFn: async ({ id, jsonText }: { id: string; jsonText: string }) => {
      const data = JSON.parse(jsonText)
      // Support both { cookies: [...] } and [...] formats
      const cookies = Array.isArray(data) ? data : data.cookies
      const userAgent = data.user_agent || data.userAgent
      return api.uploadScraperCookies(id, cookies, userAgent)
    },
    onSuccess: (result) => {
      queryClient.invalidateQueries({ queryKey: ['scrapers'] })
      showNotification('success', `${result.cookies_count} cookies uploaded successfully`)
    },
    onError: (error: Error) => {
      showNotification('error', `Invalid JSON: ${error.message}`)
    },
  })

  const clearCookiesMutation = useMutation({
    mutationFn: (id: string) => api.clearScraperCookies(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['scrapers'] })
      showNotification('success', 'Cookies cleared successfully')
    },
    onError: (error: Error) => {
      showNotification('error', error.message)
    },
  })

  const showNotification = (type: 'success' | 'error', message: string) => {
    setNotification({ type, message })
    setTimeout(() => setNotification(null), 5000)
  }

  const handleUpdate = (id: string, updates: any) => {
    updateMutation.mutate({ id, updates })
  }

  const handleTest = (id: string) => {
    testMutation.mutate(id)
  }

  const handleUploadCookies = (id: string, file: File) => {
    uploadCookiesMutation.mutate({ id, file })
  }

  const handleUploadCookiesJson = (id: string, jsonText: string) => {
    uploadCookiesJsonMutation.mutate({ id, jsonText })
  }

  const handleClearCookies = (id: string) => {
    clearCookiesMutation.mutate(id)
  }

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <RefreshCw className="w-8 h-8 animate-spin text-blue-600" />
      </div>
    )
  }

  if (error) {
    return (
      <div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-6">
        <h3 className="text-lg font-semibold text-red-900 dark:text-red-100 mb-2">Error Loading Scrapers</h3>
        <p className="text-red-700 dark:text-red-300">{error instanceof Error ? error.message : String(error)}</p>
      </div>
    )
  }

  const scrapers = data?.scrapers || []

  // Group scrapers by type
  const groupedScrapers = scrapers.reduce((acc, scraper) => {
    const type = scraper.type
    if (!acc[type]) acc[type] = []
    acc[type].push(scraper)
    return acc
  }, {} as Record<string, Scraper[]>)

  const typeOrder = ['proxy', 'direct', 'api', 'forum', 'cli_tool']
  const typeLabels: Record<string, string> = {
    proxy: 'Proxy Services',
    direct: 'Direct Platforms',
    api: 'Authenticated APIs',
    forum: 'Forums',
    cli_tool: 'CLI Tools',
  }

  return (
    <div className="space-y-6">
      {/* Notification */}
      {notification && (
        <div
          className={`fixed top-4 right-4 z-50 px-4 py-3 rounded-lg shadow-lg flex items-center space-x-2 ${
            notification.type === 'success'
              ? 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-100'
              : 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-100'
          }`}
        >
          {notification.type === 'success' ? (
            <CheckCircle className="w-5 h-5" />
          ) : (
            <XCircle className="w-5 h-5" />
          )}
          <span>{notification.message}</span>
          <button onClick={() => setNotification(null)} className="ml-2 hover:opacity-70">
            <XCircle className="w-4 h-4" />
          </button>
        </div>
      )}

      {/* Header */}
      <div className="flex items-start justify-between flex-wrap gap-3">
        <div>
          <h1 className="text-2xl sm:text-3xl font-bold flex items-center gap-2 sm:gap-3">
            <Bot className="w-8 h-8 text-violet-500" />
            Scrapers
          </h1>
          <p className="text-slate-600 dark:text-slate-400 mt-1">
            Configure proxy settings, cookies, and test connections for all scrapers
          </p>
        </div>
        {credentialsData && (
          <button
            onClick={() => globalMonitoringMutation.mutate(!(credentialsData.global_monitoring_enabled ?? true))}
            disabled={globalMonitoringMutation.isPending}
            className={`flex items-center gap-2 px-3 py-1.5 text-sm rounded-lg border transition-colors ${
              (credentialsData.global_monitoring_enabled ?? true)
                ? 'border-emerald-300 dark:border-emerald-700 bg-emerald-50 dark:bg-emerald-900/20 text-emerald-700 dark:text-emerald-300 hover:bg-emerald-100 dark:hover:bg-emerald-900/30'
                : 'border-border bg-secondary text-muted-foreground hover:bg-secondary/80'
            }`}
            title={(credentialsData.global_monitoring_enabled ?? true) ? 'Click to disable all monitoring' : 'Click to enable all monitoring'}
          >
            {(credentialsData.global_monitoring_enabled ?? true) ? <Eye className="w-4 h-4" /> : <EyeOff className="w-4 h-4" />}
            {(credentialsData.global_monitoring_enabled ?? true) ? 'Monitoring On' : 'Monitoring Off'}
          </button>
        )}
      </div>

      {/* Info box */}
      <div className="glass-gradient-border rounded-xl p-4">
        <div className="flex items-start space-x-3">
          <Shield className="w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5" />
          <div className="text-sm text-blue-800 dark:text-blue-200">
            <p className="font-medium">Cloudflare Protection</p>
            <p className="mt-1 text-blue-700 dark:text-blue-300">
              Scrapers marked with <strong>CF</strong> use FlareSolverr to bypass Cloudflare protection.
              If you configure a proxy, FlareSolverr will use that proxy to solve challenges,
              ensuring cookies are valid for the same IP.
            </p>
          </div>
        </div>
      </div>

      {/* Scraper groups */}
      {typeOrder.map((type) => {
        const scrapersOfType = groupedScrapers[type]
        if (!scrapersOfType || scrapersOfType.length === 0) return null

        return (
          <div key={type} className="space-y-3">
            <h3 className="text-lg font-medium text-foreground">
              {typeLabels[type] || type}
            </h3>
            <div className="space-y-2">
              {scrapersOfType.map((scraper) => (
                <ScraperCard
                  key={scraper.id}
                  scraper={scraper}
                  onUpdate={handleUpdate}
                  onTest={handleTest}
                  onUploadCookies={handleUploadCookies}
                  onUploadCookiesJson={handleUploadCookiesJson}
                  onClearCookies={handleClearCookies}
                  isUpdating={updateMutation.isPending || uploadCookiesMutation.isPending || uploadCookiesJsonMutation.isPending || clearCookiesMutation.isPending}
                  isTesting={testingId === scraper.id}
                  platformCredential={credentialsData?.platforms?.find(p => p.id === scraper.id)}
                />
              ))}
            </div>
          </div>
        )
      })}

      {scrapers.length === 0 && (
        <div className="text-center py-12 text-muted-foreground">
          <Globe className="w-12 h-12 mx-auto mb-4 opacity-50" />
          <p>No scrapers configured</p>
        </div>
      )}

      {/* Paid Content platforms */}
      {(() => {
        const paidContentPlatforms = (credentialsData?.platforms || []).filter(p => p.source === 'paid_content')
        if (paidContentPlatforms.length === 0) return null
        return (
          <div className="space-y-3">
            <h3 className="text-lg font-medium text-foreground">Paid Content</h3>
            <div className="space-y-2">
              {paidContentPlatforms.map(platform => (
                <ServiceCard key={platform.id} platform={platform} />
              ))}
            </div>
          </div>
        )
      })()}

      {/* Private Gallery platforms */}
      {(() => {
        const privateGalleryPlatforms = (credentialsData?.platforms || []).filter(p => p.source === 'private_gallery')
        if (privateGalleryPlatforms.length === 0) return null
        return (
          <div className="space-y-3">
            <h3 className="text-lg font-medium text-foreground">Private Gallery</h3>
            <div className="space-y-2">
              {privateGalleryPlatforms.map(platform => (
                <ServiceCard key={platform.id} platform={platform} />
              ))}
            </div>
          </div>
        )
      })()}
    </div>
  )
}
