import { useState } from 'react'
import { SPELL_GLOBAL_COOLDOWN_SECONDS, type HealOverTimeFrame } from '../actionCombatCore'

export type CombatPartyFrameData = {
  bleedTimer?: number
  burnTimer?: number
  damageDone?: number
  healOverTimes: HealOverTimeFrame[]
  hp: number
  id: string
  maxHp: number
  name: string
  renewTimer: number
  role: string
  selected: boolean
  shield: number
  specLabel?: string
}

export type CombatActionSlot<Slot extends number> = {
  canCast: boolean
  cooldown: number
  cooldownBase?: number
  globalClassName?: string
  iconUrl: string
  id: Slot
  keybind?: string
  name: string
  tooltip: {
    cast: string
    cooldown?: string
    cost: string
    description: string
    rank: string
    school: string
    target: string
  }
}

export function CombatPartyFrames({
  className = '',
  compact = false,
  frames,
  manaByFrameId,
  onSelect,
}: {
  className?: string
  compact?: boolean
  frames: CombatPartyFrameData[]
  manaByFrameId?: Record<string, { value: number, max: number } | undefined>
  onSelect?: (id: string) => void
}) {
  return (
    <div className={className} aria-label="Party frames">
      {frames.map((frame) => (
        <CombatPartyFrame
          compact={compact}
          frame={frame}
          key={frame.id}
          mana={manaByFrameId?.[frame.id]}
          onSelect={onSelect ? () => onSelect(frame.id) : undefined}
        />
      ))}
    </div>
  )
}

export function CombatPartyFrame({
  compact = false,
  frame,
  mana,
  onSelect,
}: {
  compact?: boolean
  frame: CombatPartyFrameData
  mana?: { value: number, max: number }
  onSelect?: () => void
}) {
  const percent = Math.max(0, Math.min(100, (frame.hp / frame.maxHp) * 100))
  const rawShieldPercent = Math.max(0, Math.min(100, (frame.shield / frame.maxHp) * 100))
  const shieldLeft = percent >= 99.5 ? 0 : percent
  const shieldPercent = percent >= 99.5 ? rawShieldPercent : Math.min(100 - percent, rawShieldPercent)
  const manaPercent = mana ? Math.max(0, Math.min(100, (mana.value / mana.max) * 100)) : 0

  return (
    <button
      className={`party-frame ${frame.selected ? 'selected' : ''} ${frame.hp <= 0 ? 'dead' : ''} ${compact ? 'compact' : ''}`}
      disabled={!onSelect}
      onClick={onSelect}
      type="button"
    >
      <span className={`role-chip ${frame.role}`}>{frame.specLabel ?? frame.role}</span>
      <strong>{frame.name}</strong>
      <small>{Math.ceil(frame.hp)} / {frame.maxHp}</small>
      <span className="party-damage-meter">Damage {Math.round(frame.damageDone ?? 0).toLocaleString()}</span>
      <i>
        <span className="party-health-fill" style={{ width: `${percent}%` }} />
        {frame.shield > 0 && (
          <span className="party-shield-fill" style={{ left: `${shieldLeft}%`, width: `${shieldPercent}%` }} />
        )}
      </i>
      {mana && (
        <i className="party-mana-track">
          <span className="party-mana-fill" style={{ width: `${manaPercent}%` }} />
        </i>
      )}
      {(frame.shield > 0 || frame.healOverTimes.length > 0) && (
        <span className="party-frame-effects">
          {frame.shield > 0 && <em>Shield {Math.ceil(frame.shield)}</em>}
          {frame.healOverTimes.map((effect) => (
            <em className={`hot ${effect.id}`} key={effect.id}>
              {effect.label} {effect.remaining.toFixed(0)}s
            </em>
          ))}
        </span>
      )}
      {(frame.burnTimer ?? 0) > 0 && <em className="danger">Burn {(frame.burnTimer ?? 0).toFixed(0)}s</em>}
      {(frame.bleedTimer ?? 0) > 0 && <em className="bleed">Bleed {(frame.bleedTimer ?? 0).toFixed(0)}s</em>}
    </button>
  )
}

export function CombatTargetFrame({
  action,
  className = '',
  detail,
  hp,
  kindLabel,
  label,
  maxHp,
  tone = 'enemy',
}: {
  action?: { label: string, onClick: () => void }
  className?: string
  detail: string
  hp: number
  kindLabel: string
  label: string
  maxHp: number
  tone?: 'ally' | 'enemy'
}) {
  return (
    <div className={`combat-target-frame arena-target-chip ${className} ${tone === 'ally' ? 'ally-target' : ''}`}>
      <div>
        <span>{kindLabel}</span>
        <strong>{label}</strong>
        <small>{detail}</small>
      </div>
      <i>
        <b style={{ width: `${Math.max(0, Math.min(100, (hp / maxHp) * 100))}%` }} />
      </i>
      {action && <button type="button" onClick={action.onClick}>{action.label}</button>}
    </div>
  )
}

export function CombatActionBar<Slot extends number>({
  className = '',
  columns,
  globalCooldown,
  onCast,
  slots,
}: {
  className?: string
  columns: number
  globalCooldown: number
  onCast: (slot: Slot) => void
  slots: CombatActionSlot<Slot>[]
}) {
  const [tooltipSlot, setTooltipSlot] = useState<Slot | null>(null)
  const tooltip = slots.find((slot) => slot.id === tooltipSlot)

  return (
    <div
      className={`claudecraft-actionbar ${className}`}
      style={{ gridTemplateColumns: `repeat(${columns}, 48px)` }}
      aria-label="ClaudeCraft action bar"
    >
      {slots.map((slot) => {
        const visibleCooldown = Math.max(slot.cooldown, globalCooldown)
        const cooldownBase = slot.cooldown > 0 ? (slot.cooldownBase ?? 1) : SPELL_GLOBAL_COOLDOWN_SECONDS
        const cooldownPercent = visibleCooldown > 0 && cooldownBase > 0
          ? Math.max(0, Math.min(100, (visibleCooldown / cooldownBase) * 100))
          : 0
        return (
          <button
            aria-label={`${slot.name}, slot ${slot.id}`}
            className={`claudecraft-action-slot ${visibleCooldown > 0 ? 'cooling' : ''} ${globalCooldown > 0 && slot.cooldown <= 0 ? 'global-cooldown' : ''} ${slot.globalClassName ?? ''}`}
            disabled={visibleCooldown > 0 || !slot.canCast}
            key={slot.id}
            onBlur={() => setTooltipSlot(null)}
            onClick={() => onCast(slot.id)}
            onFocus={() => setTooltipSlot(slot.id)}
            onMouseEnter={() => setTooltipSlot(slot.id)}
            onMouseLeave={() => setTooltipSlot(null)}
            type="button"
          >
            <span className="icon-label" style={{ backgroundImage: `url(${slot.iconUrl})` }} />
            <span className="keybind">{slot.keybind ?? slot.id}</span>
            {visibleCooldown > 0 && (
              <>
                <span className="cd-overlay" style={{ height: `${cooldownPercent}%` }} />
                {slot.cooldown > 0 && <span className="cdtext">{slot.cooldown > 1 ? Math.ceil(slot.cooldown) : slot.cooldown.toFixed(1)}</span>}
              </>
            )}
          </button>
        )
      })}
      {tooltip && (
        <div className="claudecraft-action-tooltip" role="tooltip">
          <div className="tooltip-heading">
            <img alt="" draggable="false" src={tooltip.iconUrl} />
            <div>
              <strong>{tooltip.name}</strong>
              <span>{tooltip.tooltip.rank}</span>
            </div>
          </div>
          <dl>
            <div><dt>School</dt><dd>{tooltip.tooltip.school}</dd></div>
            <div><dt>Target</dt><dd>{tooltip.tooltip.target}</dd></div>
            <div><dt>Cost</dt><dd>{tooltip.tooltip.cost}</dd></div>
            <div><dt>Cast</dt><dd>{tooltip.tooltip.cast}</dd></div>
            {tooltip.tooltip.cooldown && <div><dt>Cooldown</dt><dd>{tooltip.tooltip.cooldown}</dd></div>}
          </dl>
          <p>{tooltip.tooltip.description}</p>
          {tooltip.cooldown > 0 && <em>{tooltip.cooldown.toFixed(1)}s remaining</em>}
        </div>
      )}
    </div>
  )
}
