/**
 * OfflineIndicator Component
 *
 * Displays offline mode status, pending message count, and reconnection info.
 * Shows a prominent banner when the app is offline with visual feedback.
 */

import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  WifiOff,
  CloudOff,
  RefreshCw,
  Clock,
  AlertCircle,
  CheckCircle,
  Send,
  X,
  ChevronDown,
  ChevronUp,
} from 'lucide-react';
import { useOfflineStore, type QueuedMessage } from '../store/offlineStore';
import { useConnectionStore } from '../store/connectionStore';

interface OfflineIndicatorProps {
  /** Show compact version (minimal) */
  compact?: boolean;
  /** Show pending messages list */
  showQueue?: boolean;
  /** Additional CSS classes */
  className?: string;
  /** Callback when reconnect button is clicked */
  onReconnect?: () => void;
}

/**
 * Format relative time
 */
function formatRelativeTime(timestamp: number): string {
  const seconds = Math.floor((Date.now() - timestamp) / 1000);

  if (seconds < 60) return '刚刚';
  if (seconds < 3600) return `${Math.floor(seconds / 60)}分钟前`;
  if (seconds < 86400) return `${Math.floor(seconds / 3600)}小时前`;
  return `${Math.floor(seconds / 86400)}天前`;
}

/**
 * Format reconnect delay for display
 */
function formatReconnectDelay(delay: number): string {
  if (delay < 1000) return '立即';
  if (delay < 60000) return `${Math.ceil(delay / 1000)}秒`;
  return `${Math.ceil(delay / 60000)}分钟`;
}

/**
 * Truncate message content for display
 */
function truncateContent(content: string, maxLength: number = 50): string {
  if (content.length <= maxLength) return content;
  return content.slice(0, maxLength) + '...';
}

/**
 * Full offline indicator with banner, queue, and reconnect info
 */
export function OfflineIndicator({
  compact = false,
  showQueue = true,
  className = '',
  onReconnect,
}: OfflineIndicatorProps) {
  const {
    isOffline,
    isReconnecting,
    reconnectAttempt,
    nextReconnectDelay,
    queuedMessages,
    cancelReconnect,
  } = useOfflineStore();

  const connect = useConnectionStore((s) => s.connect);

  const [showMessageQueue, setShowMessageQueue] = useState(false);
  const [countdown, setCountdown] = useState<number | null>(null);

  // Countdown timer for reconnection
  useEffect(() => {
    if (!isReconnecting || !nextReconnectDelay) {
      setCountdown(null);
      return;
    }

    const endTime = Date.now() + nextReconnectDelay;
    setCountdown(nextReconnectDelay);

    const interval = setInterval(() => {
      const remaining = Math.max(0, endTime - Date.now());
      setCountdown(remaining);

      if (remaining === 0) {
        clearInterval(interval);
      }
    }, 1000);

    return () => clearInterval(interval);
  }, [isReconnecting, nextReconnectDelay]);

  // Handle manual reconnect
  const handleReconnect = async () => {
    onReconnect?.();
    try {
      await connect();
    } catch (err) {
      console.error('[OfflineIndicator] Manual reconnect failed:', err);
    }
  };

  const pendingCount = queuedMessages.filter(
    (m) => m.status === 'pending' || m.status === 'failed'
  ).length;

  // Don't show if online and no pending messages
  if (!isOffline && pendingCount === 0) {
    return null;
  }

  // Compact version for headers/toolbars
  if (compact) {
    return (
      <div className={`flex items-center gap-2 ${className}`}>
        {isOffline ? (
          <>
            <CloudOff className="w-4 h-4 text-orange-500" />
            <span className="text-sm text-orange-500 font-medium">
              离线模式
            </span>
            {pendingCount > 0 && (
              <span className="text-xs bg-orange-100 dark:bg-orange-900/30 text-orange-600 dark:text-orange-400 px-1.5 py-0.5 rounded">
                {pendingCount} 条待发
              </span>
            )}
          </>
        ) : (
          <>
            <CheckCircle className="w-4 h-4 text-green-500" />
            <span className="text-sm text-green-500">已恢复连接</span>
            {pendingCount > 0 && (
              <span className="text-xs bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 px-1.5 py-0.5 rounded">
                发送中 {pendingCount} 条
              </span>
            )}
          </>
        )}
      </div>
    );
  }

  // Full banner version
  return (
    <AnimatePresence>
      <motion.div
        initial={{ opacity: 0, y: -20 }}
        animate={{ opacity: 1, y: 0 }}
        exit={{ opacity: 0, y: -20 }}
        className={`${className}`}
      >
        {/* Main Banner */}
        <div
          className={`flex items-center gap-3 px-4 py-3 rounded-lg ${
            isOffline
              ? 'bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800'
              : 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800'
          }`}
        >
          {/* Status Icon */}
          <motion.div
            animate={isReconnecting ? { rotate: 360 } : {}}
            transition={
              isReconnecting
                ? { duration: 1, repeat: Infinity, ease: 'linear' }
                : {}
            }
          >
            {isOffline ? (
              <WifiOff className="w-5 h-5 text-orange-500" />
            ) : (
              <CheckCircle className="w-5 h-5 text-green-500" />
            )}
          </motion.div>

          {/* Status Text */}
          <div className="flex-1">
            <div
              className={`text-sm font-medium ${
                isOffline ? 'text-orange-700 dark:text-orange-400' : 'text-green-700 dark:text-green-400'
              }`}
            >
              {isOffline ? '后端服务不可用' : '连接已恢复'}
            </div>
            <div className="text-xs text-gray-500 dark:text-gray-400">
              {isReconnecting ? (
                <>
                  正在尝试重连 ({reconnectAttempt}次)
                  {countdown !== null && (
                    <span className="ml-2">
                      {formatReconnectDelay(countdown)}后重试
                    </span>
                  )}
                </>
              ) : isOffline ? (
                '消息将保存在本地，连接后自动发送'
              ) : pendingCount > 0 ? (
                `正在发送 ${pendingCount} 条排队消息...`
              ) : (
                '所有消息已同步'
              )}
            </div>
          </div>

          {/* Actions */}
          <div className="flex items-center gap-2">
            {isOffline && !isReconnecting && (
              <button
                onClick={handleReconnect}
                className="flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-white bg-orange-500 hover:bg-orange-600 rounded-md transition-colors"
              >
                <RefreshCw className="w-4 h-4" />
                重连
              </button>
            )}
            {isReconnecting && (
              <button
                onClick={cancelReconnect}
                className="flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-gray-600 dark:text-gray-300 bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-md transition-colors"
              >
                <X className="w-4 h-4" />
                取消
              </button>
            )}
            {showQueue && pendingCount > 0 && (
              <button
                onClick={() => setShowMessageQueue(!showMessageQueue)}
                className="flex items-center gap-1 px-2 py-1 text-xs text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors"
              >
                {showMessageQueue ? (
                  <ChevronUp className="w-4 h-4" />
                ) : (
                  <ChevronDown className="w-4 h-4" />
                )}
                {pendingCount} 条待发
              </button>
            )}
          </div>
        </div>

        {/* Message Queue */}
        <AnimatePresence>
          {showMessageQueue && pendingCount > 0 && (
            <motion.div
              initial={{ opacity: 0, height: 0 }}
              animate={{ opacity: 1, height: 'auto' }}
              exit={{ opacity: 0, height: 0 }}
              className="mt-2 bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden"
            >
              <div className="px-4 py-2 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
                <span className="text-sm font-medium text-gray-700 dark:text-gray-300">
                  排队消息
                </span>
              </div>
              <div className="max-h-48 overflow-y-auto">
                {queuedMessages
                  .filter((m) => m.status === 'pending' || m.status === 'failed')
                  .map((msg) => (
                    <QueuedMessageItem key={msg.id} message={msg} />
                  ))}
              </div>
            </motion.div>
          )}
        </AnimatePresence>
      </motion.div>
    </AnimatePresence>
  );
}

/**
 * Individual queued message item
 */
function QueuedMessageItem({ message }: { message: QueuedMessage }) {
  const { removeMessage } = useOfflineStore();

  const statusConfig = {
    pending: { icon: Clock, color: 'text-gray-400', label: '等待中' },
    sending: { icon: Send, color: 'text-blue-500', label: '发送中' },
    failed: { icon: AlertCircle, color: 'text-red-500', label: '发送失败' },
    sent: { icon: CheckCircle, color: 'text-green-500', label: '已发送' },
  };

  const config = statusConfig[message.status];
  const StatusIcon = config.icon;

  return (
    <div className="flex items-start gap-3 px-4 py-2 border-b border-gray-100 dark:border-gray-800 last:border-b-0">
      <StatusIcon className={`w-4 h-4 mt-0.5 ${config.color}`} />

      <div className="flex-1 min-w-0">
        <p className="text-sm text-gray-700 dark:text-gray-300 truncate">
          {truncateContent(message.content)}
        </p>
        <div className="flex items-center gap-2 mt-1">
          <span className="text-xs text-gray-400">
            {formatRelativeTime(message.timestamp)}
          </span>
          {message.status === 'failed' && message.lastError && (
            <span className="text-xs text-red-500">{message.lastError}</span>
          )}
        </div>
      </div>

      {message.status === 'failed' && (
        <button
          onClick={() => removeMessage(message.id)}
          className="p-1 text-gray-400 hover:text-red-500 transition-colors"
          title="删除消息"
        >
          <X className="w-4 h-4" />
        </button>
      )}
    </div>
  );
}

/**
 * Minimal connection status indicator for headers
 */
export function ConnectionStatusBadge({ className = '' }: { className?: string }) {
  const connectionState = useConnectionStore((s) => s.connectionState);
  const queuedMessages = useOfflineStore((s) => s.queuedMessages);

  const pendingCount = queuedMessages.filter(
    (m) => m.status === 'pending' || m.status === 'failed'
  ).length;

  const isConnected = connectionState === 'connected';

  return (
    <div className={`flex items-center gap-1.5 ${className}`}>
      <span
        className={`w-2 h-2 rounded-full ${
          isConnected
            ? 'bg-green-400'
            : connectionState === 'reconnecting'
            ? 'bg-orange-400 animate-pulse'
            : 'bg-red-400'
        }`}
      />
      <span
        className={`text-xs ${
          isConnected
            ? 'text-green-500'
            : connectionState === 'reconnecting'
            ? 'text-orange-500'
            : 'text-red-500'
        }`}
      >
        {isConnected ? '在线' : connectionState === 'reconnecting' ? '重连中' : '离线'}
      </span>
      {pendingCount > 0 && (
        <span className="text-xs bg-orange-100 dark:bg-orange-900/30 text-orange-600 dark:text-orange-400 px-1.5 py-0.5 rounded">
          {pendingCount}
        </span>
      )}
    </div>
  );
}

export default OfflineIndicator;
