import { useCallback, useEffect, useState } from 'react';
import { api } from '../api/api';
import { ApiError } from '../api/http';
import type { InventoryResponse, MarketEntry, MarketResponse } from '../api/types';
import { useAuth } from '../auth/AuthContext';
import { useToast } from '../components/Toast';
import { getSocket } from '../realtime/socket';
import { formatMoney } from '../shared/format';

export function MarketScreen() {
  const { player, refreshPlayer } = useAuth();
  const { toast } = useToast();
  const [market, setMarket] = useState<MarketResponse | null>(null);
  const [inventory, setInventory] = useState<InventoryResponse | null>(null);
  const [selected, setSelected] = useState<MarketEntry | null>(null);
  const [quantity, setQuantity] = useState(1);
  const [busy, setBusy] = useState(false);

  const reload = useCallback(async () => {
    const [m, inv] = await Promise.all([api.market(), api.inventory()]);
    setMarket(m);
    setInventory(inv);
  }, []);

  useEffect(() => {
    void reload();
  }, [reload]);

  // Il mercato si aggiorna a ogni tick del server
  useEffect(() => {
    const socket = getSocket();
    if (!socket) return;
    const onUpdate = () => void reload();
    socket.on('market:updated', onUpdate);
    return () => {
      socket.off('market:updated', onUpdate);
    };
  }, [reload]);

  const owned = (itemId: string) =>
    inventory?.items.find((i) => i.itemId === itemId)?.quantity ?? 0;

  async function trade(kind: 'buy' | 'sell') {
    if (!selected) return;
    setBusy(true);
    try {
      const fn = kind === 'buy' ? api.buy : api.sell;
      const res = await fn(selected.itemId, quantity);
      toast(
        kind === 'buy'
          ? `Comprati ${res.quantity}× ${res.itemName} per ${formatMoney(res.total)}`
          : `Venduti ${res.quantity}× ${res.itemName} per ${formatMoney(res.total)}`,
        'success',
      );
      setSelected(null);
      setQuantity(1);
      await Promise.all([reload(), refreshPlayer()]);
    } catch (err) {
      toast(err instanceof ApiError ? err.message : 'Errore imprevisto', 'error');
    } finally {
      setBusy(false);
    }
  }

  if (!market) return <p className="muted screen">Caricamento mercato...</p>;

  return (
    <div className="screen">
      <h2 className="screen__title">Mercato di {market.city.name}</h2>

      {market.activeEvents.length > 0 && (
        <div className="banner">
          {market.activeEvents.map((e) => (
            <span key={e.id}>⚡ {e.title}</span>
          ))}
        </div>
      )}

      <ul className="list">
        {market.prices.map((entry) => (
          <li
            key={entry.itemId}
            className="list__row list__row--clickable"
            onClick={() => {
              setSelected(entry);
              setQuantity(1);
            }}
          >
            <div>
              <strong>{entry.name}</strong>
              {owned(entry.itemId) > 0 && (
                <span className="badge badge--small">×{owned(entry.itemId)}</span>
              )}
            </div>
            <div className="prices">
              <span className="price price--buy">{formatMoney(entry.buyPrice)}</span>
              <span className="price price--sell">{formatMoney(entry.sellPrice)}</span>
            </div>
          </li>
        ))}
      </ul>
      <p className="muted small">
        Prezzo a sinistra: acquisto · a destra: vendita. I prezzi cambiano ogni minuto.
      </p>

      {selected && (
        <div className="modal-backdrop" onClick={() => setSelected(null)}>
          <div className="modal" onClick={(e) => e.stopPropagation()}>
            <h3>{selected.name}</h3>
            <p className="muted small">
              Possiedi: {owned(selected.itemId)} · peso {selected.weight}/unità
            </p>
            <label className="quantity">
              Quantità
              <div className="quantity__controls">
                <button type="button" onClick={() => setQuantity((q) => Math.max(1, q - 1))}>
                  −
                </button>
                <input
                  type="number"
                  min={1}
                  max={100}
                  value={quantity}
                  onChange={(e) =>
                    setQuantity(Math.max(1, Math.min(100, Number(e.target.value) || 1)))
                  }
                />
                <button type="button" onClick={() => setQuantity((q) => Math.min(100, q + 1))}>
                  +
                </button>
              </div>
            </label>
            <div className="modal__actions">
              <button
                type="button"
                className="btn btn--primary"
                disabled={busy || (player?.money ?? 0) < selected.buyPrice * quantity}
                onClick={() => void trade('buy')}
              >
                Compra · {formatMoney(selected.buyPrice * quantity)}
              </button>
              <button
                type="button"
                className="btn btn--secondary"
                disabled={busy || owned(selected.itemId) < quantity}
                onClick={() => void trade('sell')}
              >
                Vendi · {formatMoney(selected.sellPrice * quantity)}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
