package d2datadict

import (
	"log"

	"github.com/OpenDiablo2/OpenDiablo2/d2common"
)

// SkillDetails has all of the SkillRecords
//nolint:gochecknoglobals // Currently global by design, only written once
var SkillDetails map[int]*SkillRecord

// SkillRecord is a row from the skills.txt file. Here are two resources for more info on each field
// [https://d2mods.info/forum/viewtopic.php?t=41556, https://d2mods.info/forum/kb/viewarticle?a=246]
type SkillRecord struct {
	Skill             string
	Charclass         string
	Skilldesc         string
	Prgcalc1          string
	Prgcalc2          string
	Prgcalc3          string
	Srvmissile        string
	Srvmissilea       string
	Srvmissileb       string
	Srvmissilec       string
	Srvoverlay        string
	Aurastate         string
	Auratargetstate   string
	Auralencalc       string
	Aurarangecalc     string
	Aurastat1         string
	Aurastatcalc1     string
	Aurastat2         string
	Aurastatcalc2     string
	Aurastat3         string
	Aurastatcalc3     string
	Aurastat4         string
	Aurastatcalc4     string
	Aurastat5         string
	Aurastatcalc5     string
	Aurastat6         string
	Aurastatcalc6     string
	Auraevent1        string
	Auraevent2        string
	Auraevent3        string
	Auratgtevent      string
	Auratgteventfunc  string
	Passivestate      string
	Passiveitype      string
	Passivestat1      string
	Passivecalc1      string
	Passivestat2      string
	Passivecalc2      string
	Passivestat3      string
	Passivecalc3      string
	Passivestat4      string
	Passivecalc4      string
	Passivestat5      string
	Passivecalc5      string
	Passiveevent      string
	Passiveeventfunc  string
	Summon            string
	Pettype           string
	Petmax            string
	Summode           string
	Sumskill1         string
	Sumsk1calc        string
	Sumskill2         string
	Sumsk2calc        string
	Sumskill3         string
	Sumsk3calc        string
	Sumskill4         string
	Sumsk4calc        string
	Sumskill5         string
	Sumsk5calc        string
	Sumoverlay        string
	Stsound           string
	Stsoundclass      string
	Dosound           string
	DosoundA          string
	DosoundB          string
	Tgtoverlay        string
	Tgtsound          string
	Prgoverlay        string
	Prgsound          string
	Castoverlay       string
	Cltoverlaya       string
	Cltoverlayb       string
	Cltmissile        string
	Cltmissilea       string
	Cltmissileb       string
	Cltmissilec       string
	Cltmissiled       string
	Cltcalc1          string
	Cltcalc1Desc      string
	Cltcalc2          string
	Cltcalc2Desc      string
	Cltcalc3          string
	Cltcalc3Desc      string
	Range             string
	Itypea1           string
	Itypea2           string
	Itypea3           string
	Etypea1           string
	Etypea2           string
	Itypeb1           string
	Itypeb2           string
	Itypeb3           string
	Etypeb1           string
	Etypeb2           string
	Anim              string
	Seqtrans          string
	Monanim           string
	ItemCastSound     string
	ItemCastOverlay   string
	Skpoints          string
	Reqskill1         string
	Reqskill2         string
	Reqskill3         string
	State1            string
	State2            string
	State3            string
	Perdelay          string
	Calc1             string
	Calc1Desc         string
	Calc2             string
	Calc2Desc         string
	Calc3             string
	Calc3Desc         string
	Calc4             string
	Calc4Desc         string
	Param1Desc        string
	Param2Desc        string
	Param3Desc        string
	Param4Desc        string
	Param5Desc        string
	Param6Desc        string
	Param7Desc        string
	Param8Desc        string
	ToHitCalc         string
	DmgSymPerCalc     string
	EType             string
	EDmgSymPerCalc    string
	ELenSymPerCalc    string
	ID                int
	Srvstfunc         int
	Srvdofunc         int
	Srvprgfunc1       int
	Srvprgfunc2       int
	Srvprgfunc3       int
	Prgdam            int
	Aurafilter        int
	Auraeventfunc1    int
	Auraeventfunc2    int
	Auraeventfunc3    int
	Sumumod           int
	Cltstfunc         int
	Cltdofunc         int
	Cltprgfunc1       int
	Cltprgfunc2       int
	Cltprgfunc3       int
	Attackrank        int
	Weapsel           int
	Seqnum            int
	Seqinput          int
	LineOfSight       int
	SelectProc        int
	ItemEffect        int
	ItemCltEffect     int
	ItemTgtDo         int
	ItemTarget        int
	Reqlevel          int
	Maxlvl            int
	Reqstr            int
	Reqdex            int
	Reqint            int
	Reqvit            int
	Restrict          int
	Delay             int
	Checkfunc         int
	Startmana         int
	Minmana           int
	Manashift         int
	Mana              int
	Lvlmana           int
	Param1            int
	Param2            int
	Param3            int
	Param4            int
	Param5            int
	Param6            int
	Param7            int
	Param8            int
	ToHit             int
	LevToHit          int
	ResultFlags       int
	HitFlags          int
	HitClass          int
	HitShift          int
	SrcDam            int
	MinDam            int
	MinLevDam1        int
	MinLevDam2        int
	MinLevDam3        int
	MinLevDam4        int
	MinLevDam5        int
	MaxDam            int
	MaxLevDam1        int
	MaxLevDam2        int
	MaxLevDam3        int
	MaxLevDam4        int
	MaxLevDam5        int
	EMin              int
	EMinLev1          int
	EMinLev2          int
	EMinLev3          int
	EMinLev4          int
	EMinLev5          int
	EMax              int
	EMaxLev1          int
	EMaxLev2          int
	EMaxLev3          int
	EMaxLev4          int
	EMaxLev5          int
	ELen              int
	ELevLen1          int
	ELevLen2          int
	ELevLen3          int
	Aitype            int
	Aibonus           int
	CostMult          int
	CostAdd           int
	Prgstack          bool
	Decquant          bool
	Lob               bool
	Stsuccessonly     bool
	Stsounddelay      bool
	Weaponsnd         bool
	Warp              bool
	Immediate         bool
	Enhanceable       bool
	Noammo            bool
	Durability        bool
	UseAttackRate     bool
	TargetableOnly    bool
	SearchEnemyXY     bool
	SearchEnemyNear   bool
	SearchOpenXY      bool
	TargetCorpse      bool
	TargetPet         bool
	TargetAlly        bool
	TargetItem        bool
	AttackNoMana      bool
	TgtPlaceCheck     bool
	ItemCheckStart    bool
	ItemCltCheckStart bool
	Leftskill         bool
	Repeat            bool
	Nocostinstate     bool
	Usemanaondo       bool
	Interrupt         bool
	InTown            bool
	Aura              bool
	Periodic          bool
	Finishing         bool
	Passive           bool
	Progressive       bool
	General           bool
	Scroll            bool
	InGame            bool
	Kick              bool
}

// LoadSkills loads skills.txt file contents into a skill record map
//nolint:funlen // Makes no sense to split
// LoadCharStats loads charstats.txt file contents into map[d2enum.Hero]*CharStatsRecord
func LoadSkills(file []byte) {
	SkillDetails = make(map[int]*SkillRecord)

	d := d2common.LoadDataDictionary(file)
	for d.Next() {
		record := &SkillRecord{
			Skill:             d.String("skill"),
			ID:                d.Number("Id"),
			Charclass:         d.String("charclass"),
			Skilldesc:         d.String("skilldesc"),
			Srvstfunc:         d.Number("srvstfunc"),
			Srvdofunc:         d.Number("srvdofunc"),
			Prgstack:          d.Bool("prgstack"),
			Srvprgfunc1:       d.Number("srvprgfunc1"),
			Srvprgfunc2:       d.Number("srvprgfunc2"),
			Srvprgfunc3:       d.Number("srvprgfunc3"),
			Prgcalc1:          d.String("prgcalc1"),
			Prgcalc2:          d.String("prgcalc2"),
			Prgcalc3:          d.String("prgcalc3"),
			Prgdam:            d.Number("prgdam"),
			Srvmissile:        d.String("srvmissile"),
			Decquant:          d.Bool("decquant"),
			Lob:               d.Bool("lob"),
			Srvmissilea:       d.String("srvmissilea"),
			Srvmissileb:       d.String("srvmissileb"),
			Srvmissilec:       d.String("srvmissilec"),
			Srvoverlay:        d.String("srvoverlay"),
			Aurafilter:        d.Number("aurafilter"),
			Aurastate:         d.String("aurastate"),
			Auratargetstate:   d.String("auratargetstate"),
			Auralencalc:       d.String("auralencalc"),
			Aurarangecalc:     d.String("aurarangecalc"),
			Aurastat1:         d.String("aurastat1"),
			Aurastatcalc1:     d.String("aurastatcalc1"),
			Aurastat2:         d.String("aurastat2"),
			Aurastatcalc2:     d.String("aurastatcalc2"),
			Aurastat3:         d.String("aurastat3"),
			Aurastatcalc3:     d.String("aurastatcalc3"),
			Aurastat4:         d.String("aurastat4"),
			Aurastatcalc4:     d.String("aurastatcalc4"),
			Aurastat5:         d.String("aurastat5"),
			Aurastatcalc5:     d.String("aurastatcalc5"),
			Aurastat6:         d.String("aurastat6"),
			Aurastatcalc6:     d.String("aurastatcalc6"),
			Auraevent1:        d.String("auraevent1"),
			Auraeventfunc1:    d.Number("auraeventfunc1"),
			Auraevent2:        d.String("auraevent2"),
			Auraeventfunc2:    d.Number("auraeventfunc2"),
			Auraevent3:        d.String("auraevent3"),
			Auraeventfunc3:    d.Number("auraeventfunc3"),
			Auratgtevent:      d.String("auratgtevent"),
			Auratgteventfunc:  d.String("auratgteventfunc"),
			Passivestate:      d.String("passivestate"),
			Passiveitype:      d.String("passiveitype"),
			Passivestat1:      d.String("passivestat1"),
			Passivecalc1:      d.String("passivecalc1"),
			Passivestat2:      d.String("passivestat2"),
			Passivecalc2:      d.String("passivecalc2"),
			Passivestat3:      d.String("passivestat3"),
			Passivecalc3:      d.String("passivecalc3"),
			Passivestat4:      d.String("passivestat4"),
			Passivecalc4:      d.String("passivecalc4"),
			Passivestat5:      d.String("passivestat5"),
			Passivecalc5:      d.String("passivecalc5"),
			Passiveevent:      d.String("passiveevent"),
			Passiveeventfunc:  d.String("passiveeventfunc"),
			Summon:            d.String("summon"),
			Pettype:           d.String("pettype"),
			Petmax:            d.String("petmax"),
			Summode:           d.String("summode"),
			Sumskill1:         d.String("sumskill1"),
			Sumsk1calc:        d.String("sumsk1calc"),
			Sumskill2:         d.String("sumskill2"),
			Sumsk2calc:        d.String("sumsk2calc"),
			Sumskill3:         d.String("sumskill3"),
			Sumsk3calc:        d.String("sumsk3calc"),
			Sumskill4:         d.String("sumskill4"),
			Sumsk4calc:        d.String("sumsk4calc"),
			Sumskill5:         d.String("sumskill5"),
			Sumsk5calc:        d.String("sumsk5calc"),
			Sumumod:           d.Number("sumumod"),
			Sumoverlay:        d.String("sumoverlay"),
			Stsuccessonly:     d.Bool("stsuccessonly"),
			Stsound:           d.String("stsound"),
			Stsoundclass:      d.String("stsoundclass"),
			Stsounddelay:      d.Bool("stsounddelay"),
			Weaponsnd:         d.Bool("weaponsnd"),
			Dosound:           d.String("dosound"),
			DosoundA:          d.String("dosound a"),
			DosoundB:          d.String("dosound b"),
			Tgtoverlay:        d.String("tgtoverlay"),
			Tgtsound:          d.String("tgtsound"),
			Prgoverlay:        d.String("prgoverlay"),
			Prgsound:          d.String("prgsound"),
			Castoverlay:       d.String("castoverlay"),
			Cltoverlaya:       d.String("cltoverlaya"),
			Cltoverlayb:       d.String("cltoverlayb"),
			Cltstfunc:         d.Number("cltstfunc"),
			Cltdofunc:         d.Number("cltdofunc"),
			Cltprgfunc1:       d.Number("cltprgfunc1"),
			Cltprgfunc2:       d.Number("cltprgfunc2"),
			Cltprgfunc3:       d.Number("cltprgfunc3"),
			Cltmissile:        d.String("cltmissile"),
			Cltmissilea:       d.String("cltmissilea"),
			Cltmissileb:       d.String("cltmissileb"),
			Cltmissilec:       d.String("cltmissilec"),
			Cltmissiled:       d.String("cltmissiled"),
			Cltcalc1:          d.String("cltcalc1"),
			Cltcalc1Desc:      d.String("*cltcalc1 desc"),
			Cltcalc2:          d.String("cltcalc2"),
			Cltcalc2Desc:      d.String("*cltcalc2 desc"),
			Cltcalc3:          d.String("cltcalc3"),
			Cltcalc3Desc:      d.String("*cltcalc3 desc"),
			Warp:              d.Bool("warp"),
			Immediate:         d.Bool("immediate"),
			Enhanceable:       d.Bool("enhanceable"),
			Attackrank:        d.Number("attackrank"),
			Noammo:            d.Bool("noammo"),
			Range:             d.String("range"),
			Weapsel:           d.Number("weapsel"),
			Itypea1:           d.String("itypea1"),
			Itypea2:           d.String("itypea2"),
			Itypea3:           d.String("itypea3"),
			Etypea1:           d.String("etypea1"),
			Etypea2:           d.String("etypea2"),
			Itypeb1:           d.String("itypeb1"),
			Itypeb2:           d.String("itypeb2"),
			Itypeb3:           d.String("itypeb3"),
			Etypeb1:           d.String("etypeb1"),
			Etypeb2:           d.String("etypeb2"),
			Anim:              d.String("anim"),
			Seqtrans:          d.String("seqtrans"),
			Monanim:           d.String("monanim"),
			Seqnum:            d.Number("seqnum"),
			Seqinput:          d.Number("seqinput"),
			Durability:        d.Bool("durability"),
			UseAttackRate:     d.Bool("UseAttackRate"),
			LineOfSight:       d.Number("LineOfSight"),
			TargetableOnly:    d.Bool("TargetableOnly"),
			SearchEnemyXY:     d.Bool("SearchEnemyXY"),
			SearchEnemyNear:   d.Bool("SearchEnemyNear"),
			SearchOpenXY:      d.Bool("SearchOpenXY"),
			SelectProc:        d.Number("SelectProc"),
			TargetCorpse:      d.Bool("TargetCorpse"),
			TargetPet:         d.Bool("TargetPet"),
			TargetAlly:        d.Bool("TargetAlly"),
			TargetItem:        d.Bool("TargetItem"),
			AttackNoMana:      d.Bool("AttackNoMana"),
			TgtPlaceCheck:     d.Bool("TgtPlaceCheck"),
			ItemEffect:        d.Number("ItemEffect"),
			ItemCltEffect:     d.Number("ItemCltEffect"),
			ItemTgtDo:         d.Number("ItemTgtDo"),
			ItemTarget:        d.Number("ItemTarget"),
			ItemCheckStart:    d.Bool("ItemCheckStart"),
			ItemCltCheckStart: d.Bool("ItemCltCheckStart"),
			ItemCastSound:     d.String("ItemCastSound"),
			ItemCastOverlay:   d.String("ItemCastOverlay"),
			Skpoints:          d.String("skpoints"),
			Reqlevel:          d.Number("reqlevel"),
			Maxlvl:            d.Number("maxlvl"),
			Reqstr:            d.Number("reqstr"),
			Reqdex:            d.Number("reqdex"),
			Reqint:            d.Number("reqint"),
			Reqvit:            d.Number("reqvit"),
			Reqskill1:         d.String("reqskill1"),
			Reqskill2:         d.String("reqskill2"),
			Reqskill3:         d.String("reqskill3"),
			Restrict:          d.Number("restrict"),
			State1:            d.String("State1"),
			State2:            d.String("State2"),
			State3:            d.String("State3"),
			Delay:             d.Number("delay"),
			Leftskill:         d.Bool("leftskill"),
			Repeat:            d.Bool("repeat"),
			Checkfunc:         d.Number("checkfunc"),
			Nocostinstate:     d.Bool("nocostinstate"),
			Usemanaondo:       d.Bool("usemanaondo"),
			Startmana:         d.Number("startmana"),
			Minmana:           d.Number("minmana"),
			Manashift:         d.Number("manashift"),
			Mana:              d.Number("mana"),
			Lvlmana:           d.Number("lvlmana"),
			Interrupt:         d.Bool("interrupt"),
			InTown:            d.Bool("InTown"),
			Aura:              d.Bool("aura"),
			Periodic:          d.Bool("periodic"),
			Perdelay:          d.String("perdelay"),
			Finishing:         d.Bool("finishing"),
			Passive:           d.Bool("passive"),
			Progressive:       d.Bool("progressive"),
			General:           d.Bool("general"),
			Scroll:            d.Bool("scroll"),
			Calc1:             d.String("calc1"),
			Calc1Desc:         d.String("*calc1 desc"),
			Calc2:             d.String("calc2"),
			Calc2Desc:         d.String("*calc2 desc"),
			Calc3:             d.String("calc3"),
			Calc3Desc:         d.String("*calc3 desc"),
			Calc4:             d.String("calc4"),
			Calc4Desc:         d.String("*calc4 desc"),
			Param1:            d.Number("Param1"),
			Param1Desc:        d.String("*Param1 Description"),
			Param2:            d.Number("Param2"),
			Param2Desc:        d.String("*Param2 Description"),
			Param3:            d.Number("Param3"),
			Param3Desc:        d.String("*Param3 Description"),
			Param4:            d.Number("Param4"),
			Param4Desc:        d.String("*Param4 Description"),
			Param5:            d.Number("Param5"),
			Param5Desc:        d.String("*Param5 Description"),
			Param6:            d.Number("Param6"),
			Param6Desc:        d.String("*Param6 Description"),
			Param7:            d.Number("Param7"),
			Param7Desc:        d.String("*Param7 Description"),
			Param8:            d.Number("Param8"),
			Param8Desc:        d.String("*Param8 Description"),
			InGame:            d.Bool("InGame"),
			ToHit:             d.Number("ToHit"),
			LevToHit:          d.Number("LevToHit"),
			ToHitCalc:         d.String("ToHitCalc"),
			ResultFlags:       d.Number("ResultFlags"),
			HitFlags:          d.Number("HitFlags"),
			HitClass:          d.Number("HitClass"),
			Kick:              d.Bool("Kick"),
			HitShift:          d.Number("HitShift"),
			SrcDam:            d.Number("SrcDam"),
			MinDam:            d.Number("MinDam"),
			MinLevDam1:        d.Number("MinLevDam1"),
			MinLevDam2:        d.Number("MinLevDam2"),
			MinLevDam3:        d.Number("MinLevDam3"),
			MinLevDam4:        d.Number("MinLevDam4"),
			MinLevDam5:        d.Number("MinLevDam5"),
			MaxDam:            d.Number("MaxDam"),
			MaxLevDam1:        d.Number("MaxLevDam1"),
			MaxLevDam2:        d.Number("MaxLevDam2"),
			MaxLevDam3:        d.Number("MaxLevDam3"),
			MaxLevDam4:        d.Number("MaxLevDam4"),
			MaxLevDam5:        d.Number("MaxLevDam5"),
			DmgSymPerCalc:     d.String("DmgSymPerCalc"),
			EType:             d.String("EType"),
			EMin:              d.Number("EMin"),
			EMinLev1:          d.Number("EMinLev1"),
			EMinLev2:          d.Number("EMinLev2"),
			EMinLev3:          d.Number("EMinLev3"),
			EMinLev4:          d.Number("EMinLev4"),
			EMinLev5:          d.Number("EMinLev5"),
			EMax:              d.Number("EMax"),
			EMaxLev1:          d.Number("EMaxLev1"),
			EMaxLev2:          d.Number("EMaxLev2"),
			EMaxLev3:          d.Number("EMaxLev3"),
			EMaxLev4:          d.Number("EMaxLev4"),
			EMaxLev5:          d.Number("EMaxLev5"),
			EDmgSymPerCalc:    d.String("EDmgSymPerCalc"),
			ELen:              d.Number("ELen"),
			ELevLen1:          d.Number("ELevLen1"),
			ELevLen2:          d.Number("ELevLen2"),
			ELevLen3:          d.Number("ELevLen3"),
			ELenSymPerCalc:    d.String("ELenSymPerCalc"),
			Aitype:            d.Number("aitype"),
			Aibonus:           d.Number("aibonus"),
			CostMult:          d.Number("cost mult"),
			CostAdd:           d.Number("cost add"),
		}
		SkillDetails[record.ID] = record
	}

	if d.Err != nil {
		panic(d.Err)
	}

	log.Printf("Loaded %d Skill records", len(SkillDetails))
}
