import { useEffect, useMemo, useState } from 'react';
import { api, formatCredits } from '../api';
import { getSocket } from '../socket';
import { rarityColor } from '../rarities';

const MAX_BUFFER = 40;
const KEEP_FOREVER = 5;
const EXPIRE_MS = 3 * 60 * 1000; // older than 3 min disappear (except top 5)

function formatDropTime(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return '';
  return d.toLocaleString(undefined, {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });
}

function pruneDrops(list, now = Date.now()) {
  return list.filter((d, index) => {
    if (index < KEEP_FOREVER) return true;
    const t = new Date(d.at).getTime();
    if (Number.isNaN(t)) return false;
    return now - t < EXPIRE_MS;
  });
}

export default function DropFeed() {
  const [drops, setDrops] = useState([]);
  const [now, setNow] = useState(() => Date.now());

  useEffect(() => {
    let cancelled = false;
    const socket = getSocket();

    const applyList = (list) => {
      if (cancelled) return;
      const seen = new Set();
      const unique = [];
      for (const d of list || []) {
        if (!d?.id || seen.has(d.id)) continue;
        seen.add(d.id);
        unique.push(d);
      }
      setDrops(pruneDrops(unique.slice(0, MAX_BUFFER)));
    };

    const onHistory = (list) => applyList(list);
    const onDrop = (entry) => {
      if (!entry?.id) return;
      setDrops((prev) => {
        if (prev.some((d) => d.id === entry.id)) return prev;
        const nearDup = prev.find(
          (d) =>
            d.username === entry.username &&
            d.item?.id === entry.item?.id &&
            (d.count || 1) === (entry.count || 1) &&
            (d.openCount || 1) === (entry.openCount || 1) &&
            Boolean(d.respin) === Boolean(entry.respin) &&
            Math.abs(new Date(d.at) - new Date(entry.at)) < 15000
        );
        if (nearDup) return prev;
        return pruneDrops([entry, ...prev].slice(0, MAX_BUFFER));
      });
    };

    socket.emit('feed:subscribe');
    socket.on('feed:history', onHistory);
    socket.on('feed:drop', onDrop);
    socket.on('connect', () => socket.emit('feed:subscribe'));

    const t = setTimeout(() => {
      if (cancelled) return;
      api.feed()
        .then((data) => {
          setDrops((prev) => (prev.length ? prev : pruneDrops(data.drops || [])));
        })
        .catch(() => {});
    }, 400);

    return () => {
      cancelled = true;
      clearTimeout(t);
      socket.emit('feed:unsubscribe');
      socket.off('feed:history', onHistory);
      socket.off('feed:drop', onDrop);
    };
  }, []);

  useEffect(() => {
    const id = setInterval(() => {
      const t = Date.now();
      setNow(t);
      setDrops((prev) => pruneDrops(prev, t));
    }, 1000);
    return () => clearInterval(id);
  }, []);

  const visible = useMemo(() => pruneDrops(drops, now), [drops, now]);

  return (
    <aside className="drop-feed" aria-label="Drop feed">
      <div className="drop-feed-head">
        <h2>Feed Drop</h2>
        <p className="muted">Latest unboxes</p>
      </div>
      <div className="drop-feed-list">
        {visible.length === 0 ? (
          <div className="drop-feed-empty muted">No drops yet — open a case.</div>
        ) : (
          visible.map((d) => {
            const color = rarityColor(d.item?.rarity);
            return (
              <div
                key={d.id}
                className={`drop-feed-row${d.respin ? ' is-respin' : ''}`}
                style={{ borderLeftColor: color }}
              >
                <div className="drop-feed-item-visual" style={{ color }}>
                  {d.item?.imageUrl ? (
                    <img src={d.item.imageUrl} alt="" />
                  ) : (
                    (d.item?.name || '??').slice(0, 2).toUpperCase()
                  )}
                </div>
                <div className="drop-feed-meta">
                  <div className="drop-feed-item-name">
                    {d.item?.name}
                    {d.count > 1 ? <span className="drop-feed-count"> x{d.count}</span> : null}
                  </div>
                  {d.item?.wear ? (
                    <div className="drop-feed-wear muted">{d.item.wear}</div>
                  ) : null}
                  <div className="drop-feed-player">
                    {d.avatarUrl ? (
                      <img src={d.avatarUrl} alt="" className="drop-feed-avatar" />
                    ) : (
                      <span className="drop-feed-avatar fallback">
                        {(d.username || '?').slice(0, 1).toUpperCase()}
                      </span>
                    )}
                    <span>
                      {d.source === 'jackpot' ? (
                        <>
                          <span className="drop-feed-winner-label">Battle Winner</span>{' '}
                          {d.username}
                        </>
                      ) : (
                        <>
                          {d.respin ? (
                            <span className="drop-feed-respin-label">Respin</span>
                          ) : null}
                          {d.respin ? ' ' : null}
                          {d.username}
                        </>
                      )}
                    </span>
                  </div>
                  <div className="muted drop-feed-sub">
                    {d.caseName ? `${d.caseName} · ` : ''}
                    {formatCredits(d.item?.marketValue || 0)} cr
                    {d.openCount > 1
                      ? d.source === 'jackpot'
                        ? ` · ${d.openCount} items`
                        : ` · ${d.openCount}× open`
                      : ''}
                  </div>
                  <div className="muted drop-feed-time">{formatDropTime(d.at)}</div>
                </div>
              </div>
            );
          })
        )}
      </div>
    </aside>
  );
}
