import { useCallback, useEffect, useMemo, useState } from 'react';
import { api, formatCredits, compareCents } from '../api';

function dropPercents(items) {
  const total = items.reduce((s, ci) => s + Number(ci.dropRate || 0), 0);
  if (!(total > 0)) return items.map(() => 0);
  return items.map((ci) => (Number(ci.dropRate) / total) * 100);
}

function sortCatalog(list, sort) {
  const next = [...list];
  next.sort((a, b) => {
    if (sort === 'value-asc') return compareCents(a.marketValue, b.marketValue);
    if (sort === 'name') return a.name.localeCompare(b.name);
    if (sort === 'rarity') {
      const r = a.rarity.localeCompare(b.rarity);
      if (r !== 0) return r;
      return compareCents(b.marketValue, a.marketValue);
    }
    // value-desc (default)
    return compareCents(b.marketValue, a.marketValue);
  });
  return next;
}

function sortPool(list, sort) {
  const next = [...list];
  next.sort((a, b) => {
    if (sort === 'value-desc') {
      return compareCents(b.item.marketValue, a.item.marketValue);
    }
    if (sort === 'value-asc') {
      return compareCents(a.item.marketValue, b.item.marketValue);
    }
    if (sort === 'name') return a.item.name.localeCompare(b.item.name);
    if (sort === 'rarity') {
      const r = a.item.rarity.localeCompare(b.item.rarity);
      if (r !== 0) return r;
      return compareCents(b.item.marketValue, a.item.marketValue);
    }
    if (sort === 'rate-desc') return Number(b.dropRate) - Number(a.dropRate);
    // rate-asc (default)
    return Number(a.dropRate) - Number(b.dropRate);
  });
  return next;
}

export default function AdminDrops() {
  const [cases, setCases] = useState([]);
  const [items, setItems] = useState([]);
  const [error, setError] = useState('');
  const [selectedCaseId, setSelectedCaseId] = useState('');
  const [dropForm, setDropForm] = useState({ itemId: '', dropRate: 1 });
  const [itemSort, setItemSort] = useState('value-desc');
  const [itemQuery, setItemQuery] = useState('');
  const [categoryFilter, setCategoryFilter] = useState('all');
  const [poolSort, setPoolSort] = useState('rate-asc');

  const load = useCallback(async () => {
    const [c, i] = await Promise.all([api.adminCases(), api.adminItems()]);
    setCases(c.cases);
    setItems(i.items);
    setSelectedCaseId((prev) => {
      if (prev && c.cases.some((x) => String(x.id) === String(prev))) return prev;
      return c.cases[0] ? String(c.cases[0].id) : '';
    });
  }, []);

  useEffect(() => {
    load().catch((err) => setError(err.message));
  }, [load]);

  const selected = useMemo(
    () => cases.find((c) => String(c.id) === String(selectedCaseId)) || null,
    [cases, selectedCaseId]
  );

  const usedCategories = useMemo(() => {
    const set = new Set(items.map((item) => item.category || 'Misc'));
    return [...set].sort((a, b) => a.localeCompare(b));
  }, [items]);

  const catalogItems = useMemo(() => {
    const q = itemQuery.trim().toLowerCase();
    const filtered = items.filter((item) => {
      const cat = item.category || 'Misc';
      if (categoryFilter !== 'all' && cat !== categoryFilter) return false;
      if (!q) return true;
      return (
        item.name.toLowerCase().includes(q) ||
        item.rarity.toLowerCase().includes(q) ||
        cat.toLowerCase().includes(q)
      );
    });
    return sortCatalog(filtered, itemSort);
  }, [items, itemQuery, itemSort, categoryFilter]);

  useEffect(() => {
    if (!catalogItems.length) {
      setDropForm((f) => (f.itemId ? { ...f, itemId: '' } : f));
      return;
    }
    setDropForm((f) => {
      if (f.itemId && catalogItems.some((item) => String(item.id) === String(f.itemId))) {
        return f;
      }
      return { ...f, itemId: String(catalogItems[0].id) };
    });
  }, [catalogItems]);

  const poolItems = useMemo(() => {
    if (!selected) return [];
    return sortPool(selected.items, poolSort);
  }, [selected, poolSort]);

  const percents = useMemo(() => dropPercents(poolItems), [poolItems]);

  return (
    <div>
      <div className="section-head">
        <div>
          <h1>Drop rates</h1>
          <p className="muted">Weights per case · % shown from relative weights</p>
        </div>
        <select
          className="admin-search"
          value={selectedCaseId}
          onChange={(e) => setSelectedCaseId(e.target.value)}
          aria-label="Select case"
        >
          {cases.map((c) => (
            <option key={c.id} value={c.id}>
              {c.name} ({c.items.length})
            </option>
          ))}
        </select>
      </div>

      {error && <div className="error">{error}</div>}

      {!selected ? (
        <div className="empty">Create a case first.</div>
      ) : (
        <>
          <div className="admin-block">
            <h3>
              Add drop · {selected.name}{' '}
              <span className="muted">({formatCredits(selected.price)} cr)</span>
            </h3>
            <div className="admin-toolbar" style={{ marginBottom: '0.75rem' }}>
              <select
                value={categoryFilter}
                onChange={(e) => setCategoryFilter(e.target.value)}
                aria-label="Filter category"
              >
                <option value="all">All categories</option>
                {usedCategories.map((c) => (
                  <option key={c} value={c}>
                    {c}
                  </option>
                ))}
              </select>
              <select
                value={itemSort}
                onChange={(e) => setItemSort(e.target.value)}
                aria-label="Sort catalog items"
              >
                <option value="value-desc">Sort: value ↓</option>
                <option value="value-asc">Sort: value ↑</option>
                <option value="name">Sort: name</option>
                <option value="rarity">Sort: rarity</option>
              </select>
              <input
                className="admin-search"
                placeholder="Search items…"
                value={itemQuery}
                onChange={(e) => setItemQuery(e.target.value)}
                aria-label="Search catalog items"
              />
            </div>
            <form
              className="admin-row"
              onSubmit={async (e) => {
                e.preventDefault();
                setError('');
                try {
                  await api.addCaseItem(Number(selectedCaseId), {
                    itemId: Number(dropForm.itemId),
                    dropRate: Number(dropForm.dropRate),
                  });
                  await load();
                } catch (err) {
                  setError(err.message);
                }
              }}
            >
              <select
                value={dropForm.itemId}
                onChange={(e) => setDropForm({ ...dropForm, itemId: e.target.value })}
                disabled={!catalogItems.length}
                aria-label="Select item to add"
              >
                {catalogItems.length === 0 ? (
                  <option value="">No matching items</option>
                ) : (
                  catalogItems.map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.name} ({item.rarity}) · {formatCredits(item.marketValue)} cr
                    </option>
                  ))
                )}
              </select>
              <input
                type="number"
                step="0.1"
                min="0.01"
                value={dropForm.dropRate}
                onChange={(e) => setDropForm({ ...dropForm, dropRate: e.target.value })}
                placeholder="Weight"
                required
              />
              <button className="btn" type="submit" disabled={!dropForm.itemId}>
                Add drop
              </button>
            </form>
          </div>

          <div className="admin-block">
            <div className="section-head" style={{ marginBottom: '0.75rem' }}>
              <h3 style={{ margin: 0 }}>Pool ({poolItems.length})</h3>
              <select
                value={poolSort}
                onChange={(e) => setPoolSort(e.target.value)}
                aria-label="Sort pool"
              >
                <option value="rate-asc">Sort: weight ↑</option>
                <option value="rate-desc">Sort: weight ↓</option>
                <option value="value-desc">Sort: value ↓</option>
                <option value="value-asc">Sort: value ↑</option>
                <option value="name">Sort: name</option>
                <option value="rarity">Sort: rarity</option>
              </select>
            </div>
            {poolItems.length === 0 ? (
              <div className="muted">No drops yet.</div>
            ) : (
              <div className="drop-list">
                {poolItems.map((ci, idx) => (
                  <div key={ci.id} className="drop-row">
                    <span className="drop-item-cell">
                      {ci.item.imageUrl ? (
                        <img src={ci.item.imageUrl} alt="" className="drop-thumb" />
                      ) : null}
                      {ci.item.name}{' '}
                      <span className="muted">
                        ({ci.item.rarity}) · {formatCredits(ci.item.marketValue)} cr
                      </span>
                    </span>
                    <input
                      type="number"
                      step="0.1"
                      min="0.01"
                      defaultValue={ci.dropRate}
                      key={`${ci.id}-${ci.dropRate}`}
                      onBlur={async (e) => {
                        const dropRate = Number(e.target.value);
                        if (!(dropRate > 0) || dropRate === ci.dropRate) return;
                        try {
                          await api.updateCaseItem(ci.id, { dropRate });
                          await load();
                        } catch (err) {
                          setError(err.message);
                        }
                      }}
                    />
                    <span className="admin-drop-pct">{percents[idx].toFixed(2)}%</span>
                    <button
                      type="button"
                      className="btn danger"
                      onClick={async () => {
                        await api.deleteCaseItem(ci.id);
                        await load();
                      }}
                    >
                      Remove
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
}
