import type { Spell } from '../game'
import { createStackCounts, summarizeStackCounts } from './stackCounts'

export type UpgradeChoice<T extends string> = {
  id: T
  name: string
  description: string
}

export function slotLabel(slot: string, spells: Spell[], labelMode: 'ability' | 'slot') {
  const spell = spells.find((candidate) => candidate.key === slot)
  if (labelMode === 'ability' && spell) return spell.name
  return `Slot ${slot}`
}

export function buildSelfSlotUpgradeChoices<T extends string>({
  slots,
  spells,
  labelMode,
  idPrefix = 'slot',
}: {
  slots: readonly string[]
  spells: Spell[]
  labelMode: 'ability' | 'slot'
  idPrefix?: string
}) {
  return slots.flatMap((slot) => {
    const label = slotLabel(slot, spells, labelMode)
    return [
      {
        id: `${idPrefix}${slot}-extra-target` as T,
        name: `${label}: +1 target`,
        description: `${label} affects 1 additional ally when possible.`,
      },
      {
        id: `${idPrefix}${slot}-cost-down` as T,
        name: `${label}: -25% cost`,
        description: `${label} costs 25% less resource.`,
      },
      {
        id: `${idPrefix}${slot}-cooldown-down` as T,
        name: `${label}: -25% cooldown`,
        description: `${label} recharges 25% faster.`,
      },
    ]
  })
}

export function buildOpponentSlotDebuffChoices<T extends string>({
  slots,
  spells,
  labelMode,
}: {
  slots: readonly string[]
  spells: Spell[]
  labelMode: 'ability' | 'slot'
}) {
  return slots.flatMap((slot) => {
    const label = slotLabel(slot, spells, labelMode)
    return [
      {
        id: `opp-slot${slot}-cost-up` as T,
        name: `${label}: +25% cost`,
        description: `Opponent ${label.toLowerCase()} costs 25% more resource.`,
      },
      {
        id: `opp-slot${slot}-cooldown-up` as T,
        name: `${label}: +25% cooldown`,
        description: `Opponent ${label.toLowerCase()} recharges 25% slower.`,
      },
    ]
  })
}

export function summarizeChoiceStacks<T extends string>(
  items: T[],
  catalog: Array<UpgradeChoice<T>>,
  emptyLabel = '',
) {
  return summarizeStackCounts(createStackCounts(items), catalog, emptyLabel)
}
