import { useRef, useEffect, useState, useMemo, useCallback } from 'react';
import { Sidebar } from './Sidebar';
import { InputBar } from './InputBar';
import { GenerationCard } from './GenerationCard';
import { VideoDetailModal } from './VideoDetailModal';
import { AnnouncementBanner } from './AnnouncementBanner';
import { AnnouncementModal } from './AnnouncementModal';
import { useGenerationStore } from '../store/generation';
import { useAuthStore } from '../store/auth';
import type { GenerationTask } from '../types';
import styles from './VideoGenerationPage.module.css';

export function VideoGenerationPage() {
  const tasks = useGenerationStore((s) => s.tasks);
  const loadTasks = useGenerationStore((s) => s.loadTasks);
  const loadMore = useGenerationStore((s) => s.loadMore);
  const isLoadingMore = useGenerationStore((s) => s.isLoadingMore);
  const teamDisabled = useAuthStore((s) => s.teamDisabled);
  const reEdit = useGenerationStore((s) => s.reEdit);
  const regenerate = useGenerationStore((s) => s.regenerate);
  const removeTask = useGenerationStore((s) => s.removeTask);
  const scrollRef = useRef<HTMLDivElement>(null);
  const prevCountRef = useRef(tasks.length);
  const initialLoadRef = useRef(true);
  const savedScrollTop = useGenerationStore((s) => s.savedScrollTop);
  const saveScrollPosition = useGenerationStore((s) => s.saveScrollPosition);
  const [detailTaskId, setDetailTaskId] = useState<string | null>(null);
  const [showAnnouncement, setShowAnnouncement] = useState(false);
  const [autoAnnouncementDone, setAutoAnnouncementDone] = useState(false);
  const [showScrollBottom, setShowScrollBottom] = useState(false);
  const detailTask = useMemo(() => detailTaskId ? tasks.find((t) => t.id === detailTaskId) || null : null, [detailTaskId, tasks]);
  const setDetailTask = useCallback((t: GenerationTask | null) => setDetailTaskId(t?.id || null), []);

  // Load tasks from backend on mount (persist across page refresh)
  useEffect(() => {
    loadTasks();
  }, [loadTasks]);

  // Restore scroll position after initial load, or scroll to bottom for new tasks
  useEffect(() => {
    if (tasks.length === 0) return;
    if (initialLoadRef.current) {
      initialLoadRef.current = false;
      // Use requestAnimationFrame to ensure DOM has rendered
      const restoreTop = savedScrollTop;
      requestAnimationFrame(() => {
        if (restoreTop !== null && scrollRef.current) {
          scrollRef.current.scrollTop = restoreTop;
        } else if (scrollRef.current) {
          scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
        }
      });
      prevCountRef.current = tasks.length;
      return;
    }
    if (tasks.length > prevCountRef.current && scrollRef.current) {
      scrollRef.current.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' });
    }
    prevCountRef.current = tasks.length;
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tasks.length]);

  // Save scroll position + auto-load older tasks when scrolled near top
  const handleScroll = useCallback(() => {
    if (!scrollRef.current) return;
    saveScrollPosition(scrollRef.current.scrollTop);

    // Show "scroll to bottom" button when not near bottom
    const el = scrollRef.current;
    const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
    setShowScrollBottom(distanceFromBottom > 300);

    // Trigger loadMore when scrolled within 100px of the top
    if (scrollRef.current.scrollTop < 100) {
      const el = scrollRef.current;
      const prevHeight = el.scrollHeight;
      loadMore().then(() => {
        // After older tasks are prepended, restore visual position so user doesn't jump
        requestAnimationFrame(() => {
          const diff = el.scrollHeight - prevHeight;
          if (diff > 0) el.scrollTop += diff;
        });
      });
    }
  }, [saveScrollPosition, loadMore]);

  const handleReEdit = (id: string) => {
    reEdit(id);
    setDetailTask(null);
  };

  const handleRegenerate = (id: string) => {
    regenerate(id);
    setDetailTask(null);
  };

  const handleDelete = (id: string) => {
    removeTask(id);
    setDetailTask(null);
  };

  const completedTasks = useMemo(
    () => tasks.filter((t) => t.status === 'completed' && t.resultUrl),
    [tasks],
  );
  const detailIdx = detailTask ? completedTasks.findIndex((t) => t.id === detailTask.id) : -1;

  if (teamDisabled) {
    return (
      <div className={styles.layout}>
        <Sidebar />
        <main className={styles.main}>
          <div style={{
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            height: '100%', flexDirection: 'column', gap: 16,
            color: 'var(--color-text-secondary)',
          }}>
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#8b8ea8" strokeWidth="1.5">
              <circle cx="12" cy="12" r="10" />
              <path d="M4.93 4.93l14.14 14.14" />
            </svg>
            <p style={{ fontSize: 18, color: 'var(--color-text-primary)' }}>您的团队已被停用</p>
            <p>请联系管理员</p>
          </div>
        </main>
      </div>
    );
  }

  return (
    <div className={styles.layout}>
      <Sidebar />
      <main className={styles.main}>
        {/* 公告已改为弹窗，旧的横幅不再显示 */}
        {/* 右上角公告小喇叭 */}
        <button
          onClick={() => setShowAnnouncement(true)}
          style={{
            position: 'absolute', top: 12, right: 16, zIndex: 20,
            background: 'rgba(255,255,255,0.06)', border: '1px solid var(--color-border-card)',
            borderRadius: '50%', width: 32, height: 32,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            cursor: 'pointer', color: 'var(--color-text-secondary)',
            transition: 'all 0.15s',
          }}
          onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.color = 'var(--color-primary)'; (e.currentTarget as HTMLElement).style.borderColor = 'var(--color-primary)'; }}
          onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.color = 'var(--color-text-secondary)'; (e.currentTarget as HTMLElement).style.borderColor = 'var(--color-border-card)'; }}
          title="查看公告"
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />
            <path d="M13.73 21a2 2 0 0 1-3.46 0" />
          </svg>
        </button>
        <div className={styles.contentArea} ref={scrollRef} onScroll={handleScroll}>
          {tasks.length === 0 ? (
            <div className={styles.emptyArea}>
              <p className={styles.emptyHint}>Every frame was once just air.</p>
            </div>
          ) : (
            <div className={styles.taskList}>
              {isLoadingMore && (
                <div className={styles.loadMoreWrap}>
                  <span className={styles.loadMoreText}>加载中…</span>
                </div>
              )}
              {tasks.map((task) => (
                <GenerationCard
                  key={task.id}
                  task={task}
                  onOpenDetail={setDetailTask}
                />
              ))}
            </div>
          )}
        </div>
        <InputBar scrollBottomBtn={showScrollBottom ? (
          <button
            onClick={() => scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: 'smooth' })}
            style={{
              marginLeft: 'auto',
              background: 'rgba(255, 255, 255, 0.06)',
              backdropFilter: 'blur(24px) saturate(180%)',
              WebkitBackdropFilter: 'blur(24px) saturate(180%)',
              border: '1px solid rgba(255, 255, 255, 0.10)',
              boxShadow: '0 0 0 1px rgba(255,255,255,0.05) inset, 0 4px 16px rgba(0,0,0,0.3)',
              borderRadius: 6, padding: '4px 12px', fontSize: 12,
              color: 'var(--color-text-secondary)', cursor: 'pointer',
              transition: 'all 0.15s', whiteSpace: 'nowrap',
            }}
            onMouseEnter={(e) => { (e.currentTarget as HTMLElement).style.background = 'rgba(255,255,255,0.10)'; (e.currentTarget as HTMLElement).style.color = 'var(--color-text-primary)'; }}
            onMouseLeave={(e) => { (e.currentTarget as HTMLElement).style.background = 'rgba(255,255,255,0.06)'; (e.currentTarget as HTMLElement).style.color = 'var(--color-text-secondary)'; }}
          >
            回到底部 ↓
          </button>
        ) : null} />
      </main>
      <VideoDetailModal
        task={detailTask}
        onClose={() => setDetailTask(null)}
        onReEdit={handleReEdit}
        onRegenerate={handleRegenerate}
        onDelete={handleDelete}
        onToggleFavorite={(id) => { useGenerationStore.getState().toggleFavorite(id); }}
        hasPrev={detailIdx > 0}
        hasNext={detailIdx >= 0 && detailIdx < completedTasks.length - 1}
        onPrev={() => detailIdx > 0 && setDetailTask(completedTasks[detailIdx - 1])}
        onNext={() => detailIdx < completedTasks.length - 1 && setDetailTask(completedTasks[detailIdx + 1])}
      />
      {/* 自动弹窗（首次未读）*/}
      {!autoAnnouncementDone && (
        <AnnouncementModal onClose={() => setAutoAnnouncementDone(true)} />
      )}
      {/* 手动弹窗（点小喇叭）*/}
      {showAnnouncement && (
        <AnnouncementModal forceOpen onClose={() => setShowAnnouncement(false)} />
      )}
    </div>
  );
}
