import { useState, useEffect, useCallback, useRef } from "react";
import { useWatchlist } from "../context/WatchlistContext.jsx";

const STATIC_ASSETS = "https://warframe.market/static/assets";

function computeStats(orders) {
  const sells = orders
    .filter((o) => o.type === "sell" && o.user?.status !== "invisible")
    .sort((a, b) => a.platinum - b.platinum);
  const buys = orders
    .filter((o) => o.type === "buy" && o.user?.status !== "invisible")
    .sort((a, b) => b.platinum - a.platinum);

  const lowestSell = sells.length > 0 ? sells[0].platinum : null;
  const highestBuy = buys.length > 0 ? buys[0].platinum : null;
  const activeSells = sells.length;

  return { lowestSell, highestBuy, activeSells };
}

export default function WatchlistTable({ priceMin, priceMax, onItemSelect }) {
  const { watchlist, toggleItem } = useWatchlist();
  const [catalog, setCatalog] = useState({});
  const [ordersCache, setOrdersCache] = useState({});
  const [loading, setLoading] = useState(true);
  const [errors, setErrors] = useState({});
  const [sortKey, setSortKey] = useState("name");
  const [sortAsc, setSortAsc] = useState(true);
  const intervalRef = useRef(null);

  // Fetch catalog for watchlist items
  useEffect(() => {
    let cancelled = false;
    async function loadCatalog() {
      try {
        const res = await fetch("/api/items");
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = await res.json();
        if (!cancelled) {
          const map = {};
          for (const item of data) map[item.slug] = item;
          setCatalog(map);
        }
      } catch (err) {
        console.error("Failed to load catalog:", err);
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    loadCatalog();
    return () => { cancelled = true; };
  }, []);

  const fetchOrders = useCallback(async () => {
    for (const slug of watchlist) {
      try {
        const res = await fetch(`/api/orders/${encodeURIComponent(slug)}`);
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = await res.json();
        setOrdersCache((prev) => ({ ...prev, [slug]: data }));
        setErrors((prev) => {
          const next = { ...prev };
          delete next[slug];
          return next;
        });
      } catch (err) {
        setErrors((prev) => ({ ...prev, [slug]: err.message }));
      }
    }
  }, [watchlist]);

  useEffect(() => {
    if (watchlist.length === 0) return;
    fetchOrders();
    intervalRef.current = setInterval(fetchOrders, 60000);
    return () => clearInterval(intervalRef.current);
  }, [watchlist, fetchOrders]);

  const rows = watchlist
    .filter((slug) => catalog[slug])
    .map((slug) => {
      const item = catalog[slug];
      const orders = ordersCache[slug] || [];
      const stats = computeStats(orders);
      const name = item.i18n?.en?.name || slug;
      const thumb = item.i18n?.en?.thumb;
      const tags = item.tags || [];
      return { slug, name, thumb, tags, ...stats, hasError: !!errors[slug] };
    });

  const sorted = [...rows].sort((a, b) => {
    let va, vb;
    if (sortKey === "name") { va = a.name; vb = b.name; }
    else if (sortKey === "platinum") { va = a.lowestSell ?? 99999; vb = b.lowestSell ?? 99999; }
    else if (sortKey === "buy") { va = a.highestBuy ?? -1; vb = b.highestBuy ?? -1; }
    else if (sortKey === "spread") {
      va = (a.lowestSell != null && a.highestBuy != null) ? a.lowestSell - a.highestBuy : 99999;
      vb = (b.lowestSell != null && b.highestBuy != null) ? b.lowestSell - b.highestBuy : 99999;
    }
    else { va = a.activeSells; vb = b.activeSells; }
    if (va < vb) return sortAsc ? -1 : 1;
    if (va > vb) return sortAsc ? 1 : -1;
    return 0;
  });

  const filtered = sorted.filter((r) => {
    if (r.lowestSell == null && r.highestBuy == null) return true;
    const effective = r.lowestSell ?? 0;
    return effective >= priceMin && effective <= priceMax;
  });

  const sortArrow = (key) => {
    if (sortKey !== key) return "";
    return <span className="sort-arrow">{sortAsc ? "\u25B2" : "\u25BC"}</span>;
  };

  if (loading) {
    return <div className="loading"><div className="spinner" /> Loading catalog...</div>;
  }

  if (watchlist.length === 0) {
    return (
      <div className="empty-msg">
        Your watchlist is empty. Go to the Catalog tab and star some items.
      </div>
    );
  }

  return (
    <div className="table-wrap">
      <table>
        <thead>
          <tr>
            <th style={{ width: 40 }}></th>
            <th onClick={() => { setSortKey("name"); setSortAsc(sortKey === "name" ? !sortAsc : true); }}>
              Name{sortArrow("name")}
            </th>
            <th>Tags</th>
            <th onClick={() => { setSortKey("platinum"); setSortAsc(sortKey === "platinum" ? !sortAsc : true); }}>
              Platinum{sortArrow("platinum")}
            </th>
            <th onClick={() => { setSortKey("buy"); setSortAsc(sortKey === "buy" ? !sortAsc : true); }}>
              Highest Buy{sortArrow("buy")}
            </th>
            <th onClick={() => { setSortKey("spread"); setSortAsc(sortKey === "spread" ? !sortAsc : true); }}>
              Spread{sortArrow("spread")}
            </th>
            <th onClick={() => { setSortKey("sells"); setSortAsc(sortKey === "sells" ? !sortAsc : true); }}>
              # Sells{sortArrow("sells")}
            </th>
          </tr>
        </thead>
        <tbody>
          {filtered.map((row) => {
            const spread =
              row.lowestSell != null && row.highestBuy != null
                ? row.lowestSell - row.highestBuy
                : null;
            return (
              <tr key={row.slug} style={{ cursor: "pointer" }} onClick={() => onItemSelect(row.slug)}>
                <td>
                  <button
                    className="star-btn starred"
                    onClick={(e) => { e.stopPropagation(); toggleItem(row.slug); }}
                    title="Remove from watchlist"
                  >
                    {"\u2605"}
                  </button>
                </td>
                <td>
                  <div className="item-name">
                    {row.thumb && (
                      <img
                        className="item-thumb"
                        src={`${STATIC_ASSETS}/${row.thumb}`}
                        alt=""
                        loading="lazy"
                      />
                    )}
                    <span>{row.name}</span>
                    {row.hasError && <span style={{ color: "var(--red)", fontSize: "0.75rem" }}> (error)</span>}
                  </div>
                </td>
                <td>
                  {row.tags.slice(0, 3).map((tag) => (
                    <span key={tag} className="tag-badge">{tag}</span>
                  ))}
                </td>
                <td className="price-sell">
                  {row.lowestSell != null ? `${row.lowestSell}\u25BC` : "\u2014"}
                </td>
                <td className="price-buy">
                  {row.highestBuy != null ? `${row.highestBuy}\u25B2` : "\u2014"}
                </td>
                <td className="price-spread">
                  {spread != null ? (spread >= 0 ? `+${spread}` : spread) : "\u2014"}
                </td>
                <td>{row.activeSells}</td>
              </tr>
            );
          })}
          {filtered.length === 0 && (
            <tr>
              <td colSpan={7} className="empty-msg">
                No watchlist items match the price filter.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  );
}
