package gsmaster

import (
	"bamort/models"
	"fmt"
)

type LernCostRequest struct {
	CharId       uint   `json:"char_id" binding:"omitempty"`                      // Charakter-ID
	Name         string `json:"name" binding:"omitempty"`                         // Name der Fertigkeit / des Zaubers
	CurrentLevel int    `json:"current_level,omitempty"`                          // Aktueller Wert (nur für Verbesserung)
	Type         string `json:"type" binding:"required,oneof=skill spell weapon"` // 'skill', 'spell' oder 'weapon' Waffenfertigkeiten sind normale Fertigkeiten (evtl. kann hier später der Name der Waffe angegeben werden )
	Action       string `json:"action" binding:"required,oneof=learn improve"`    // 'learn' oder 'improve'
	TargetLevel  int    `json:"target_level,omitempty"`                           // Zielwert (optional, für Kostenberechnung bis zu einem bestimmten Level)
	UsePP        int    `json:"use_pp,omitempty"`                                 // Anzahl der zu verwendenden Praxispunkte
	UseGold      int    `json:"use_gold,omitempty"`                               // Anzahl der zu verwendenden Goldstücke
	// Belohnungsoptionen
	Reward *string `json:"reward" binding:"required,oneof=default noGold halveep halveepnoGold"` // Belohnungsoptionen Lernen als Belohnung
	// default
	// learn: ohne Gold
	// improve/spell: halbe EP kein Gold
}

// DifficultyData enthält Skills und Trainingskosten für eine Schwierigkeitsstufe
type DifficultyData struct {
	LearnCost  int         `json:"learncosts"`
	Skills     []string    `json:"skills"`
	TrainCosts map[int]int `json:"traincosts"`
}

// LearningCostsTable strukturiert die Daten aus Lerntabellen.md
type LearningCostsTable2 struct {
	// EP-Kosten für 1 Trainingseinheit (TE) pro Charakterklasse und Fertigkeitskategorie
	EPPerTE map[string]map[string]int

	// EP-Kosten für 1 Lerneinheit (LE) für Zauber pro Charakterklasse und Zauberschule
	SpellEPPerLE    map[string]map[string]int
	SpellLEPerLevel map[int]int

	// LE-Kosten für Fertigkeiten basierend auf Schwierigkeit
	BaseLearnCost map[string]map[string]int

	// TE-Kosten für Verbesserungen basierend auf Kategorie, Schwierigkeit und aktuellem Wert
	ImprovementCost map[string]map[string]DifficultyData
}

// learningCostsData enthält alle statischen Lerntabellendaten
var learningCostsData = &LearningCostsTable2{
	// EP-Kosten für 1 Trainingseinheit (TE) nach Klasse und Kategorie
	EPPerTE: map[string]map[string]int{
		"As": { // Assassine
			"Alltag":    20,
			"Freiland":  20,
			"Halbwelt":  20,
			"Kampf":     30,
			"Körper":    10,
			"Sozial":    20,
			"Unterwelt": 10,
			"Waffen":    20,
			"Wissen":    20,
		},
		"Bb": { // Barbar
			"Alltag":    20,
			"Freiland":  10,
			"Halbwelt":  30,
			"Kampf":     10,
			"Körper":    10,
			"Sozial":    30,
			"Unterwelt": 30,
			"Waffen":    20,
			"Wissen":    40,
		},
		"Gl": { // Glücksritter
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  10,
			"Kampf":     20,
			"Körper":    30,
			"Sozial":    10,
			"Unterwelt": 30,
			"Waffen":    20,
			"Wissen":    20,
		},
		"Hä": { // Händler
			"Alltag":    10,
			"Freiland":  20,
			"Halbwelt":  20,
			"Kampf":     20,
			"Körper":    20,
			"Sozial":    10,
			"Unterwelt": 40,
			"Waffen":    20,
			"Wissen":    20,
		},
		"Kr": { // Krieger
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  30,
			"Kampf":     10,
			"Körper":    20,
			"Sozial":    20,
			"Unterwelt": 30,
			"Waffen":    10,
			"Wissen":    40,
		},
		"Sp": { // Spitzbube
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  10,
			"Kampf":     40,
			"Körper":    10,
			"Sozial":    10,
			"Unterwelt": 10,
			"Waffen":    20,
			"Wissen":    30,
		},
		"Wa": { // Waldläufer
			"Alltag":    20,
			"Freiland":  10,
			"Halbwelt":  20,
			"Kampf":     20,
			"Körper":    10,
			"Sozial":    30,
			"Unterwelt": 30,
			"Waffen":    20,
			"Wissen":    30,
		},
		"Ba": { // Barde
			"Alltag":    10,
			"Freiland":  20,
			"Halbwelt":  20,
			"Kampf":     40,
			"Körper":    20,
			"Sozial":    30,
			"Unterwelt": 40,
			"Waffen":    40,
			"Wissen":    10,
		},
		"Or": { // Ordenskrieger
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  40,
			"Kampf":     10,
			"Körper":    20,
			"Sozial":    20,
			"Unterwelt": 40,
			"Waffen":    10,
			"Wissen":    20,
		},
		"Dr": { // Druide
			"Alltag":    20,
			"Freiland":  10,
			"Halbwelt":  30,
			"Kampf":     40,
			"Körper":    20,
			"Sozial":    30,
			"Unterwelt": 40,
			"Waffen":    40,
			"Wissen":    10,
		},
		"Hx": { // Hexer
			"Alltag":    20,
			"Freiland":  20,
			"Halbwelt":  30,
			"Kampf":     40,
			"Körper":    30,
			"Sozial":    20,
			"Unterwelt": 30,
			"Waffen":    40,
			"Wissen":    20,
		},
		"Ma": { // Magier
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  40,
			"Kampf":     40,
			"Körper":    30,
			"Sozial":    30,
			"Unterwelt": 40,
			"Waffen":    40,
			"Wissen":    10,
		},
		"PB": { // Priester Beschützer
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  30,
			"Kampf":     40,
			"Körper":    30,
			"Sozial":    10,
			"Unterwelt": 40,
			"Waffen":    40,
			"Wissen":    20,
		},
		"PS": { // Priester Streiter
			"Alltag":    20,
			"Freiland":  30,
			"Halbwelt":  40,
			"Kampf":     30,
			"Körper":    30,
			"Sozial":    30,
			"Unterwelt": 40,
			"Waffen":    30,
			"Wissen":    20,
		},
		"Sc": { // Schamane
			"Alltag":    20,
			"Freiland":  10,
			"Halbwelt":  40,
			"Kampf":     40,
			"Körper":    20,
			"Sozial":    20,
			"Unterwelt": 40,
			"Waffen":    40,
			"Wissen":    20,
		},
	},

	// EP-Kosten für 1 Lerneinheit (LE) für Zauber pro Charakterklasse und Zauberschule
	SpellEPPerLE: map[string]map[string]int{
		"Dr": { // Druide
			"Beherrschen": 90,
			"Bewegen":     60,
			"Erkennen":    120,
			"Erschaffen":  90,
			"Formen":      60,
			"Verändern":   90,
			"Zerstören":   120,
			"Wunder":      0, // Nicht verfügbar
			"Dweomer":     30,
			"Lied":        0, // Nicht verfügbar
		},
		"Hx": { // Hexer
			"Beherrschen": 30,
			"Bewegen":     90,
			"Erkennen":    90,
			"Erschaffen":  90,
			"Formen":      60,
			"Verändern":   30,
			"Zerstören":   60,
			"Wunder":      0, // Nicht verfügbar
			"Dweomer":     90,
			"Lied":        0, // Nicht verfügbar
		},
		"Ma": { // Magier (* = Spezialgebiet für 30 EP)
			"Beherrschen": 60, // *30
			"Bewegen":     60, // *30
			"Erkennen":    60, // *30
			"Erschaffen":  60, // *30
			"Formen":      60, // *30
			"Verändern":   60, // *30
			"Zerstören":   60, // *30
			"Wunder":      0,  // Nicht verfügbar
			"Dweomer":     120,
			"Lied":        0, // Nicht verfügbar
		},
		"PB": { // Priester Beschützer
			"Beherrschen": 90,
			"Bewegen":     90,
			"Erkennen":    60,
			"Erschaffen":  90,
			"Formen":      90,
			"Verändern":   90,
			"Zerstören":   90,
			"Wunder":      30,
			"Dweomer":     120,
			"Lied":        0, // Nicht verfügbar
		},
		"PS": { // Priester Streiter
			"Beherrschen": 90,
			"Bewegen":     90,
			"Erkennen":    90,
			"Erschaffen":  90,
			"Formen":      90,
			"Verändern":   90,
			"Zerstören":   60,
			"Wunder":      30,
			"Dweomer":     120,
			"Lied":        0, // Nicht verfügbar
		},
		"Sc": { // Schamane
			"Beherrschen": 90,
			"Bewegen":     90,
			"Erkennen":    60,
			"Erschaffen":  60,
			"Formen":      90,
			"Verändern":   90,
			"Zerstören":   90,
			"Wunder":      30,
			"Dweomer":     120,
			"Lied":        0, // Nicht verfügbar
		},
		"Ba": { // Barde
			"Beherrschen": 0, // Nicht verfügbar
			"Bewegen":     0, // Nicht verfügbar
			"Erkennen":    0, // Nicht verfügbar
			"Erschaffen":  0, // Nicht verfügbar
			"Formen":      0, // Nicht verfügbar
			"Verändern":   0, // Nicht verfügbar
			"Zerstören":   0, // Nicht verfügbar
			"Wunder":      0, // Nicht verfügbar
			"Dweomer":     0, // Nicht verfügbar
			"Lied":        30,
		},
	},
	// Lernen von Zaubern
	// LE pro Stufe des Zaubers
	SpellLEPerLevel: map[int]int{1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 10, 7: 15, 8: 20, 9: 30, 10: 40, 11: 60, 12: 90},

	// TE-Kosten für Verbesserungen basierend auf Kategorie, Schwierigkeit und aktuellem Wert
	ImprovementCost: map[string]map[string]DifficultyData{
		"Alltag": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Klettern", "Reiten", "Seilkunst", "Bootfahren", "Glücksspiel", "Wagenlenken", "Musizieren"},
				TrainCosts: map[int]int{9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
			},
			"normal": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Schreiben", "Sprache"},
				TrainCosts: map[int]int{9: 1, 10: 1, 11: 1, 12: 1, 13: 2, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
			},
			"schwer": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Erste Hilfe", "Etikette"},
				TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
			},
			"sehr schwer": DifficultyData{
				LearnCost:  10,
				Skills:     []string{"Gerätekunde", "Geschäftssinn"},
				TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
			},
		},
		"Freiland": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Überleben"},
				TrainCosts: map[int]int{9: 1, 10: 1, 11: 1, 12: 2, 13: 2, 14: 2, 15: 5, 16: 5, 17: 10, 18: 10},
			},
			"normal": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Naturkunde", "Pflanzenkunde", "Tierkunde"},
				TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 20, 17: 50, 18: 50},
			},
			"schwer": DifficultyData{
				LearnCost:  4,
				Skills:     []string{"Schleichen", "Spurensuche", "Tarnen"},
				TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
			},
		},
		"Halbwelt": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Klettern", "Glücksspiel", "Balancieren"},
				TrainCosts: map[int]int{9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
			},
			"normal": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Akrobatik"},
				TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
			},
			"schwer": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Gassenwissen", "Stehlen"},
				TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 50, 17: 50, 18: 50},
			},
			"sehr schwer": DifficultyData{
				LearnCost:  10,
				Skills:     []string{"Betäuben"},
				TrainCosts: map[int]int{9: 5, 10: 10, 11: 20, 12: 20, 13: 30, 14: 50, 15: 80, 16: 80, 17: 100, 18: 100},
			},
		},
		"Kampf": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Reiten"},
				TrainCosts: map[int]int{6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
			},
			"normal": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Anführen", "Athletik"},
				TrainCosts: map[int]int{6: 0, 7: 0, 8: 0, 9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
			},
			"schwer": DifficultyData{
				LearnCost:  10,
				Skills:     []string{"Betäuben"},
				TrainCosts: map[int]int{6: 0, 7: 0, 8: 0, 9: 5, 10: 10, 11: 20, 12: 20, 13: 30, 14: 50, 15: 80, 16: 80, 17: 100, 18: 100},
			},
			"sehr schwer": DifficultyData{
				LearnCost:  10,
				Skills:     []string{},
				TrainCosts: map[int]int{6: 2, 7: 5, 8: 10, 9: 10, 10: 20, 11: 20, 12: 30, 13: 50, 14: 50, 15: 100, 16: 100, 17: 150, 18: 200},
			},
		},
		"Körper": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Geländelauf", "Klettern", "Schwimmen", "Balancieren"},
				TrainCosts: map[int]int{9: 0, 10: 0, 11: 0, 12: 0, 13: 1, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
			},
			"normal": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Tauchen"},
				TrainCosts: map[int]int{9: 1, 10: 1, 11: 2, 12: 2, 13: 5, 14: 10, 15: 10, 16: 20, 17: 20, 18: 50},
			},
			"schwer": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Akrobatik", "Athletik", "Laufen", "Meditieren"},
				TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
			},
		},
		"Sozial": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Anführen", "Verführen", "Verstellen", "Etikette"},
				TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
			},
			"normal": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Gassenwissen", "Beredsamkeit", "Verhören"},
				TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 50, 17: 50, 18: 50},
			},
			"schwer": DifficultyData{
				LearnCost:  4,
				Skills:     []string{"Menschenkenntnis"},
				TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
			},
		},
		"Unterwelt": {
			"leicht": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Gassenwissen", "Stehlen"},
				TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 50, 17: 50, 18: 50},
			},
			"normal": DifficultyData{
				LearnCost:  4,
				Skills:     []string{"Schleichen", "Spurensuche", "Tarnen", "Fallen entdecken", "Schlösser öffnen"},
				TrainCosts: map[int]int{9: 5, 10: 5, 11: 10, 12: 10, 13: 20, 14: 20, 15: 50, 16: 50, 17: 100, 18: 100},
			},
			"schwer": DifficultyData{
				LearnCost:  10,
				Skills:     []string{"Fallenmechanik", "Meucheln", "Menschenkenntnis"},
				TrainCosts: map[int]int{9: 5, 10: 10, 11: 20, 12: 20, 13: 30, 14: 50, 15: 80, 16: 80, 17: 100, 18: 100},
			},
		},
		"Waffen": {
			"leicht": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Stichwaffen"},
				TrainCosts: map[int]int{6: 1, 7: 1, 8: 1, 9: 2, 10: 2, 11: 5, 12: 10, 13: 20, 14: 50, 15: 100, 16: 100, 17: 150, 18: 150},
			},
			"normal": DifficultyData{
				LearnCost:  4,
				Skills:     []string{"Einhandschlagwaffen"},
				TrainCosts: map[int]int{6: 1, 7: 1, 8: 2, 9: 2, 10: 5, 11: 10, 12: 20, 13: 50, 14: 50, 15: 100, 16: 150, 17: 150, 18: 200},
			},
			"schwer": DifficultyData{
				LearnCost:  6,
				Skills:     []string{"Zweihandschlagwaffen"},
				TrainCosts: map[int]int{6: 1, 7: 2, 8: 2, 9: 5, 10: 5, 11: 10, 12: 20, 13: 50, 14: 100, 15: 150, 16: 200, 17: 300, 18: 300},
			},
			"sehr schwer": DifficultyData{
				LearnCost:  8,
				Skills:     []string{},
				TrainCosts: map[int]int{6: 1, 7: 2, 8: 2, 9: 5, 10: 10, 11: 20, 12: 50, 13: 100, 14: 150, 15: 200, 16: 300, 17: 300, 18: 400},
			},
		},
		"Wissen": {
			"leicht": DifficultyData{
				LearnCost:  1,
				Skills:     []string{"Lesen von Zauberschrift", "Schreiben", "Sprache"},
				TrainCosts: map[int]int{9: 1, 10: 1, 11: 1, 12: 1, 13: 2, 14: 2, 15: 5, 16: 10, 17: 10, 18: 20},
			},
			"normal": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Erste Hilfe", "Meditieren"},
				TrainCosts: map[int]int{9: 2, 10: 2, 11: 5, 12: 5, 13: 10, 14: 10, 15: 20, 16: 20, 17: 50, 18: 50},
			},
			"schwer": DifficultyData{
				LearnCost:  2,
				Skills:     []string{"Alchimie", "Heilkunde", "Landeskunde", "Zauberkunde", "Naturkunde", "Pflanzenkunde", "Tierkunde"},
				TrainCosts: map[int]int{9: 2, 10: 5, 11: 5, 12: 10, 13: 10, 14: 20, 15: 20, 16: 20, 17: 50, 18: 50},
			},
		},
		"Schilde und Parierwaﬀen": {
			"normal": DifficultyData{
				LearnCost:  0, // Not defined in BaseLearnCost, using 0 as default
				Skills:     []string{},
				TrainCosts: map[int]int{2: 1, 3: 2, 4: 10, 5: 30, 6: 50, 7: 100, 8: 150},
			},
		},
	},
}

// contains checks if a slice contains a specific string
func contains(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

//### End of Helper functions ###

// GetSpellInfoNewSystem returns the school and level of a spell from the database
func GetSpellInfoNewSystem(spellName string) (string, int, error) {
	// Create a Spell instance to search in the database
	var spell models.Spell

	// Search for the spell in the database
	err := spell.First(spellName)
	if err != nil {
		return "", 0, fmt.Errorf("spell '%s' not found in database: %w", spellName, err)
	}

	return spell.Category, spell.Stufe, nil
}
