/* global React */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ============================================================
// ATOMIC COMPONENTS
// ============================================================

function ZoneBackdrop({ zone }) {
  if (!zone) return null;
  return (
    <div className="zone-backdrop" style={{ background: zone.bg }}>
      <div className="zone-horizon"></div>
      <svg
        className="zone-silhouette"
        viewBox="0 0 100 100"
        preserveAspectRatio="none"
      >
        <path d={zone.silhouette} fill="rgba(0,0,0,0.85)" />
        <path
          d={zone.silhouette}
          fill="rgba(0,0,0,0.4)"
          transform="translate(0, -6)"
          style={{ opacity: 0.5 }}
        />
      </svg>
      <div className="zone-grain"></div>
    </div>
  );
}

function formatNum(n) {
  if (n == null) return '0';
  if (n >= 1000) return (n / 1000).toFixed(1).replace(/\.0$/, '') + 'K';
  return Math.round(n).toString();
}

function HpBar({ hp, hpMax, size = 'sm', showPct = false, label = 'HP' }) {
  const pct = Math.max(0, Math.min(100, (hp / hpMax) * 100));
  const cls = pct < 25 ? 'low' : pct < 55 ? 'mid' : '';
  return (
    <div className="bar-row">
      {label && <span className="key">{label}</span>}
      <div className={`bar bar-hp ${cls}`}>
        <div className="bar-fill" style={{ width: `${pct}%` }}></div>
        <span className="bar-num">
          {showPct ? `${pct.toFixed(1)}%` : `${formatNum(hp)} / ${formatNum(hpMax)}`}
        </span>
      </div>
    </div>
  );
}

function ResourceBar({ value, max, kind, label }) {
  const pct = Math.max(0, Math.min(100, (value / max) * 100));
  const cls = `bar-${kind}`;
  return (
    <div className="bar-row">
      <span className="key">{label}</span>
      <div className={`bar ${cls}`}>
        <div className="bar-fill" style={{ width: `${pct}%` }}></div>
        <span className="bar-num">{formatNum(value)} / {formatNum(max)}</span>
      </div>
    </div>
  );
}

function CastBar({ ability, progress, kind = 'cast' }) {
  if (!ability) return null;
  const cls = `bar-${kind}`;
  return (
    <div className="bar-cast-row">
      <span className="ability-tag">
        <span className="icon">{ability.glyph}</span>
        {ability.name}
      </span>
      <div className={`bar ${cls} ${ability.kind === 'heal' ? 'heal' : ''}`}>
        <div className="bar-fill" style={{ width: `${progress * 100}%` }}></div>
      </div>
      <span className="pct">{Math.round(progress * 100)}%</span>
    </div>
  );
}

function StateIconGroup({ icons, kind }) {
  return (
    <div className={`state-group ${kind === 'buff' ? 'buffs' : 'debuffs'}`}>
      <span className="lbl-icon">{kind === 'buff' ? 'GRUPO' : 'ENEMIGO'}</span>
      {icons.map(ic => (
        <div key={ic.id} className={`state-icon ${kind}`}>
          <span>{ic.glyph}</span>
          <div className="tip">
            <span className="t-name">{ic.name}</span>
            <span className="t-desc">{ic.desc}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

function Timer({ seconds }) {
  const m = Math.floor(seconds / 60).toString().padStart(2, '0');
  const s = Math.floor(seconds % 60).toString().padStart(2, '0');
  return (
    <div className="timer">
      <span className="lbl">TIEMPO</span>
      <span className="val">{m}:{s}</span>
    </div>
  );
}

function WaveCounter({ wave, total, isBoss }) {
  return (
    <div className="wave-counter">
      <span className="lbl">Fase 1 — Oleada</span>
      <span className="val">{wave}/{total}</span>
      <div className="wave-pips">
        {Array.from({ length: total - 1 }).map((_, i) => (
          <div
            key={i}
            className={`wave-pip ${i + 1 < wave ? 'done' : i + 1 === wave ? 'current' : ''}`}
          />
        ))}
        <div className={`wave-pip boss ${wave > total - 1 ? 'current' : wave === total ? 'current' : ''} ${isBoss ? 'done' : ''}`}>
        </div>
      </div>
    </div>
  );
}

function FloatingNumber({ value, kind, x, y, id }) {
  return (
    <div
      key={id}
      className={`dmg-float ${kind}`}
      style={{ left: x, top: y }}
    >
      {kind === 'heal' ? '+' : kind === 'miss' ? '' : '−'}
      {kind === 'miss' ? 'Falló' : formatNum(value)}
      {kind === 'crit' && '!'}
    </div>
  );
}

// ============================================================
// PORTRAIT
// ============================================================

function Portrait({ glyph, tint, slotLabel, badges, big = false, imageUrl }) {
  const [imgFailed, setImgFailed] = useState(false);
  const showImage = !!imageUrl && !imgFailed;
  return (
    <div
      className="portrait"
      style={tint ? { background: `radial-gradient(ellipse at center, ${tint}22 0%, transparent 65%), var(--bg-1)` } : null}
    >
      {badges && badges.length > 0 && (
        <div className="badges">
          {badges.map((b, i) => (
            <div key={i} className={`badge-mini ${b.kind}`}>{b.glyph}</div>
          ))}
        </div>
      )}
      {showImage ? (
        <img
          src={imageUrl}
          alt={slotLabel || ''}
          onError={() => setImgFailed(true)}
          style={{
            position: 'absolute', inset: 0, width: '100%', height: '100%',
            objectFit: 'cover', objectPosition: 'top center', opacity: 0.92,
          }}
        />
      ) : (
        <span className="glyph" style={{ fontSize: big ? 140 : undefined }}>{glyph}</span>
      )}
      {!showImage && <span className="slot-label">{slotLabel}</span>}
    </div>
  );
}

// ============================================================
// EXPORT
// ============================================================

Object.assign(window, {
  ZoneBackdrop, HpBar, ResourceBar, CastBar, StateIconGroup, Timer, WaveCounter,
  FloatingNumber, Portrait, formatNum,
});
