import * as React from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import axios from 'axios';

const RANK_ORDER = ['None', 'Respected', 'Distinguished', 'Famed', 'Hero']

function normalizeRenown(r) {
  const s = String(r || '').trim()
  return RANK_ORDER.find(x => x.toLowerCase() === s.toLowerCase()) || 'None'
}

function renownBadge(r) {
  const rn = normalizeRenown(r)
  if (rn === 'Respected')    return 'bg-emerald-700 text-emerald-100'
  if (rn === 'Distinguished') return 'bg-indigo-700 text-indigo-100'
  if (rn === 'Famed')        return 'bg-purple-700 text-purple-100'
  if (rn === 'Hero')         return 'bg-rose-700 text-rose-100'
  return 'bg-slate-700 text-slate-300'
}

function canAfford(playerRp, playerRenown, item) {
  const rpOk = (playerRp || 0) >= item.req
  const renownRequired = normalizeRenown(item.renown)
  const renownOk = renownRequired === 'Any' ||
    RANK_ORDER.indexOf(normalizeRenown(playerRenown)) >= RANK_ORDER.indexOf(renownRequired)
  return { rpOk, renownOk, ok: rpOk && renownOk }
}

export default function RequisitionShop({ authedPlayer, sessionId }) {
  const isGM = authedPlayer === 'gm'

  // ── Player state ─────────────────────────────────────────────────
  const [playerRp, setPlayerRp] = useState(0)
  const [playerRenown, setPlayerRenown] = useState('None')
  const [playerGear, setPlayerGear] = useState([])
  const [playerLoaded, setPlayerLoaded] = useState(false)

  // ── Shop state ───────────────────────────────────────────────────
  const [items, setItems] = useState([])
  const [search, setSearch] = useState('')
  const [categoryFilter, setCategoryFilter] = useState('All')
  const [renownFilter, setRenownFilter] = useState('All')
  const [showAffordableOnly, setShowAffordableOnly] = useState(false)

  // ── GM panel state ───────────────────────────────────────────────
  const [allPlayers, setAllPlayers] = useState([])
  const [gmRpTarget, setGmRpTarget] = useState('')
  const [gmRpPlayer, setGmRpPlayer] = useState('')
  const [gmRenownPlayer, setGmRenownPlayer] = useState('')
  const [gmRenownValue, setGmRenownValue] = useState('Respected')

  // ── UI state ─────────────────────────────────────────────────────
  const [message, setMessage] = useState('')   // success (green)
  const [error, setError] = useState('')       // error (red)
  const [saving, setSaving] = useState(false)
  const [showGear, setShowGear] = useState(false)

  // ─── Flash helpers ───────────────────────────────────────────────
  function flashMsg(msg) { setMessage(msg); setError(''); setTimeout(() => setMessage(''), 3500) }
  function flashErr(msg) { setError(msg); setMessage(''); setTimeout(() => setError(''), 4000) }

  // ─── Load current player ─────────────────────────────────────────
  const loadPlayer = useCallback(async () => {
    if (!authedPlayer || isGM) return
    try {
      const res = await axios.get(`/api/players/${authedPlayer}`)
      const tab = res.data?.tabInfo || {}
      setPlayerRp(Number(tab.rp) || 0)
      setPlayerRenown(tab.renown || 'None')
      setPlayerGear(Array.isArray(tab.gear) ? tab.gear : [])
      setPlayerLoaded(true)
    } catch (e) {
      setPlayerLoaded(true)
    }
  }, [authedPlayer, isGM])

  // ─── Load all players (GM) ───────────────────────────────────────
  const loadAllPlayers = useCallback(async () => {
    if (!isGM) return
    try {
      const res = await axios.get('/api/players', {
        headers: { 'x-session-id': sessionId || '' }
      })
      setAllPlayers(Array.isArray(res.data) ? res.data.filter(p => p.name !== 'gm') : [])
    } catch {}
  }, [isGM, sessionId])

  // ─── Load shop items ─────────────────────────────────────────────
  useEffect(() => {
    axios.get('/api/shop').then(res => {
      const byCategory = res.data?.items || {}
      const flat = []
      for (const cat in byCategory) {
        if (!Array.isArray(byCategory[cat])) continue
        for (const item of byCategory[cat]) {
          if ((item.req || 0) > 0) {
            flat.push({
              id: `${cat}-${item.name}`,
              name: item.name,
              category: cat,
              req: item.req,
              renown: item.renown || 'Any',
              stats: item.stats || {},
            })
          }
        }
      }
      setItems(flat)
    }).catch(() => {})
  }, [])

  useEffect(() => { loadPlayer() }, [loadPlayer])
  useEffect(() => { loadAllPlayers() }, [loadAllPlayers])

  // ─── Purchase ────────────────────────────────────────────────────
  async function purchaseItem(item) {
    if (!authedPlayer || isGM) return
    if (!sessionId) { flashErr('Session expired — please log in again.'); return }

    const { rpOk, renownOk } = canAfford(playerRp, playerRenown, item)
    if (!rpOk)     { flashErr(`Not enough RP. Need ${item.req}, have ${playerRp}.`); return }
    if (!renownOk) { flashErr(`Requires ${item.renown} renown. You are ${playerRenown}.`); return }

    setSaving(true)
    try {
      const res = await axios.post('/api/shop/purchase',
        { playerId: authedPlayer, itemId: item.id, quantity: 1 },
        { headers: { 'x-session-id': sessionId } }
      )
      // Optimistic update from server response, then re-fetch for accuracy
      if (typeof res.data?.newRp === 'number') setPlayerRp(res.data.newRp)
      flashMsg(`Purchased ${item.name} for ${item.req} RP`)
      await loadPlayer()
    } catch (e) {
      flashErr(e.response?.data?.error || 'Purchase failed')
    } finally {
      setSaving(false)
    }
  }

  // ─── GM: set RP ─────────────────────────────────────────────────
  async function gmSetRp(playerName, rp) {
    if (!isGM) return
    try {
      await axios.post('/api/players/gm/set-rp',
        { playerName, requisitionPoints: Number(rp) },
        { headers: { 'x-gm-secret': process.env.REACT_APP_GM_SECRET || '', 'x-session-id': sessionId } }
      )
      flashMsg(`Set ${playerName} to ${rp} RP`)
      await loadAllPlayers()
    } catch (e) {
      flashErr(e.response?.data?.error || 'Failed to set RP')
    }
  }

  // ─── GM: set renown ──────────────────────────────────────────────
  async function gmSetRenown(playerName, renown) {
    if (!isGM) return
    try {
      await axios.post('/api/players/gm/set-renown',
        { playerName, renown },
        { headers: { 'x-gm-secret': process.env.REACT_APP_GM_SECRET || '', 'x-session-id': sessionId } }
      )
      flashMsg(`Set ${playerName} renown to ${renown}`)
      await loadAllPlayers()
    } catch (e) {
      flashErr(e.response?.data?.error || 'Failed to set renown')
    }
  }

  // ─── Derived ─────────────────────────────────────────────────────
  const categories = useMemo(() => {
    const s = new Set(items.map(i => i.category))
    return ['All', ...Array.from(s).sort()]
  }, [items])

  const filteredItems = useMemo(() => {
    const q = search.trim().toLowerCase()
    return items.filter(item => {
      if (q && !item.name.toLowerCase().includes(q) && !item.category.toLowerCase().includes(q)) return false
      if (categoryFilter !== 'All' && item.category !== categoryFilter) return false
      if (renownFilter !== 'All' && normalizeRenown(item.renown) !== renownFilter) return false
      if (showAffordableOnly && !isGM) {
        const { ok } = canAfford(playerRp, playerRenown, item)
        if (!ok) return false
      }
      return true
    })
  }, [items, search, categoryFilter, renownFilter, showAffordableOnly, playerRp, playerRenown, isGM])

  // ─── Render ──────────────────────────────────────────────────────
  if (!authedPlayer) {
    return (
      <div className="rounded-2xl bg-slate-800 border border-slate-700 p-6">
        <h2 className="text-2xl font-bold mb-3">Requisition Shop</h2>
        <p className="text-amber-300">Please log in to access the shop.</p>
      </div>
    )
  }

  return (
    <div className="rounded-2xl bg-slate-800 border border-slate-700 p-5 shadow-xl space-y-4">
      <h2 className="text-2xl font-bold">Requisition Shop</h2>

      {message && (
        <div className="rounded-lg border border-emerald-500/40 bg-emerald-950/30 px-4 py-2 text-sm text-emerald-200">{message}</div>
      )}
      {error && (
        <div className="rounded-lg border border-red-500/40 bg-red-950/30 px-4 py-2 text-sm text-red-200">{error}</div>
      )}

      {/* ── Player status bar ── */}
      {!isGM && playerLoaded && (
        <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-blue-500/30 bg-blue-950/20 px-4 py-3">
          <div className="flex items-center gap-4">
            <div>
              <div className="text-xs uppercase tracking-wide text-blue-300">Battle-Brother</div>
              <div className="text-lg font-bold capitalize">{authedPlayer}</div>
            </div>
            <div className="h-10 w-px bg-blue-800/60" />
            <div>
              <div className="text-xs uppercase tracking-wide text-blue-300">Requisition Points</div>
              <div className="text-2xl font-bold text-amber-300 tabular-nums">{playerRp} RP</div>
            </div>
            <div className="h-10 w-px bg-blue-800/60" />
            <div>
              <div className="text-xs uppercase tracking-wide text-blue-300">Renown</div>
              <span className={`mt-0.5 inline-block rounded px-2 py-0.5 text-xs font-semibold ${renownBadge(playerRenown)}`}>
                {playerRenown}
              </span>
            </div>
          </div>
          <button
            onClick={() => setShowGear(v => !v)}
            className="rounded bg-slate-700 px-3 py-1.5 text-sm hover:bg-slate-600"
          >
            {showGear ? 'Hide Gear' : `Gear (${playerGear.length})`}
          </button>
        </div>
      )}

      {/* ── Gear inventory ── */}
      {!isGM && showGear && (
        <div className="rounded-lg border border-slate-700 bg-slate-900/60 p-4">
          <div className="mb-2 text-sm font-semibold uppercase tracking-wide text-slate-300">Requisitioned Gear</div>
          {playerGear.length === 0 ? (
            <p className="text-sm text-slate-500">No items requisitioned yet.</p>
          ) : (
            <div className="grid gap-1.5 sm:grid-cols-2 lg:grid-cols-3">
              {playerGear.map((g, i) => (
                <div key={i} className="flex items-center justify-between rounded border border-slate-700 bg-slate-800 px-3 py-2 text-sm">
                  <span className="font-medium text-slate-100">{g.name}</span>
                  {g.qty > 1 && <span className="rounded bg-slate-700 px-1.5 py-0.5 text-xs text-slate-300">×{g.qty}</span>}
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* ── GM panel: manage all players ── */}
      {isGM && (
        <div className="rounded-lg border border-amber-500/30 bg-amber-950/10 p-4 space-y-4">
          <div className="text-sm font-semibold uppercase tracking-wide text-amber-300">GM — Manage RP & Renown</div>

          {/* Player RP table */}
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-slate-700 text-left text-xs uppercase tracking-wide text-slate-400">
                  <th className="pb-2 pr-4">Player</th>
                  <th className="pb-2 pr-4">RP</th>
                  <th className="pb-2 pr-4">Renown</th>
                  <th className="pb-2">Gear</th>
                </tr>
              </thead>
              <tbody>
                {allPlayers.map(p => {
                  const tab = p.tabInfo || {}
                  return (
                    <tr key={p.name} className="border-b border-slate-800">
                      <td className="py-2 pr-4 font-medium capitalize">{p.name}</td>
                      <td className="py-2 pr-4 text-amber-300 font-bold tabular-nums">{tab.rp ?? 0}</td>
                      <td className="py-2 pr-4">
                        <span className={`rounded px-1.5 py-0.5 text-xs ${renownBadge(tab.renown)}`}>{tab.renown || 'None'}</span>
                      </td>
                      <td className="py-2 text-xs text-slate-400">
                        {Array.isArray(tab.gear) && tab.gear.length > 0
                          ? tab.gear.map(g => g.name).join(', ')
                          : '—'}
                      </td>
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>

          {/* Set RP form */}
          <div className="grid gap-3 sm:grid-cols-2">
            <div>
              <div className="mb-1 text-xs text-slate-400">Set RP</div>
              <div className="flex gap-2">
                <select
                  value={gmRpPlayer}
                  onChange={e => setGmRpPlayer(e.target.value)}
                  className="flex-1 rounded border border-slate-600 bg-slate-900 px-2 py-1.5 text-sm"
                >
                  <option value="">Select player</option>
                  {allPlayers.map(p => <option key={p.name} value={p.name}>{p.name}</option>)}
                </select>
                <input
                  type="number"
                  min="0"
                  max="999"
                  value={gmRpTarget}
                  onChange={e => setGmRpTarget(e.target.value)}
                  placeholder="RP"
                  className="w-20 rounded border border-slate-600 bg-slate-900 px-2 py-1.5 text-sm"
                />
                <button
                  onClick={() => { if (gmRpPlayer && gmRpTarget !== '') gmSetRp(gmRpPlayer, gmRpTarget) }}
                  disabled={!gmRpPlayer || gmRpTarget === ''}
                  className="rounded bg-amber-700 px-3 py-1.5 text-sm hover:bg-amber-600 disabled:opacity-40"
                >
                  Set
                </button>
              </div>
            </div>
            <div>
              <div className="mb-1 text-xs text-slate-400">Set Renown</div>
              <div className="flex gap-2">
                <select
                  value={gmRenownPlayer}
                  onChange={e => setGmRenownPlayer(e.target.value)}
                  className="flex-1 rounded border border-slate-600 bg-slate-900 px-2 py-1.5 text-sm"
                >
                  <option value="">Select player</option>
                  {allPlayers.map(p => <option key={p.name} value={p.name}>{p.name}</option>)}
                </select>
                <select
                  value={gmRenownValue}
                  onChange={e => setGmRenownValue(e.target.value)}
                  className="rounded border border-slate-600 bg-slate-900 px-2 py-1.5 text-sm"
                >
                  {RANK_ORDER.filter(r => r !== 'None').map(r => <option key={r} value={r}>{r}</option>)}
                </select>
                <button
                  onClick={() => { if (gmRenownPlayer) gmSetRenown(gmRenownPlayer, gmRenownValue) }}
                  disabled={!gmRenownPlayer}
                  className="rounded bg-indigo-700 px-3 py-1.5 text-sm hover:bg-indigo-600 disabled:opacity-40"
                >
                  Set
                </button>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* ── Filters ── */}
      <div className="flex flex-wrap gap-2">
        <input
          className="flex-1 min-w-40 rounded border border-slate-600 bg-slate-800 px-3 py-2 text-sm"
          placeholder="Search items..."
          value={search}
          onChange={e => setSearch(e.target.value)}
        />
        <select
          className="rounded border border-slate-600 bg-slate-800 px-3 py-2 text-sm"
          value={categoryFilter}
          onChange={e => setCategoryFilter(e.target.value)}
        >
          {categories.map(c => <option key={c} value={c}>{c}</option>)}
        </select>
        <select
          className="rounded border border-slate-600 bg-slate-800 px-3 py-2 text-sm"
          value={renownFilter}
          onChange={e => setRenownFilter(e.target.value)}
        >
          <option value="All">All Renown</option>
          {RANK_ORDER.filter(r => r !== 'None').concat(['Any']).map(r => (
            <option key={r} value={r}>{r}</option>
          ))}
        </select>
        {!isGM && (
          <label className="flex items-center gap-2 rounded border border-slate-600 bg-slate-800 px-3 py-2 text-sm cursor-pointer select-none">
            <input
              type="checkbox"
              checked={showAffordableOnly}
              onChange={e => setShowAffordableOnly(e.target.checked)}
              className="rounded"
            />
            Affordable only
          </label>
        )}
      </div>

      <div className="text-xs text-slate-500">{filteredItems.length} items</div>

      {/* ── Items grid ── */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
        {filteredItems.map(item => {
          const { rpOk, renownOk, ok } = canAfford(playerRp, playerRenown, item)
          const btnClass = isGM
            ? 'rounded bg-slate-700 px-3 py-1.5 text-xs text-slate-300 cursor-default'
            : ok
              ? 'rounded bg-blue-600 px-3 py-1.5 text-sm hover:bg-blue-500 disabled:opacity-50'
              : 'rounded bg-slate-700 px-3 py-1.5 text-xs text-slate-400 cursor-not-allowed'

          let btnLabel = 'Buy'
          if (isGM) btnLabel = `${item.req} RP`
          else if (!rpOk && !renownOk) btnLabel = 'Need RP + Renown'
          else if (!rpOk)     btnLabel = `Need ${item.req} RP`
          else if (!renownOk) btnLabel = `Need ${item.renown}`

          return (
            <div
              key={item.id}
              className={`rounded-lg border p-3 flex flex-col gap-2 ${
                !isGM && ok ? 'border-blue-700/40 bg-slate-800' : 'border-slate-700 bg-slate-800/70'
              }`}
            >
              <div>
                <div className="font-semibold text-white leading-tight">{item.name}</div>
                <div className="text-xs text-slate-400 mt-0.5">{item.category}</div>
              </div>

              {/* Stats */}
              {item.stats?.damage && (
                <div className="text-xs text-slate-300 leading-relaxed">{item.stats.damage}</div>
              )}
              {item.stats?.class && (
                <div className="text-xs text-slate-400">{item.stats.class}</div>
              )}
              {item.stats?.source && (
                <div className="text-xs text-slate-600">{item.stats.source}</div>
              )}

              <div className="mt-auto flex items-center justify-between gap-2 pt-1">
                <div className="flex items-center gap-2">
                  <span className="text-xs font-bold text-amber-300">{item.req} RP</span>
                  {normalizeRenown(item.renown) !== 'None' && item.renown !== 'Any' && (
                    <span className={`rounded px-1.5 py-0.5 text-xs ${renownBadge(item.renown)}`}>
                      {item.renown}
                    </span>
                  )}
                </div>
                {!isGM && (
                  <button
                    onClick={() => purchaseItem(item)}
                    disabled={!ok || saving}
                    className={btnClass}
                  >
                    {btnLabel}
                  </button>
                )}
              </div>
            </div>
          )
        })}
      </div>

      {filteredItems.length === 0 && (
        <div className="py-8 text-center text-slate-500">
          {showAffordableOnly ? 'No items you can currently afford.' : 'No items match your filters.'}
        </div>
      )}
    </div>
  )
}
