import type { CSSProperties } from "react";
import { ABILITY_CONTROLLER_BINDINGS } from "../game/controllerBindings";
import { HEALER_CLASSES, resolveSlottedAbility } from "../game/healers";
import { runAbilityCastTime, runAbilityCooldown, runAbilityManaCost } from "../game/roguelike";
import { GLOBAL_COOLDOWN_SECONDS, abilityRemaining, useGameStore } from "../game/store";
import type { AbilitySlotId } from "../game/types";

export function AbilityButton({ abilityId, compact = false }: { abilityId: AbilitySlotId; compact?: boolean }) {
  const healerClassId = useGameStore((state) => state.healerClassId);
  const ability = useGameStore((state) => resolveSlottedAbility(state.abilityLoadout, abilityId));
  const time = useGameStore((state) => state.time);
  const cooldowns = useGameStore((state) => state.cooldowns);
  const globalCooldownUntil = useGameStore((state) => state.globalCooldownUntil);
  const mana = useGameStore((state) => state.mana);
  const phase = useGameStore((state) => state.phase);
  const healerAlive = useGameStore((state) => state.party.some((member) => member.id === "aelia" && member.hp > 0));
  const selected = useGameStore((state) => state.party.find((member) => member.id === state.selectedMemberId)!);
  const activeCast = useGameStore((state) => state.activeCast);
  const castAbility = useGameStore((state) => state.castAbility);
  const runModifiers = useGameStore((state) => state.runModifiers);
  const healerMechanic = useGameStore((state) => state.healerMechanic);
  const classes = `ability ability-${abilityId} ${compact ? "is-compact" : ""}`;

  if (!ability) {
    return (
      <button className={`${classes} is-empty`} disabled aria-label={`Empty ${abilityId}`}>
        <span className="ability-key">{Number(abilityId.slice(-1))}</span>
        <span className="ability-icon">—</span>
        <span className="ability-copy"><strong>Empty</strong><small>No spell drafted</small></span>
        <span className="ability-pad">{ABILITY_CONTROLLER_BINDINGS[abilityId].glyph}</span>
      </button>
    );
  }

  const remaining = abilityRemaining(abilityId, time, cooldowns);
  const manaCost = runAbilityManaCost(abilityId, ability.mana, runModifiers);
  const baseCastTime = ability.castTime ? runAbilityCastTime(abilityId, ability.castTime, runModifiers) : 0;
  const castTime = ability.id === "shaman-healing-wave" && healerMechanic.resource > 0 ? baseCastTime * 0.5 : baseCastTime;
  const cooldownDuration = runAbilityCooldown(abilityId, ability.cooldown, runModifiers);
  const globalRemaining = Math.max(0, globalCooldownUntil - time);
  const noDispel = ability.pulseKind === "cleanse" && selected.debuffs.length === 0;
  const invalidTarget = ability.targeting === "ally" && selected.hp <= 0;
  const disabled = phase !== "combat" || !healerAlive || activeCast !== null || remaining > 0 || globalRemaining > 0 || mana < manaCost || noDispel || invalidTarget;
  const resourceName = HEALER_CLASSES[healerClassId].resourceName.toLowerCase();
  const resourceCopy = `${manaCost ? `${manaCost} ${resourceName}` : "free"}${castTime ? ` · ${castTime.toFixed(1)}s` : ""}`;

  return (
    <button
      className={`${classes} ${remaining > 0 || globalRemaining > 0 ? "on-cooldown" : ""}`}
      style={{ "--ability-color": ability.color } as CSSProperties}
      onClick={() => castAbility(abilityId)}
      disabled={disabled}
      title={ability.description}
      aria-label={`${ability.name}. ${ability.description}`}
    >
      <span className="ability-key">{Number(abilityId.slice(-1))}</span>
      <span className="ability-icon">{ability.icon}</span>
      <span className="ability-copy"><strong>{ability.shortName}</strong><small>{resourceCopy}</small></span>
      <span className="ability-pad">{ABILITY_CONTROLLER_BINDINGS[abilityId].glyph}</span>
      {remaining > 0 && (
        <span className="cooldown-mask" style={{ "--cooldown-progress": Math.min(1, remaining / cooldownDuration) } as CSSProperties}>
          <b>{remaining < 1 ? remaining.toFixed(1) : Math.ceil(remaining)}</b>
        </span>
      )}
      {remaining <= 0 && globalRemaining > 0 && (
        <span className="cooldown-mask global-cooldown" style={{ "--cooldown-progress": Math.min(1, globalRemaining / GLOBAL_COOLDOWN_SECONDS) } as CSSProperties}>
          <b>{globalRemaining.toFixed(1)}</b>
        </span>
      )}
    </button>
  );
}
