import { useState, useEffect, type ReactNode } from 'react';
import { motion } from 'motion/react';
import { ArrowRight } from 'lucide-react';
import {
  ShieldFilled, DatabaseFilled, ServerFilled, BoltFilled,
  EyeFilled, EyeOffFilled, CopyFilled, CheckFilled, CrossFilled,
  WarningFilled, RefreshFilled, FlowFilled, CoinFilled,
  LinkExternalFilled, GlobeFilled, PrismFilled,
  YoutubeFilled, VideoFilled, MegaphoneFilled,
} from '@/shared/icons/FilledIcons';
import { PageContainer } from '@/shared/ui/page-container';

/* ───────────────────────────── 타입 ───────────────────────────── */

type ApiStatus = 'connected' | 'missing' | 'error';
type ApiLayer = 'frontend' | 'edge-function' | 'both';

interface ApiConfig {
  id: string;
  name: string;
  description: string;
  envKeys: string[];
  layer: ApiLayer;
  docsUrl: string;
  IconComponent: (props: { size?: number; className?: string }) => ReactNode;
  category: 'ai' | 'scraping' | 'social' | 'platform';
  pricingModel: string;
  usedInPhases: string[];
  estimatedCostPerRun?: string;
  rateLimit?: string;
  notes?: string;
}

interface ApiStatusInfo extends ApiConfig {
  status: ApiStatus;
  keyPresent: Record<string, boolean>;
}

/* ──────────────────── API 레지스트리 (단일 진실 공급원) ──────────── */

const API_REGISTRY: ApiConfig[] = [
  // TODO(migration): 백엔드 플랫폼 (FastAPI) 의 메타 정보는 별도 엔드포인트가 없어 레지스트리에서 제외.
  {
    id: 'perplexity',
    name: 'Perplexity AI',
    description: 'LLM 기반 시장 분석 및 리포트 생성',
    envKeys: ['PERPLEXITY_API_KEY'],
    layer: 'edge-function',
    docsUrl: 'https://docs.perplexity.ai',
    IconComponent: PrismFilled,
    category: 'ai',
    pricingModel: 'Sonar: $1/1K requests',
    usedInPhases: ['Phase 1: discover', 'Phase 2: collect', 'Phase 3: generate'],
    estimatedCostPerRun: '~$0.05-0.15',
    rateLimit: '50 RPM (rate limit)',
    notes: 'discover(2회) + collect(4회 병렬) + generate(1회) = 분석당 ~7회 호출',
  },
  {
    id: 'firecrawl',
    name: 'Firecrawl',
    description: '웹 스크래핑, 스크린샷 캡처, 구조화 데이터 추출',
    envKeys: ['FIRECRAWL_API_KEY'],
    layer: 'edge-function',
    docsUrl: 'https://docs.firecrawl.dev',
    IconComponent: GlobeFilled,
    category: 'scraping',
    pricingModel: 'Free 500 credits → $19/mo',
    usedInPhases: ['Phase 1: discover', 'Phase 2: collect'],
    estimatedCostPerRun: '~5-10 credits',
    rateLimit: '3 RPM (free), 20 RPM (paid)',
    notes: 'scrape + map + search + fullPage screenshot',
  },
  {
    id: 'apify',
    name: 'Apify',
    description: 'Instagram/Facebook 데이터 수집',
    envKeys: ['APIFY_API_TOKEN'],
    layer: 'edge-function',
    docsUrl: 'https://docs.apify.com',
    IconComponent: ServerFilled,
    category: 'scraping',
    pricingModel: 'Free $5/mo → Starter $49/mo',
    usedInPhases: ['Phase 1: discover', 'Phase 2: collect', 'Enrich'],
    estimatedCostPerRun: '~$0.10-0.30',
    rateLimit: 'Actor-dependent (30-120s timeout)',
    notes: 'IG profile/posts/reels + FB pages actors',
  },
  {
    id: 'google-places',
    name: 'Google Places API (New)',
    description: 'Google Maps 장소 검색, 평점, 리뷰, 연락처 데이터',
    envKeys: ['GOOGLE_PLACES_API_KEY'],
    layer: 'edge-function',
    docsUrl: 'https://developers.google.com/maps/documentation/places/web-service',
    IconComponent: GlobeFilled,
    category: 'social',
    pricingModel: '$200/mo 무료 크레딧 포함',
    usedInPhases: ['Phase 2: collect', 'Enrich', 'Registry enrichment'],
    estimatedCostPerRun: '~$0.04',
    rateLimit: 'No hard limit (pay-as-you-go)',
    notes: 'Text Search + Place Details (1-2초 응답, Apify 대비 30x 빠름)',
  },
  {
    id: 'youtube',
    name: 'YouTube Data API v3',
    description: 'YouTube 채널 검색, 통계, 영상 데이터',
    envKeys: ['YOUTUBE_API_KEY'],
    layer: 'edge-function',
    docsUrl: 'https://developers.google.com/youtube/v3',
    IconComponent: YoutubeFilled,
    category: 'social',
    pricingModel: 'Free (10,000 units/day)',
    usedInPhases: ['Phase 1: discover', 'Phase 2: collect'],
    estimatedCostPerRun: '~200-400 units',
    rateLimit: '10,000 units/day',
    notes: 'search(100u) + channels(5u) + videos(5u each)',
  },
  {
    id: 'naver',
    name: 'Naver Search API',
    description: '네이버 블로그/웹/플레이스 검색',
    envKeys: ['NAVER_CLIENT_ID', 'NAVER_CLIENT_SECRET'],
    layer: 'edge-function',
    docsUrl: 'https://developers.naver.com/docs/serviceapi/search/blog/blog.md',
    IconComponent: MegaphoneFilled,
    category: 'social',
    pricingModel: 'Free (25,000/day)',
    usedInPhases: ['Phase 1: discover', 'Phase 2: collect'],
    estimatedCostPerRun: 'Free',
    rateLimit: '25,000 calls/day',
    notes: 'blog.json + webkr.json + local.json',
  },
  {
    id: 'gemini',
    name: 'Google Gemini',
    description: 'AI 이미지 생성 + Vision 분석 (스크린샷 OCR)',
    envKeys: ['GEMINI_API_KEY'],
    layer: 'both',
    docsUrl: 'https://ai.google.dev/docs',
    IconComponent: DatabaseFilled,
    category: 'ai',
    pricingModel: 'Free tier → Pay-as-you-go',
    usedInPhases: ['Phase 2: collect (Vision)', 'Studio (Image Gen)'],
    estimatedCostPerRun: '~$0.01-0.05',
    rateLimit: '15 RPM (free), 1000 RPM (paid)',
    notes: 'gemini-2.5-flash-image 모델 사용',
  },
  {
    id: 'creatomate',
    name: 'Creatomate',
    description: '마케팅 영상 자동 생성 (템플릿 기반)',
    envKeys: ['VITE_CREATOMATE_API_KEY'],
    layer: 'frontend',
    docsUrl: 'https://creatomate.com/docs/api/introduction',
    IconComponent: VideoFilled,
    category: 'ai',
    pricingModel: 'Free 5 renders → Pro $39/mo',
    usedInPhases: ['Studio'],
    estimatedCostPerRun: '1 render credit',
    rateLimit: '2 concurrent renders (free)',
    notes: 'POST /renders → poll until complete',
  },
];

/* ────────────────── 환경변수 체커 ─────────────── */

function checkEnvVars(): ApiStatusInfo[] {
  return API_REGISTRY.map((api) => {
    const keyPresent: Record<string, boolean> = {};
    for (const key of api.envKeys) {
      if (key.startsWith('VITE_')) {
        const val = (import.meta.env as Record<string, string | undefined>)[key];
        keyPresent[key] = !!val && val.length > 0;
      } else {
        keyPresent[key] = true;
      }
    }

    const allPresent = Object.values(keyPresent).every(Boolean);
    const nonePresent = Object.values(keyPresent).every((v) => !v);

    return {
      ...api,
      status: nonePresent ? 'missing' : allPresent ? 'connected' : 'error',
      keyPresent,
    };
  });
}

/* ──────────────────────── 서브 컴포넌트 ──────────────────────── */

function StatusDot({ status }: { status: ApiStatus }) {
  const styles = {
    connected: 'bg-status-good-dot',
    missing: 'bg-status-critical-dot',
    error: 'bg-status-warning-dot',
  };
  return (
    <span className="relative flex h-3 w-3">
      {status === 'connected' && (
        <span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-40 ${styles[status]}`} />
      )}
      <span className={`relative inline-flex rounded-full h-3 w-3 ${styles[status]}`} />
    </span>
  );
}

function StatusBadge({ status }: { status: ApiStatus }) {
  const config = {
    connected: { bg: 'bg-status-good-bg', text: 'text-status-good-text', border: 'border-status-good-border', label: 'Connected', Icon: CheckFilled },
    missing: { bg: 'bg-status-critical-bg', text: 'text-status-critical-text', border: 'border-status-critical-border', label: 'Missing Key', Icon: CrossFilled },
    error: { bg: 'bg-status-warning-bg', text: 'text-status-warning-text', border: 'border-status-warning-border', label: 'Partial', Icon: WarningFilled },
  };
  const c = config[status];
  return (
    <span className={`inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-semibold rounded-full border ${c.bg} ${c.text} ${c.border}`}>
      <c.Icon size={12} className={c.text} />
      {c.label}
    </span>
  );
}

function LayerBadge({ layer }: { layer: ApiLayer }) {
  const config = {
    frontend: { bg: 'bg-status-info-bg', text: 'text-status-info-text', border: 'border-status-info-border', label: 'Frontend', Icon: GlobeFilled },
    'edge-function': { bg: 'bg-status-good-bg', text: 'text-status-good-text', border: 'border-status-good-border', label: 'Edge Function', Icon: ServerFilled },
    both: { bg: 'bg-status-warning-bg', text: 'text-status-warning-text', border: 'border-status-warning-border', label: 'Both', Icon: BoltFilled },
  };
  const c = config[layer];
  return (
    <span className={`inline-flex items-center gap-1 px-2 py-0.5 text-[11px] font-medium rounded-md border ${c.bg} ${c.text} ${c.border}`}>
      <c.Icon size={12} className={c.text} />
      {c.label}
    </span>
  );
}

function CategoryBadge({ category }: { category: ApiConfig['category'] }) {
  const config = {
    ai: { bg: 'bg-status-good-bg', text: 'text-status-good-text', label: 'AI' },
    scraping: { bg: 'bg-status-warning-bg', text: 'text-status-warning-text', label: 'Scraping' },
    social: { bg: 'bg-status-info-bg', text: 'text-status-info-text', label: 'Social' },
    platform: { bg: 'bg-primary-50', text: 'text-primary-800', label: 'Platform' },
  };
  const c = config[category];
  return (
    <span className={`px-2 py-0.5 text-[11px] font-medium rounded-md ${c.bg} ${c.text}`}>
      {c.label}
    </span>
  );
}

function EnvKeyRow({ envKey, present, isServerSide }: { envKey: string; present: boolean; isServerSide: boolean }) {
  const [showKey, setShowKey] = useState(false);
  const [copied, setCopied] = useState(false);

  const value = isServerSide
    ? '(Edge Function 환경변수 — 프론트엔드에서 확인 불가)'
    : showKey
      ? (import.meta.env as Record<string, string | undefined>)[envKey] || ''
      : '••••••••••••••••';

  const handleCopy = () => {
    if (!isServerSide) {
      navigator.clipboard.writeText((import.meta.env as Record<string, string | undefined>)[envKey] || '');
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    }
  };

  return (
    <div className="flex items-center gap-2 py-1.5 px-3 rounded-lg bg-primary-50 text-xs font-mono group">
      <StatusDot status={present ? 'connected' : 'missing'} />
      <span className="text-slate-500 min-w-[200px]">{envKey}</span>
      <span className="text-slate-400 flex-1 truncate">{value}</span>
      {!isServerSide && (
        <div className="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
          <button onClick={() => setShowKey(!showKey)} className="p-1 hover:bg-slate-200 rounded">
            {showKey
              ? <EyeOffFilled size={14} className="text-slate-400" />
              : <EyeFilled size={14} className="text-slate-400" />}
          </button>
          <button onClick={handleCopy} className="p-1 hover:bg-slate-200 rounded">
            {copied
              ? <CheckFilled size={14} className="text-status-good-dot" />
              : <CopyFilled size={14} className="text-slate-400" />}
          </button>
        </div>
      )}
    </div>
  );
}

function ApiCard({ api, index }: { api: ApiStatusInfo; index: number }) {
  const [expanded, setExpanded] = useState(false);

  return (
    <motion.div
      initial={{ opacity: 0, y: 16 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3, delay: index * 0.05 }}
      className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] hover:shadow-[4px_6px_16px_rgba(0,0,0,0.09)] transition-shadow overflow-hidden"
    >
      {/* Header */}
      <button
        onClick={() => setExpanded(!expanded)}
        className="w-full px-6 py-5 flex items-center gap-4 text-left"
      >
        <div className="flex-shrink-0 w-10 h-10 rounded-xl bg-accent/10 flex items-center justify-center">
          <api.IconComponent size={20} className="text-accent" />
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1">
            <h3 className="font-serif font-bold text-primary-900 text-base">{api.name}</h3>
            <StatusDot status={api.status} />
          </div>
          <p className="text-xs text-slate-500 truncate">{api.description}</p>
        </div>
        <div className="flex items-center gap-2 flex-shrink-0">
          <CategoryBadge category={api.category} />
          <LayerBadge layer={api.layer} />
          <StatusBadge status={api.status} />
        </div>
      </button>

      {/* Expandable detail */}
      {expanded && (
        <motion.div
          initial={{ height: 0, opacity: 0 }}
          animate={{ height: 'auto', opacity: 1 }}
          transition={{ duration: 0.2 }}
          className="border-t border-slate-100 px-6 py-4 space-y-4"
        >
          {/* Env Keys */}
          <div>
            <h4 className="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Environment Variables</h4>
            <div className="space-y-1.5">
              {api.envKeys.map((key) => (
                <EnvKeyRow
                  key={key}
                  envKey={key}
                  present={api.keyPresent[key]}
                  isServerSide={!key.startsWith('VITE_')}
                />
              ))}
            </div>
          </div>

          {/* Info Grid */}
          <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
            <div className="bg-primary-50 rounded-xl p-3">
              <div className="text-[11px] text-slate-400 font-medium mb-1">Pricing</div>
              <div className="text-xs font-semibold text-slate-700">{api.pricingModel}</div>
            </div>
            {api.estimatedCostPerRun && (
              <div className="bg-primary-50 rounded-xl p-3">
                <div className="text-[11px] text-slate-400 font-medium mb-1">Cost / Run</div>
                <div className="text-xs font-semibold text-slate-700">{api.estimatedCostPerRun}</div>
              </div>
            )}
            {api.rateLimit && (
              <div className="bg-primary-50 rounded-xl p-3">
                <div className="text-[11px] text-slate-400 font-medium mb-1">Rate Limit</div>
                <div className="text-xs font-semibold text-slate-700">{api.rateLimit}</div>
              </div>
            )}
            <div className="bg-primary-50 rounded-xl p-3">
              <div className="text-[11px] text-slate-400 font-medium mb-1">Used In</div>
              <div className="text-xs font-semibold text-slate-700">{api.usedInPhases.join(', ')}</div>
            </div>
          </div>

          {/* Notes + Docs link */}
          <div className="flex items-center justify-between">
            {api.notes && (
              <p className="text-xs text-slate-500 italic">{api.notes}</p>
            )}
            <a
              href={api.docsUrl}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center gap-1 text-xs font-medium text-accent hover:underline flex-shrink-0"
            >
              API Docs <LinkExternalFilled size={12} className="text-accent" />
            </a>
          </div>
        </motion.div>
      )}
    </motion.div>
  );
}

/* ──────────────────── 파이프라인 플로우 다이어그램 ───────────────────── */

function PipelineFlow({ apis }: { apis: ApiStatusInfo[] }) {
  const phases = [
    { name: 'Phase 1', label: 'Discover Channels', apis: ['firecrawl', 'youtube', 'naver', 'perplexity', 'apify'] },
    { name: 'Phase 2', label: 'Collect Data', apis: ['apify', 'youtube', 'firecrawl', 'naver', 'perplexity', 'gemini'] },
    { name: 'Phase 3', label: 'Generate Report', apis: ['perplexity'] },
    { name: 'Studio', label: 'Content Creation', apis: ['gemini', 'creatomate'] },
  ];

  const apiMap = Object.fromEntries(apis.map((a) => [a.id, a]));

  return (
    <div className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] p-6">
      <h3 className="font-serif font-bold text-primary-900 text-base mb-5 flex items-center gap-2">
        <FlowFilled size={18} className="text-accent" />
        Pipeline API Flow
      </h3>
      <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
        {phases.map((phase, idx) => (
          <div key={phase.name} className="relative">
            <div className="bg-gradient-to-r from-[#4F1DA1] to-[#021341] text-white text-xs font-bold px-3 py-1.5 rounded-t-xl">
              {phase.name}: {phase.label}
            </div>
            <div className="border border-t-0 border-slate-200 rounded-b-xl p-3 space-y-1.5 min-h-[100px]">
              {phase.apis.map((apiId) => {
                const api = apiMap[apiId];
                if (!api) return null;
                return (
                  <div key={apiId} className="flex items-center gap-2 text-xs">
                    <StatusDot status={api.status} />
                    <api.IconComponent size={14} className="text-slate-400" />
                    <span className="text-slate-600">{api.name}</span>
                  </div>
                );
              })}
            </div>
            {idx < phases.length - 1 && (
              <div className="hidden md:flex absolute -right-3 top-1/2 transform -translate-y-1/2 z-10">
                <ArrowRight className="w-4 h-4 text-slate-300" />
              </div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

/* ────────────────────── 비용 추정기 ────────────────────────── */

function CostEstimator({ apis }: { apis: ApiStatusInfo[] }) {
  const costItems = apis
    .filter((a) => a.estimatedCostPerRun)
    .map((a) => ({
      name: a.name,
      IconComponent: a.IconComponent,
      cost: a.estimatedCostPerRun!,
    }));

  return (
    <div className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] p-6">
      <h3 className="font-serif font-bold text-primary-900 text-base mb-4 flex items-center gap-2">
        <CoinFilled size={18} className="text-accent" />
        Estimated Cost per Analysis Run
      </h3>
      <div className="space-y-2">
        {costItems.map((item) => (
          <div key={item.name} className="flex items-center justify-between py-2 px-3 bg-primary-50 rounded-xl">
            <span className="text-sm text-slate-700 flex items-center gap-2">
              <item.IconComponent size={16} className="text-slate-400" />
              {item.name}
            </span>
            <span className="text-sm font-bold text-primary-900">{item.cost}</span>
          </div>
        ))}
        <div className="flex items-center justify-between py-3 px-3 bg-accent/5 rounded-xl border border-accent/20 mt-3">
          <span className="text-sm font-bold text-primary-900">Total (estimated)</span>
          <span className="text-sm font-black text-accent">~$0.26-0.80 / run</span>
        </div>
      </div>
    </div>
  );
}

/* ──────────────────────── 메인 페이지 ───────────────────────────── */

export default function ApiDashboardPage() {
  const [apis, setApis] = useState<ApiStatusInfo[]>([]);
  const [lastChecked, setLastChecked] = useState<Date | null>(null);
  const [filter, setFilter] = useState<'all' | 'connected' | 'missing'>('all');

  const refreshStatus = () => {
    setApis(checkEnvVars());
    setLastChecked(new Date());
  };

  useEffect(() => {
    refreshStatus();
  }, []);

  const connectedCount = apis.filter((a) => a.status === 'connected').length;
  const missingCount = apis.filter((a) => a.status === 'missing').length;
  const errorCount = apis.filter((a) => a.status === 'error').length;

  const filteredApis = filter === 'all' ? apis : apis.filter((a) => a.status === filter);

  return (
    <div className="min-h-screen bg-slate-50 pt-28 pb-16 px-6">
      <PageContainer className="space-y-8 px-0">

        {/* Page Header */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5 }}
        >
          <div className="flex items-center gap-3 mb-2">
            <div className="p-2.5 bg-accent/10 rounded-xl">
              <ShieldFilled size={24} className="text-accent" />
            </div>
            <div>
              <h1 className="font-serif text-3xl font-bold text-primary-900">API Dashboard</h1>
              <p className="text-sm text-slate-500">API 연결 상태, 환경변수, 사용량, 비용 현황</p>
            </div>
          </div>
        </motion.div>

        {/* Summary Cards */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5, delay: 0.1 }}
          className="grid grid-cols-2 md:grid-cols-4 gap-4"
        >
          <div className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] p-5">
            <div className="flex items-center gap-2 mb-2">
              <DatabaseFilled size={16} className="text-slate-400" />
              <span className="text-xs font-medium text-slate-400 uppercase tracking-wider">Total APIs</span>
            </div>
            <div className="text-3xl font-black text-primary-900">{apis.length}</div>
          </div>
          <div className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] p-5">
            <div className="flex items-center gap-2 mb-2">
              <CheckFilled size={16} className="text-status-good-dot" />
              <span className="text-xs font-medium text-slate-400 uppercase tracking-wider">Connected</span>
            </div>
            <div className="text-3xl font-black text-status-good-text">{connectedCount}</div>
          </div>
          <div className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] p-5">
            <div className="flex items-center gap-2 mb-2">
              <CrossFilled size={16} className="text-status-critical-dot" />
              <span className="text-xs font-medium text-slate-400 uppercase tracking-wider">Missing</span>
            </div>
            <div className="text-3xl font-black text-status-critical-text">{missingCount}</div>
          </div>
          <div className="bg-white rounded-2xl border border-slate-100 shadow-[3px_4px_12px_rgba(0,0,0,0.06)] p-5">
            <div className="flex items-center gap-2 mb-2">
              <WarningFilled size={16} className="text-status-warning-dot" />
              <span className="text-xs font-medium text-slate-400 uppercase tracking-wider">Partial</span>
            </div>
            <div className="text-3xl font-black text-status-warning-text">{errorCount}</div>
          </div>
        </motion.div>

        {/* Pipeline Flow */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5, delay: 0.15 }}
        >
          <PipelineFlow apis={apis} />
        </motion.div>

        {/* Filter + Refresh */}
        <div className="flex items-center justify-between">
          <div className="flex gap-2">
            {(['all', 'connected', 'missing'] as const).map((f) => (
              <button
                key={f}
                onClick={() => setFilter(f)}
                className={`px-5 py-2.5 text-xs font-semibold rounded-full transition-all ${
                  filter === f
                    ? 'bg-gradient-to-r from-[#4F1DA1] to-[#021341] text-white shadow-[3px_4px_12px_rgba(0,0,0,0.06)]'
                    : 'bg-white text-slate-500 border border-slate-200 hover:bg-slate-50'
                }`}
              >
                {f === 'all' ? 'All' : f === 'connected' ? 'Connected' : 'Missing'}
              </button>
            ))}
          </div>
          <div className="flex items-center gap-3">
            {lastChecked && (
              <span className="text-xs text-slate-400">
                Last checked: {lastChecked.toLocaleTimeString('ko-KR')}
              </span>
            )}
            <button
              onClick={refreshStatus}
              className="inline-flex items-center gap-1.5 px-5 py-2.5 text-xs font-semibold bg-white border border-slate-200 rounded-full hover:bg-slate-50 transition-all text-slate-600"
            >
              <RefreshFilled size={14} className="text-slate-500" />
              Refresh
            </button>
          </div>
        </div>

        {/* API Cards */}
        <div className="space-y-3">
          {filteredApis.map((api, idx) => (
            <ApiCard key={api.id} api={api} index={idx} />
          ))}
        </div>

        {/* Cost Estimator */}
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5, delay: 0.2 }}
        >
          <CostEstimator apis={apis} />
        </motion.div>

        {/* Footer note */}
        <div className="text-center text-xs text-slate-400 pt-4">
          <PrismFilled size={14} className="text-slate-300 inline mr-1" />
          VITE_ 접두사 키만 프론트엔드에서 확인 가능합니다. 서버 키는 백엔드 환경설정에서 확인하세요.
        </div>
      </PageContainer>
    </div>
  );
}
