package theorycrafter.tournaments.impl

import eve.data.EveData
import eve.data.NNBSP
import eve.data.ShipType
import theorycrafter.tournaments.PointsCompositionRules.MarginalShipCostComputation
import theorycrafter.tournaments.TournamentDescriptor
import theorycrafter.tournaments.TournamentRules
import theorycrafter.tournaments.marginalShipCostComputationWithDuplicatePenalty
import theorycrafter.tournaments.shipsCostWithDuplicatePenalty


/**
 * The descriptor for Alliance Tournament XX (2024).
 */
val AllianceTournamentXX = TournamentDescriptor(
    id = "atxx",
    name = "Alliance Tournament XX",
    shortName = "AT${NNBSP}XX",
    rulesFactory = ::allianceTournamentXXRules,
    winner = "The Tuskers Co."
)


/**
 * Maps ship type names to their point values.
 */
private val ShipCostByName = mapOf(
    "Impairor" to 1,
    "Ibis" to 1,
    "Velator" to 1,
    "Reaper" to 1,
    "Executioner" to 4,
    "Tormentor" to 4,
    "Punisher" to 6,
    "Magnate" to 4,
    "Condor" to 4,
    "Kestrel" to 4,
    "Merlin" to 4,
    "Heron" to 4,
    "Atron" to 4,
    "Tristan" to 4,
    "Incursus" to 4,
    "Imicus" to 4,
    "Slasher" to 4,
    "Breacher" to 4,
    "Rifter" to 4,
    "Probe" to 4,
    "Inquisitor" to 3,
    "Bantam" to 3,
    "Navitas" to 3,
    "Burst" to 3,
    "Crucifier" to 8,
    "Griffin" to 7,
    "Maulus" to 7,
    "Vigil" to 6,
    "Imperial Navy Slicer" to 6,
    "Crucifier Navy Issue" to 6,
    "Caldari Navy Hookbill" to 6,
    "Griffin Navy Issue" to 6,
    "Federation Navy Comet" to 6,
    "Maulus Navy Issue" to 6,
    "Republic Fleet Firetail" to 6,
    "Vigil Fleet Issue" to 6,
    "Vengeance" to 9,
    "Retribution" to 9,
    "Hawk" to 9,
    "Harpy" to 9,
    "Ishkur" to 9,
    "Enyo" to 9,
    "Wolf" to 9,
    "Jaguar" to 9,
    "Anathema" to 4,
    "Buzzard" to 4,
    "Helios" to 4,
    "Cheetah" to 4,
    "Purifier" to 7,
    "Manticore" to 7,
    "Nemesis" to 7,
    "Hound" to 7,
    "Sentinel" to 14,
    "Kitsune" to 11,
    "Keres" to 14,
    "Hyena" to 11,
    "Crusader" to 6,
    "Malediction" to 6,
    "Crow" to 6,
    "Raptor" to 6,
    "Taranis" to 6,
    "Ares" to 6,
    "Claw" to 6,
    "Stiletto" to 6,
    "Deacon" to 10,
    "Kirin" to 10,
    "Thalia" to 10,
    "Scalpel" to 10,
    "Coercer" to 5,
    "Dragoon" to 5,
    "Cormorant" to 5,
    "Corax" to 5,
    "Catalyst" to 5,
    "Algos" to 5,
    "Thrasher" to 5,
    "Talwar" to 5,
    "Pontifex" to 12,
    "Stork" to 12,
    "Magus" to 12,
    "Bifrost" to 12,
    "Heretic" to 9,
    "Flycatcher" to 9,
    "Eris" to 9,
    "Sabre" to 9,
    "Confessor" to 10,
    "Jackdaw" to 11,
    "Hecate" to 10,
    "Svipul" to 10,
    "Arbitrator" to 14,
    "Blackbird" to 16,
    "Celestis" to 15,
    "Bellicose" to 10,
    "Augoror" to 20,
    "Osprey" to 20,
    "Exequror" to 20,
    "Scythe" to 20,
    "Maller" to 10,
    "Omen" to 9,
    "Moa" to 9,
    "Caracal" to 10,
    "Vexor" to 10,
    "Thorax" to 9,
    "Stabber" to 9,
    "Rupture" to 9,
    "Augoror Navy Issue" to 20,
    "Omen Navy Issue" to 16,
    "Caracal Navy Issue" to 16,
    "Osprey Navy Issue" to 16,
    "Exequror Navy Issue" to 20,
    "Vexor Navy Issue" to 16,
    "Scythe Fleet Issue" to 16,
    "Stabber Fleet Issue" to 16,
    "Zealot" to 26,
    "Sacrilege" to 26,
    "Eagle" to 26,
    "Cerberus" to 26,
    "Ishtar" to 26,
    "Deimos" to 26,
    "Vagabond" to 26,
    "Muninn" to 26,
    "Devoter" to 24,
    "Onyx" to 24,
    "Phobos" to 24,
    "Broadsword" to 24,
    "Guardian" to 32,
    "Basilisk" to 32,
    "Oneiros" to 32,
    "Scimitar" to 32,
    "Curse" to 30,
    "Pilgrim" to 27,
    "Falcon" to 28,
    "Rook" to 28,
    "Arazu" to 28,
    "Lachesis" to 28,
    "Huginn" to 27,
    "Rapier" to 27,
    "Legion" to 31,
    "Tengu" to 31,
    "Proteus" to 31,
    "Loki" to 32,
    "Oracle" to 22,
    "Naga" to 22,
    "Talos" to 22,
    "Tornado" to 22,
    "Prophecy" to 28,
    "Harbinger" to 28,
    "Drake" to 28,
    "Ferox" to 28,
    "Brutix" to 28,
    "Myrmidon" to 28,
    "Hurricane" to 28,
    "Cyclone" to 28,
    "Harbinger Navy Issue" to 30,
    "Drake Navy Issue" to 30,
    "Brutix Navy Issue" to 30,
    "Hurricane Fleet Issue" to 30,
    "Damnation" to 36,
    "Absolution" to 36,
    "Vulture" to 36,
    "Nighthawk" to 36,
    "Astarte" to 36,
    "Eos" to 36,
    "Claymore" to 36,
    "Sleipnir" to 36,
    "Abaddon" to 39,
    "Apocalypse" to 39,
    "Armageddon" to 39,
    "Scorpion" to 39,
    "Raven" to 39,
    "Rokh" to 39,
    "Hyperion" to 39,
    "Megathron" to 39,
    "Dominix" to 39,
    "Tempest" to 39,
    "Typhoon" to 39,
    "Maelstrom" to 39,
    "Praxis" to 39,
    "Apocalypse Navy Issue" to 42,
    "Armageddon Navy Issue" to 44,
    "Scorpion Navy Issue" to 45,
    "Raven Navy Issue" to 42,
    "Megathron Navy Issue" to 42,
    "Dominix Navy Issue" to 45,
    "Tempest Fleet Issue" to 42,
    "Typhoon Fleet Issue" to 45,
    "Redeemer" to 43,
    "Widow" to 50,
    "Sin" to 43,
    "Panther" to 43,
    "Paladin" to 48,
    "Golem" to 48,
    "Kronos" to 48,
    "Vargur" to 48,
    "Bestower" to 3,
    "Sigil" to 3,
    "Badger" to 3,
    "Tayra" to 3,
    "Nereus" to 3,
    "Kryos" to 3,
    "Epithal" to 3,
    "Miasmos" to 3,
    "Iteron Mark V" to 3,
    "Hoarder" to 3,
    "Mammoth" to 3,
    "Wreathe" to 3,
    "Dramiel" to 8,
    "Cruor" to 9,
    "Worm" to 10,
    "Garmur" to 8,
    "Succubus" to 8,
    "Astero" to 8,
    "Daredevil" to 8,
    "Cynabal" to 15,
    "Ashimmu" to 18,
    "Gila" to 25,
    "Orthrus" to 19,
    "Phantasm" to 18,
    "Stratios" to 18,
    "Vigilant" to 18,
    "Machariel" to 47,
    "Bhaalgorn" to 53,
    "Rattlesnake" to 52,
    "Barghest" to 54,
    "Nightmare" to 51,
    "Vindicator" to 50,
    "Gnosis" to 28,
    "Sunesis" to 5,
    "Thunderchild" to 37,
    "Stormbringer" to 14,
    "Skybreaker" to 5,
    "Leshak" to 54,
    "Zarmazd" to 34,
    "Drekavac" to 34,
    "Ikitursa" to 28,
    "Rodiva" to 24,
    "Draugur" to 15,
    "Vedmak" to 19,
    "Kikimora" to 14,
    "Nergal" to 11,
    "Damavik" to 10,
    "Echo" to 2,
    "Hematos" to 2,
    "Immolator" to 2,
    "Taipan" to 2,
    "Violator" to 2,
    "Magnate Navy Issue" to 6,
    "Heron Navy Issue" to 6,
    "Imicus Navy Issue" to 6,
    "Probe Fleet Issue" to 6,
    "Thrasher Fleet Issue" to 11,
    "Cormorant Navy Issue" to 11,
    "Coercer Navy Issue" to 11,
    "Catalyst Navy Issue" to 11,
    "Cyclone Fleet Issue" to 32,
    "Ferox Navy Issue" to 30,
    "Prophecy Navy Issue" to 30,
    "Myrmidon Navy Issue" to 30,
    "Metamorphosis" to 5,
    "Khizriel" to 35,
    "Alligator" to 36,
    "Mamba" to 14,
    "Mekubal" to 14,
    "Squall" to 4,
    "Deluge" to 10,
    "Geri" to 32,
    "Bestla" to 47,
    "Laelaps" to 50,
    "Raiju" to 37,
    "Shapash" to 33,
    "Cybele" to 48,
)


/**
 * The list of non-Battleship ships that can be a flagship.
 */
private val nonBattleshipFlagships = setOf(
    "Geri",
    "Bestla",
    "Laelaps",
    "Raiju",
    "Shapash",
    "Cybele",
)


/**
 * The composition rules for Alliance Tournament XX.
 */
private class AtXXCompositionRules(eveData: EveData): AllianceTournamentCompositionRules(
    eveData = eveData,
    maxCompositionSize = 10,
    maxCompositionCost = 200,
    shipCostByName = ShipCostByName,
    maxShipsInSizeClass = 4,
    nonBattleshipFlagships = nonBattleshipFlagships
) {


    override fun shipsCost(shipTypes: List<ShipType?>): List<Int> {
        return shipsCostWithDuplicatePenalty(shipTypes, shipCostByType)
    }


    override fun marginalShipCostComputation(usedShipTypes: List<ShipType?>): MarginalShipCostComputation {
        return marginalShipCostComputationWithDuplicatePenalty(usedShipTypes, shipCostByType)
    }


}


/**
 * The fitting rules for Alliance Tournament XX.
 */
private class AtXXFittingRules(eveData: EveData): AllianceTournamentFittingRules(eveData, nonBattleshipFlagships) {

    override fun canBeFlagship(shipType: ShipType): Boolean {
        if (shipType.name == "Widow")
            return false

        return super.canBeFlagship(shipType)
    }

}


/**
 * The rules for Alliance Tournament XX.
 */
private fun allianceTournamentXXRules(eveData: EveData) =
    TournamentRules(
        compositionRules = AtXXCompositionRules(eveData),
        fittingRules = AtXXFittingRules(eveData)
    )
