/**
 * Sidebar Component
 *
 * 支持响应式：responsive=true 时桌面端固定显示，移动端抽屉式菜单
 */

import { useState, useEffect, forwardRef } from 'react';
import { Plus, MessageSquare, Trash2, Menu, X, MessageCircle } from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { toast } from 'sonner';
import { cn } from '../utils/cn';
import { fadeInUp, smoothTransition } from '../utils/animations';
import { listSessions, createSession, deleteSession, type Session } from '../api/client.js';
import { SessionSkeleton } from './Skeleton';
import { ThemeToggleCompact } from './ThemeToggle';

interface SidebarProps {
  currentSessionId: string | null;
  onSelectSession: (id: string) => void;
  onCreateSession: (session: Session) => void;
  /** 是否启用响应式布局（移动端抽屉式菜单） */
  responsive?: boolean;
  /** 会话标题更新事件（从 WebSocket 接收） */
  sessionTitleUpdate?: { sessionId: string; name: string } | null;
}

export function Sidebar({
  currentSessionId,
  onSelectSession,
  onCreateSession,
  responsive = false,
  sessionTitleUpdate,
}: SidebarProps) {
  const [sessions, setSessions] = useState<Session[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isOpen, setIsOpen] = useState(false);

  const loadSessions = async () => {
    setIsLoading(true);
    try {
      const { data } = await listSessions();
      setSessions(data);
    } catch (error) {
      console.error('Failed to load sessions:', error);
      toast.error('Failed to load sessions');
    } finally {
      setIsLoading(false);
    }
  };

  const handleCreate = async () => {
    try {
      const { data } = await createSession();
      setSessions((prev) => [data, ...prev]);
      onCreateSession(data);
      toast.success('Session created');
      if (responsive) setIsOpen(false);
    } catch (error) {
      console.error('Failed to create session:', error);
      toast.error('Failed to create session');
    }
  };

  const handleDelete = async (id: string, e: React.MouseEvent) => {
    e.stopPropagation();
    try {
      await deleteSession(id);
      setSessions((prev) => prev.filter((s) => s.id !== id));
      toast.success('Session deleted');
      if (currentSessionId === id) {
        const remaining = sessions.filter((s) => s.id !== id);
        if (remaining.length > 0) {
          onSelectSession(remaining[0].id);
        }
      }
    } catch (error) {
      console.error('Failed to delete session:', error);
      toast.error('Failed to delete session');
    }
  };

  const handleSelectSession = (id: string) => {
    onSelectSession(id);
    if (responsive) setIsOpen(false);
  };

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

  // 处理会话标题更新
  useEffect(() => {
    if (sessionTitleUpdate) {
      setSessions((prev) =>
        prev.map((s) =>
          s.id === sessionTitleUpdate.sessionId
            ? { ...s, name: sessionTitleUpdate.name }
            : s
        )
      );
    }
  }, [sessionTitleUpdate]);

  const handleOverlayClick = () => {
    setIsOpen(false);
  };

  // 空状态组件
  const EmptyState = () => (
    <motion.div
      initial={{ opacity: 0, y: 10 }}
      animate={{ opacity: 1, y: 0 }}
      transition={smoothTransition}
      className="p-6 text-center"
    >
      <div className="w-12 h-12 mx-auto mb-4 rounded-full bg-surface-muted/50 flex items-center justify-center">
        <MessageCircle size={24} className="text-fg-subtle" />
      </div>
      <p className="text-fg-muted mb-4">No conversations yet</p>
      <motion.button
        whileHover={{ scale: 1.02 }}
        whileTap={{ scale: 0.98 }}
        onClick={handleCreate}
        className="text-primary-400 text-sm hover:text-primary-300 transition-colors"
      >
        Create your first chat
      </motion.button>
    </motion.div>
  );

  // 会话列表项 - 使用 forwardRef 支持 AnimatePresence 的 popLayout 模式
  const SessionItem = forwardRef<HTMLDivElement, { session: Session }>(
    ({ session }, ref) => (
      <motion.div
        ref={ref}
        layout
        variants={fadeInUp}
        initial="initial"
        animate="animate"
        exit="exit"
        transition={smoothTransition}
        onClick={() => handleSelectSession(session.id)}
        className={cn(
          'flex items-center gap-2 p-3 rounded-lg cursor-pointer group',
          'hover:bg-surface-muted transition-colors',
          'active:bg-surface-emphasis',
          currentSessionId === session.id && 'bg-surface-muted'
        )}
      >
        <MessageSquare size={18} className="text-fg-muted flex-shrink-0" />
        <div className="flex-1 min-w-0">
          <div className="text-sm truncate text-fg">
            {session.name || `Chat ${session.id.slice(0, 8)}`}
          </div>
          <div className="text-xs text-fg-subtle">{session.messageCount} messages</div>
        </div>
        <motion.button
          whileHover={{ scale: 1.1 }}
          whileTap={{ scale: 0.9 }}
          onClick={(e) => handleDelete(session.id, e)}
          className="opacity-0 group-hover:opacity-100 p-1 hover:bg-surface-emphasis rounded transition-opacity"
          aria-label="Delete session"
        >
          <Trash2 size={14} className="text-fg-muted" />
        </motion.button>
      </motion.div>
    )
  );

  // 加载状态
  const LoadingState = () => (
    <div className="p-2 space-y-2">
      {[1, 2, 3].map((i) => (
        <SessionSkeleton key={i} />
      ))}
    </div>
  );

  // 侧边栏内容
  const SidebarContent = () => (
    <>
      {/* Header */}
      <div className="p-4 border-b border-line">
        {responsive && (
          <div className="flex items-center justify-between mb-3 md:hidden">
            <span className="text-lg font-semibold text-fg">Sessions</span>
            <button
              onClick={() => setIsOpen(false)}
              className="p-1 hover:bg-surface-muted rounded transition-colors"
              aria-label="Close menu"
            >
              <X size={20} />
            </button>
          </div>
        )}
        <motion.button
          whileHover={{ scale: 1.02 }}
          whileTap={{ scale: 0.98 }}
          onClick={handleCreate}
          className="w-full flex items-center justify-center gap-2 px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-colors"
        >
          <Plus size={18} />
          <span>New Chat</span>
        </motion.button>
      </div>

      {/* Session List */}
      <div className="flex-1 overflow-y-auto">
        {isLoading ? (
          <LoadingState />
        ) : sessions.length === 0 ? (
          <EmptyState />
        ) : (
          <div className="p-2 space-y-1">
            <AnimatePresence mode="popLayout">
              {sessions.map((session) => (
                <SessionItem key={session.id} session={session} />
              ))}
            </AnimatePresence>
          </div>
        )}
      </div>

      {/* Footer */}
      <div className="p-4 border-t border-line flex items-center justify-between">
        <span className="text-xs text-fg-subtle">AI Assistant v1.0</span>
        <ThemeToggleCompact />
      </div>
    </>
  );

  // 非响应式模式
  if (!responsive) {
    return (
      <div className="w-64 bg-surface-subtle border-r border-line flex flex-col">
        <SidebarContent />
      </div>
    );
  }

  // 响应式模式
  return (
    <>
      {/* 移动端菜单按钮 */}
      <motion.button
        whileHover={{ scale: 1.05 }}
        whileTap={{ scale: 0.95 }}
        onClick={() => setIsOpen(true)}
        className="fixed top-3 left-3 z-40 p-2 rounded-lg bg-surface-subtle text-fg-muted hover:bg-surface-muted transition-colors md:hidden"
        aria-label="Open menu"
      >
        <Menu size={20} />
      </motion.button>

      {/* 遮罩层 - 仅移动端 */}
      <AnimatePresence>
        {isOpen && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="fixed inset-0 bg-black/50 z-40 md:hidden"
            onClick={handleOverlayClick}
          />
        )}
      </AnimatePresence>

      {/* 移动端抽屉式侧边栏 */}
      <motion.div
        initial={false}
        animate={{ x: isOpen ? 0 : '-100%' }}
        transition={{ type: 'spring', stiffness: 300, damping: 30 }}
        className="fixed inset-y-0 left-0 z-50 w-64 bg-surface-subtle border-r border-line flex flex-col md:hidden"
      >
        <SidebarContent />
      </motion.div>

      {/* 桌面端固定侧边栏 */}
      <div className="hidden md:flex w-64 bg-surface-subtle border-r border-line flex-col">
        <SidebarContent />
      </div>
    </>
  );
}
