"use client";
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Link from 'next/link';
import HoverVideo from './HoverVideo';
import { ThumbsUp } from 'lucide-react';
import type { FeedItem, FeedResponse } from '@/app/types/feed';

type Props = {
  initialItems: FeedItem[];
  initialCursor: string | null;
};

export default function FeedMasonry({ initialItems, initialCursor }: Props) {
  // 哨兵与容器
  const [cursor, setCursor] = useState<string | null>(initialCursor);
  const [loading, setLoading] = useState(false);
  const [ended, setEnded] = useState(!initialCursor);

  const sentinelRef = useRef<HTMLDivElement | null>(null);
  const containerRef = useRef<HTMLDivElement | null>(null);

  // 响应式列数：<640:1, >=640:2, >=1024:3, >=1280:4
  const getColumnCount = useCallback(() => {
    if (typeof window === 'undefined') return 1;
    const w = window.innerWidth;
    if (w >= 1280) return 4; // xl
    if (w >= 1024) return 3; // lg
    if (w >= 640) return 2;  // sm
    return 1;
  }, []);
  // 为避免 SSR 与客户端初次渲染不一致（window 未定义导致服务端为 1 列，客户端首次渲染为多列），
  // 这里将初始列数固定为 1，待挂载后再根据窗口宽度更新。
  const [columnCount, setColumnCount] = useState<number>(1);

  useEffect(() => {
    // 挂载后立即根据当前窗口宽度更新一次列数
    setColumnCount(getColumnCount());
    const onResize = () => setColumnCount(getColumnCount());
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, [getColumnCount]);

  // 估算卡片高度（用于分配到“最短列”）
  const estimateItemHeight = useCallback((item: FeedItem, colWidth: number) => {
    // 媒体区域高度
    let mediaH = 200; // fallback
    if (item.width && item.height) {
      mediaH = Math.max(80, (Number(item.height) / Number(item.width)) * colWidth);
    } else if (item.type === 'video') {
      mediaH = (9 / 16) * colWidth; // 常见视频比例
    }
    // 文本 + 作者栏的高度粗估
    const textH = 48; // 标题+标签区域
    const authorH = 48; // 作者行
    const gap = 16; // 卡片内边距/间隙
    return mediaH + textH + authorH + gap;
  }, []);

  // 维护列数据与列高
  const [columns, setColumns] = useState<FeedItem[][]>(() => {
    const cols: FeedItem[][] = Array.from({ length: columnCount }, () => []);
    return cols;
  });
  const [colHeights, setColHeights] = useState<number[]>(() => Array.from({ length: columnCount }, () => 0));

  // 初始化与当列数变化时重排
  useEffect(() => {
    const containerWidth = containerRef.current?.clientWidth ?? 0;
    const colWidth = columnCount > 0 ? containerWidth / columnCount : containerWidth;
    // 用 initialItems 重排
    const newCols: FeedItem[][] = Array.from({ length: columnCount }, () => []);
    const newHeights: number[] = Array.from({ length: columnCount }, () => 0);
    for (const item of initialItems) {
      // 找最短列
      let minIdx = 0;
      for (let i = 1; i < columnCount; i++) {
        if (newHeights[i] < newHeights[minIdx]) minIdx = i;
      }
      newCols[minIdx].push(item);
      newHeights[minIdx] += estimateItemHeight(item, colWidth || 300);
    }
    setColumns(newCols);
    setColHeights(newHeights);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [columnCount]);

  const fetchMore = useCallback(async () => {
    if (loading || ended) return;
    setLoading(true);
    try {
      const params = new URLSearchParams();
      if (cursor) params.set('before', cursor);
      params.set('limit', '24');
      const res = await fetch(`/api/feed?${params.toString()}`, { cache: 'no-store' });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data: FeedResponse = await res.json();
      // 将新数据按最短列分配
      setColumns((prevCols) => {
        const containerWidth = containerRef.current?.clientWidth ?? 0;
        const colWidth = columnCount > 0 ? containerWidth / columnCount : containerWidth;
        const cols = prevCols.map((c) => [...c]);
        const heights = [...colHeights];
        for (const item of data.items) {
          // 找当前最短列
          let minIdx = 0;
          for (let i = 1; i < columnCount; i++) {
            if (heights[i] < heights[minIdx]) minIdx = i;
          }
          cols[minIdx].push(item);
          heights[minIdx] += estimateItemHeight(item, colWidth || 300);
        }
        setColHeights(heights);
        return cols;
      });
      setCursor(data.nextCursor);
      if (!data.nextCursor || data.items.length === 0) setEnded(true);
    } catch (e) {
      console.error('fetch more feed failed', e);
      // 失败也不要死循环
      setEnded(true);
    } finally {
      setLoading(false);
    }
  }, [cursor, ended, loading, columnCount, colHeights, estimateItemHeight]);

  useEffect(() => {
    const el = sentinelRef.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      const entry = entries[0];
      if (entry.isIntersecting) {
        fetchMore();
      }
    }, { rootMargin: '800px 0px 800px 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, [fetchMore]);

  const renderCard = useCallback((item: FeedItem) => (
    <Link key={item.aweme_id} href={`/aweme/${item.aweme_id}`} target="_blank" className="mb-4 block group">
      <article className="relative overflow-hidden rounded-2xl shadow-sm ring-1 ring-black/5 bg-white/80 dark:bg-zinc-900/60 backdrop-blur-sm transition-transform duration-300 group-hover:-translate-y-1">
        <div
          className="relative w-full"
          style={{ aspectRatio: `${(item.width && item.height) ? `${item.width}/${item.height}` : ''}` as any }}
        >
          {item.type === 'video' ? (
            <HoverVideo
              videoUrl={(item as any).video_url}
              coverUrl={item.cover_url}
              className="absolute inset-0 w-full h-full"
            />
          ) : (
            <img
              loading="lazy"
              src={item.cover_url || '/placeholder.svg'}
              alt={item.desc?.slice(0, 20) || 'image'}
              className="absolute inset-0 w-full h-full object-cover"
            />
          )}
          <div className="pointer-events-none absolute inset-0 bg-gradient-to-t from-black/50 via-black/0 to-black/0 opacity-70" />
          <div className="absolute left-3 bottom-3 right-3 flex items-end justify-between gap-3">
            <p className="text-white/95 text-sm leading-tight line-clamp-2 drop-shadow">
              {item.desc}
            </p>
            <span className="shrink-0 inline-flex items-center gap-2 rounded-full bg-white/85 px-2 py-1 text-xs text-zinc-800">
              {item.type === 'video' ? '视频' : '图文'}
            </span>
          </div>
        </div>

        <div className="flex items-center gap-2 p-3">
          <div className="size-6 rounded-full overflow-hidden bg-zinc-200">
            {item.author.avatar_url ? (
              <img src={item.author.avatar_url} alt="avatar" className="w-full h-full object-cover" />
            ) : null}
          </div>
          <span className="text-sm text-zinc-700 dark:text-zinc-300 truncate">{item.author.nickname}</span>
          <span className="ml-auto text-sm text-zinc-700 dark:text-zinc-300">{item.likes} </span><ThumbsUp size={16} style={{ color: 'var(--color-zinc-700)' }} />
        </div>
      </article>
    </Link>
  ), []);

  return (
    <>
      {/* Masonry（按列渲染，动态分配到最短列） */}
      <div ref={containerRef} className="grid gap-4" style={{ gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))` }}>
        {columns.map((col, idx) => (
          <div key={idx} className="flex flex-col">
            {col.map((item) => renderCard(item))}
          </div>
        ))}
      </div>
      <div ref={sentinelRef} className="h-10 flex items-center justify-center text-sm text-zinc-500">
        {ended ? '没有更多了' : (loading ? '加载中…' : '下拉加载更多')}
      </div>
    </>
  );
}
