import type { Equipment, EquipmentType } from "@elysium/types";
import { useState } from "react";
import { useGame } from "../../context/GameContext.js";
import { EQUIPMENT_SETS } from "../../data/equipmentSets.js";
import { LockToggle } from "../ui/LockToggle.js";

const RARITY_LABEL: Record<string, string> = {
  common: "Common",
  rare: "Rare",
  epic: "Epic",
  legendary: "Legendary",
};

const TYPE_ICON: Record<EquipmentType, string> = {
  weapon: "⚔️",
  armour: "🛡️",
  trinket: "💍",
};

const bonusDescription = (item: Equipment): string => {
  const parts: string[] = [];
  if (item.bonus.combatMultiplier != null) {
    parts.push(`+${Math.round((item.bonus.combatMultiplier - 1) * 100)}% Combat`);
  }
  if (item.bonus.goldMultiplier != null) {
    parts.push(`+${Math.round((item.bonus.goldMultiplier - 1) * 100)}% Gold/s`);
  }
  if (item.bonus.clickMultiplier != null) {
    parts.push(`+${Math.round((item.bonus.clickMultiplier - 1) * 100)}% Click`);
  }
  return parts.join(", ");
};

interface EquipmentCardProps {
  item: Equipment;
  gold: number;
  essence: number;
  crystals: number;
  dropBossName?: string | undefined;
  setName?: string | undefined;
}

const costLabel = (cost: { gold: number; essence: number; crystals: number }): string => {
  const parts: string[] = [];
  if (cost.gold > 0) parts.push(`🪙 ${cost.gold.toLocaleString()}`);
  if (cost.essence > 0) parts.push(`✨ ${cost.essence.toLocaleString()}`);
  if (cost.crystals > 0) parts.push(`💎 ${cost.crystals.toLocaleString()}`);
  return parts.join("  ");
};

const EquipmentCard = ({ item, gold, essence, crystals, dropBossName, setName }: EquipmentCardProps): React.JSX.Element => {
  const { equipItem, buyEquipment } = useGame();

  const canAfford = item.cost
    ? gold >= item.cost.gold && essence >= item.cost.essence && crystals >= item.cost.crystals
    : false;

  return (
    <div className={`equipment-card rarity-${item.rarity} ${item.equipped ? "equipped" : ""} ${!item.owned ? "not-owned" : ""}`}>
      <div className="equipment-icon">{TYPE_ICON[item.type]}</div>
      <div className="equipment-info">
        <div className="equipment-name-row">
          <h3>{item.name}</h3>
          <span className={`rarity-badge rarity-${item.rarity}`}>{RARITY_LABEL[item.rarity]}</span>
        </div>
        <p className="equipment-description">{item.description}</p>
        <p className="equipment-bonus">{bonusDescription(item)}</p>
        {setName && <span className="equipment-set-badge">🔗 {setName}</span>}
        {!item.owned && item.cost && (
          <p className="equipment-cost">{costLabel(item.cost)}</p>
        )}
      </div>
      <div className="equipment-action">
        {!item.owned && !item.cost && (
          <span className="equipment-locked">
            {dropBossName ? `⚔️ Drop: ${dropBossName}` : "🔒 Boss drop"}
          </span>
        )}
        {!item.owned && item.cost && (
          <button
            className="equip-button"
            disabled={!canAfford}
            onClick={() => { buyEquipment(item.id); }}
            type="button"
          >
            {canAfford ? "Purchase" : "Can't afford"}
          </button>
        )}
        {item.owned && item.equipped && <span className="equipment-equipped-badge">✓ Equipped</span>}
        {item.owned && !item.equipped && (
          <button
            className="equip-button"
            onClick={() => { equipItem(item.id); }}
            type="button"
          >
            Equip
          </button>
        )}
      </div>
    </div>
  );
};

const SLOT_ORDER: EquipmentType[] = ["weapon", "armour", "trinket"];
const SLOT_LABEL: Record<EquipmentType, string> = {
  weapon: "⚔️ Weapons",
  armour: "🛡️ Armour",
  trinket: "💍 Trinkets",
};

export const EquipmentPanel = (): React.JSX.Element => {
  const { state } = useGame();
  const [showLocked, setShowLocked] = useState(true);

  if (!state) return <section className="panel"><p>Loading...</p></section>;

  const equipment = state.equipment ?? [];
  const unownedCount = equipment.filter((e) => !e.owned).length;

  const equipmentDropSources = new Map<string, string>();
  for (const boss of state.bosses) {
    for (const equipmentId of (boss.equipmentRewards ?? [])) {
      equipmentDropSources.set(equipmentId, boss.name);
    }
  }

  // Build set name lookup for card badges
  const setNameById = new Map<string, string>(
    EQUIPMENT_SETS.map((s) => [s.id, s.name]),
  );

  // Compute active set bonuses for the summary strip
  const equippedItemIds = equipment.filter((e) => e.equipped).map((e) => e.id);
  const activeSets = EQUIPMENT_SETS.map((set) => {
    const count = set.pieces.filter((id) => equippedItemIds.includes(id)).length;
    return { set, count };
  }).filter(({ count }) => count >= 2);

  const setBonusDescription = (set: typeof EQUIPMENT_SETS[number], count: number): string => {
    const parts: string[] = [];
    for (const threshold of [2, 3] as const) {
      if (count >= threshold) {
        const bonus = set.bonuses[threshold];
        if (bonus.goldMultiplier) parts.push(`+${Math.round((bonus.goldMultiplier - 1) * 100)}% Gold/s (${threshold}pc)`);
        if (bonus.combatMultiplier) parts.push(`+${Math.round((bonus.combatMultiplier - 1) * 100)}% Combat (${threshold}pc)`);
        if (bonus.clickMultiplier) parts.push(`+${Math.round((bonus.clickMultiplier - 1) * 100)}% Click (${threshold}pc)`);
      }
    }
    return parts.join(", ");
  };

  return (
    <section className="panel equipment-panel">
      <div className="panel-header">
        <h2>Equipment</h2>
        <LockToggle
          lockedCount={unownedCount}
          showLocked={showLocked}
          onToggle={() => { setShowLocked((v) => !v); }}
        />
      </div>
      <p className="equipment-intro">
        Equipment drops from bosses and grants passive bonuses. Only one item per slot can be equipped at a time. Equip matching set pieces for bonus effects!
      </p>

      {activeSets.length > 0 && (
        <div className="active-sets">
          <h3 className="active-sets-heading">✨ Active Set Bonuses</h3>
          {activeSets.map(({ set, count }) => (
            <div key={set.id} className="active-set-row">
              <span className="active-set-name">{set.name} ({count}/{set.pieces.length})</span>
              <span className="active-set-bonus">{setBonusDescription(set, count)}</span>
            </div>
          ))}
        </div>
      )}

      {SLOT_ORDER.map((slotType) => {
        const items = equipment.filter(
          (e) => e.type === slotType && (showLocked || e.owned),
        );
        return (
          <div key={slotType} className="equipment-slot-section">
            <h3 className="slot-heading">{SLOT_LABEL[slotType]}</h3>
            <div className="equipment-list">
              {items.map((item) => (
                <EquipmentCard
                  key={item.id}
                  item={item}
                  gold={state.resources.gold}
                  essence={state.resources.essence}
                  crystals={state.resources.crystals}
                  dropBossName={equipmentDropSources.get(item.id)}
                  setName={item.setId ? setNameById.get(item.setId) : undefined}
                />
              ))}
              {items.length === 0 && (
                <p className="empty-zone">No items to show in this slot.</p>
              )}
            </div>
          </div>
        );
      })}
    </section>
  );
};
