/**
 * ContextUsage Component
 *
 * 显示会话上下文使用情况和压缩控制
 */

import { useState, useEffect, useCallback } from 'react';
import { Zap, AlertTriangle, RefreshCw } from 'lucide-react';
import { toast } from 'sonner';
import { cn } from '../utils/cn';
import { Button } from '../primitives/Button';
import {
  getContextUsage,
  compressContext,
  type ContextUsageInfo,
} from '../api/client.js';

interface ContextUsageProps {
  /** 会话 ID */
  sessionId: string;
  /** 是否显示压缩按钮 */
  showCompressButton?: boolean;
  /** 刷新间隔（毫秒），0 表示不自动刷新 */
  refreshInterval?: number;
  /** 紧凑模式（只显示进度条和数值） */
  compact?: boolean;
  /** 自定义类名 */
  className?: string;
}

/**
 * 获取使用百分比对应的颜色
 */
function getUsageColor(percent: number): string {
  if (percent >= 90) return 'bg-red-500';
  if (percent >= 80) return 'bg-amber-500';
  if (percent >= 60) return 'bg-yellow-500';
  return 'bg-primary-500';
}

/**
 * 获取使用百分比对应的文本颜色
 */
function getTextColor(percent: number): string {
  if (percent >= 90) return 'text-red-400';
  if (percent >= 80) return 'text-amber-400';
  return 'text-fg-muted';
}

export function ContextUsage({
  sessionId,
  showCompressButton = true,
  refreshInterval = 0,
  compact = false,
  className,
}: ContextUsageProps) {
  const [usage, setUsage] = useState<ContextUsageInfo | null>(null);
  const [loading, setLoading] = useState(false);
  const [compressing, setCompressing] = useState(false);

  // 获取上下文使用情况
  const fetchUsage = useCallback(async () => {
    if (!sessionId) return;

    try {
      const response = await getContextUsage(sessionId);
      if (response.success && response.data) {
        setUsage(response.data);
      }
    } catch (error) {
      // 静默失败，不影响用户体验
      console.error('Failed to fetch context usage:', error);
    }
  }, [sessionId]);

  // 初始加载和定时刷新
  useEffect(() => {
    fetchUsage();

    if (refreshInterval > 0) {
      const interval = setInterval(fetchUsage, refreshInterval);
      return () => clearInterval(interval);
    }
  }, [fetchUsage, refreshInterval]);

  // 手动刷新
  const handleRefresh = async () => {
    setLoading(true);
    await fetchUsage();
    setLoading(false);
  };

  // 触发压缩
  const handleCompress = async () => {
    if (!sessionId) return;

    setCompressing(true);
    try {
      const response = await compressContext(sessionId, { force: true });

      if (response.success && response.data) {
        const { status, freedTokens, type } = response.data;

        if (status === 'success') {
          const freedK = (freedTokens / 1000).toFixed(1);
          toast.success(`已释放 ${freedK}K tokens (${type})`);
          // 刷新使用情况
          await fetchUsage();
        } else if (status === 'noop') {
          toast.info('当前无需压缩');
        } else if (status === 'failed_empty_summary') {
          toast.error('压缩失败：生成的摘要为空');
        } else if (status === 'failed_token_inflated') {
          toast.error('压缩失败：摘要比原文更长');
        } else {
          toast.error(`压缩失败：${response.data.error || status}`);
        }
      } else {
        toast.error(response.error || '压缩失败');
      }
    } catch (error) {
      toast.error(error instanceof Error ? error.message : '压缩失败');
    } finally {
      setCompressing(false);
    }
  };

  // 无数据时显示占位
  if (!usage) {
    return (
      <div className={cn('flex items-center gap-2 text-sm text-fg-subtle', className)}>
        <div className="h-2 w-24 bg-surface-muted rounded-full animate-pulse" />
        <span>--</span>
      </div>
    );
  }

  const { usagePercent, formatted, shouldCompress } = usage;
  const barColor = getUsageColor(usagePercent);
  const textColor = getTextColor(usagePercent);

  // 紧凑模式
  if (compact) {
    return (
      <div className={cn('flex items-center gap-2', className)}>
        {/* 进度条 */}
        <div className="relative h-1.5 w-16 bg-surface-muted rounded-full overflow-hidden">
          <div
            className={cn('absolute h-full rounded-full transition-all', barColor)}
            style={{ width: `${Math.min(usagePercent, 100)}%` }}
          />
        </div>
        {/* 数值 */}
        <span className={cn('text-xs', textColor)}>{formatted}</span>
        {/* 警告图标 */}
        {shouldCompress && (
          <AlertTriangle size={12} className="text-amber-500" />
        )}
      </div>
    );
  }

  // 完整模式
  return (
    <div className={cn('space-y-2', className)}>
      {/* 标题行 */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <Zap size={14} className="text-fg-muted" />
          <span className="text-xs font-medium text-fg-secondary">Context Usage</span>
        </div>
        <div className="flex items-center gap-1">
          {/* 刷新按钮 */}
          <Button
            variant="ghost"
            size="icon"
            className="h-6 w-6"
            onClick={handleRefresh}
            disabled={loading}
          >
            <RefreshCw size={12} className={cn(loading && 'animate-spin')} />
          </Button>
          {/* 数值 */}
          <span className={cn('text-xs font-mono', textColor)}>{formatted}</span>
        </div>
      </div>

      {/* 进度条 */}
      <div className="relative h-2 w-full bg-surface-muted rounded-full overflow-hidden">
        <div
          className={cn('absolute h-full rounded-full transition-all duration-300', barColor)}
          style={{ width: `${Math.min(usagePercent, 100)}%` }}
        />
      </div>

      {/* 压缩按钮 */}
      {showCompressButton && shouldCompress && (
        <div className="flex items-center justify-between pt-1">
          <div className="flex items-center gap-1.5 text-amber-500">
            <AlertTriangle size={12} />
            <span className="text-xs">建议压缩上下文</span>
          </div>
          <Button
            variant="ghost"
            size="sm"
            className="h-6 text-xs"
            onClick={handleCompress}
            disabled={compressing}
          >
            {compressing ? '压缩中...' : '压缩'}
          </Button>
        </div>
      )}
    </div>
  );
}
