package termmapper

/*
$(	=>	PUNCT	PunctType=Brck	``, '', *RRB*, *LRB*, -
$,	=>	PUNCT	PunctType=Comm	,
$.	=>	PUNCT	PunctType=Peri	., :, ?, ;, !
ADJA	=>	ADJ	_	neuen, neue, deutschen, ersten, anderen
ADJD	=>	ADJ	Variant=Short	gut, rund, knapp, deutlich, möglich
ADV	=>	ADV	_	auch, nur, noch, so, aber
APPO	=>	ADP	AdpType=Post	zufolge, nach, gegenüber, wegen, über
APPR	=>	ADP	AdpType=Prep	in, von, mit, für, auf
APPRART	=>	ADP	AdpType=Prep|PronType=Art	im, am, zum, zur, vom
APZR	=>	ADP	AdpType=Circ	an, hinaus, aus, her, heraus
ART	=>	DET	PronType=Art	der, die, den, des, das
CARD	=>	NUM	NumType=Card	000, zwei, drei, vier, fünf
FM	=>	X	Foreign=Yes	New, of, de, Times, the
ITJ	=>	INTJ	_	naja, Ach, äh, Na, piep
KOKOM	=>	CCONJ	ConjType=Comp	als, wie, denn, wir
KON	=>	CCONJ	_	und, oder, sondern, sowie, aber
KOUI	=>	SCONJ	_	um, ohne, statt, anstatt, Ums
KOUS	=>	SCONJ	_	daß, wenn, weil, ob, als
NE	=>	PROPN	_	SPD, Deutschland, USA, dpa, Bonn
NN	=>	NOUN	_	Prozent, Mark, Millionen, November, Jahren
PAV	=>	ADV	PronType=Dem
PDAT	=>	DET	PronType=Dem	dieser, diese, diesem, dieses, diesen
PDS	=>	PRON	PronType=Dem	das, dies, die, diese, der
PIAT	=>	DET	PronType=Ind,Neg,Tot	keine, mehr, alle, kein, beiden
PIDAT	=>	DET	AdjType=Pdt|PronType=Ind,Neg,Tot
PIS	=>	PRON	PronType=Ind,Neg,Tot	man, allem, nichts, alles, mehr
PPER	=>	PRON	PronType=Prs	es, sie, er, wir, ich
PPOSAT	=>	DET	Poss=Yes|PronType=Prs	ihre, seine, seiner, ihrer, ihren
PPOSS	=>	PRON	Poss=Yes|PronType=Prs	ihren, Seinen, seinem, unsrigen, meiner
PRELAT	=>	DET	PronType=Rel	deren, dessen, die
PRELS	=>	PRON	PronType=Rel	die, der, das, dem, denen
PRF	=>	PRON	PronType=Prs|Reflex=Yes	sich, uns, mich, mir, dich
PTKA	=>	PART	_	zu, am, allzu, Um
PTKANT	=>	PART	PartType=Res	nein, ja, bitte, Gewiß, Also
PTKNEG	=>	PART	Polarity=Neg	nicht
PTKVZ	=>	ADP	PartType=Vbp	an, aus, ab, vor, auf
PTKZU	=>	PART	PartType=Inf	zu, zur, zum
PWAT	=>	DET	PronType=Int	welche, welchen, welcher, wie, welchem
PWAV	=>	ADV	PronType=Int	wie, wo, warum, wobei, wonach
PWS	=>	PRON	PronType=Int	was, wer, wem, wen, welches
TRUNC	=>	X	Hyph=Yes	Staats-, Industrie-, Finanz-, Öl-, Lohn-
VAFIN	=>	AUX	Mood=Ind|VerbForm=Fin	ist, hat, wird, sind, sei
VAIMP	=>	AUX	Mood=Imp|VerbForm=Fin	Seid, werde, Sei
VAINF	=>	AUX	VerbForm=Inf	werden, sein, haben, worden, Dabeisein
VAPP	=>	AUX	Aspect=Perf|VerbForm=Part	worden, gewesen, geworden, gehabt, werden
VMFIN	=>	VERB	Mood=Ind|VerbForm=Fin|VerbType=Mod	kann, soll, will, muß, sollen
VMINF	=>	VERB	VerbForm=Inf|VerbType=Mod	können, müssen, wollen, dürfen, sollen
VMPP	=>	VERB	Aspect=Perf|VerbForm=Part|VerbType=Mod	gewollt
VVFIN	=>	VERB	Mood=Ind|VerbForm=Fin	sagte, gibt, geht, steht, kommt
VVIMP	=>	VERB	Mood=Imp|VerbForm=Fin	siehe, sprich, schauen, Sagen, gestehe
VVINF	=>	VERB	VerbForm=Inf	machen, lassen, bleiben, geben, bringen
VVIZU	=>	VERB	VerbForm=Inf	einzusetzen, durchzusetzen, aufzunehmen, abzubauen, umzusetzen
VVPP	=>	VERB	Aspect=Perf|VerbForm=Part	gemacht, getötet, gefordert, gegeben, gestellt
XY	=>	X	_	dpa, ap, afp, rtr, wb
*/

import (
	"strconv"
	"strings"

	"github.com/rs/zerolog/log"
	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

/*
import (
	"encoding/json"
	"fmt"
	"log"
	"strings"
)

var mapping = map[string]string{
	"$(":"PUNCT",
}

// Recursive function to turn the UPos query into a STTS query
func koralRewriteUpos2Stts(koralquery interface{}) interface{} {
	switch v := koralquery.(type) {
	case map[string]interface{}:
		// Check for '@type' key and act accordingly
		if typ, ok := v["@type"].(string); ok {
			switch typ {
			case "koral:term":

        // Modify the key to use STTS
// This may require to turn object into a koral:token with terms like:


				if key, ok := v["key"].(string); ok {
					v["key"] = "hallo-" + key
				}
			case "operation":
				// Handle the 'operators' key by recursively modifying each operator
				if operators, ok := v["operators"].([]interface{}); ok {
					for i, operator := range operators {
						operators[i] = modifyJSON(operator)
					}
					v["operators"] = operators
				}
			}
		}
		// Recursively modify any nested maps
		for k, val := range v {
			v[k] = modifyJSON(val)
		}
		return v
	case []interface{}:
		// Recursively modify elements of arrays
		for i, item := range v {
			v[i] = modifyJSON(item)
		}
		return v
	}
	return koralquery
}

func main() {
	// Sample JSON input string
	jsonStr := `{
		"@type": "operation",
		"operators": [
			{
				"@type": "term",
				"key": "example1"
			},
			{
				"@type": "term",
				"key": "example2"
			},
			{
				"@type": "operation",
				"operators": [
					{
						"@type": "term",
						"key": "nested"
					}
				]
			}
		]
	}`

	// Parse the JSON string into a generic interface{}
	var data interface{}
	err := json.Unmarshal([]byte(jsonStr), &data)
	if err != nil {
		log.Fatal("Error unmarshaling JSON:", err)
	}

	// Modify the JSON structure recursively
	modifiedData := modifyJSON(data)

	// Marshal the modified data back into a JSON string
	modifiedJSON, err := json.MarshalIndent(modifiedData, "", "  ")
	if err != nil {
		log.Fatal("Error marshaling JSON:", err)
	}

	// Output the modified JSON string
	fmt.Println(string(modifiedJSON))
}



func turnupostostts(json string, targetFoundry string, targetLayer string) {
	if targetLayer == "" {
		targetLayer = "p"
	}

  ldType := "@type"

  if ldType == "koral:span" {
    next
  }
  if ldType == "koral:term"  {
      if foundry == if layer === key -> rewrite
  }

	// Iterate through the query and whenever a term is requested without a foundry, and without a layser or layer p,
  // change the key following the mapping


}

func addupostooutput(json string, reffoundry string, foundry string) {
	// https://universaldependencies.org/tagset-conversion/de-stts-uposf.html
	// Iterate through all matches and add to all xml snippets a line of foundry

}

*/

type Term struct {
	Foundry string
	Layer   string
	Key     string
}

func Map2(json []byte) string {
	/*
		result := gjson.GetBytes(json, "query")
		var raw []byte
		if result.Index > 0 {
			raw = json[result.Index:result.Index+len(result.Raw)]
		} else {
			raw = []byte(result.Raw)
		}

		if result.IsObject() {
			koralType := gjson.GetBytes(raw, "@type").String()
			switch koralType {
				case "koral:term":

			}
		}
	*/

	koralObj := gjson.ParseBytes(json)

	switch koralObj.Get("@type").String() {
	case "koral:term":
		{
			if koralObj.Get("value").String() == "KOKOM" {
				// TODO: Turn this in a token, if it isn't already!
				newJson, _ := sjson.Set(string(json), "value", "CCONJ")
				return newJson
			}
		}

	case "koral:operation":
		{

		}

	}
	/*

		var raw []byte
		if result.Index > 0 {
			raw = json[result.Index:result.Index+len(result.Raw)]
		} else {
			raw = []byte(result.Raw)
		}
	*/
	return "jj"
}

// token writes a token to the string builder
func token(strBuilder *strings.Builder, terms []Term, positive bool) {
	strBuilder.WriteString(`{"@type":"koral:token","wrap":`)
	if len(terms) > 1 {
		termGroup(strBuilder, terms, positive)
	} else {
		term(strBuilder, terms[0], positive)
	}
	strBuilder.WriteString(`}`)
}

// termGroup writes a termGroup to the string builder
func termGroup(strBuilder *strings.Builder, terms []Term, positive bool) {
	strBuilder.WriteString(`{"@type":"koral:termGroup",`)

	if positive {
		strBuilder.WriteString(`"relation":"relation:and","operation":"operation:and",`)
	} else {
		strBuilder.WriteString(`"relation":"relation:or","operation":"operation:or",`)
	}

	strBuilder.WriteString(`"operands":[`)
	for i, t := range terms {
		term(strBuilder, t, positive)
		if i < len(terms)-1 {
			strBuilder.WriteString(",")
		}
	}
	strBuilder.WriteString(`]}`)
}

// term writes a term to the string builder
func term(strBuilder *strings.Builder, term Term, match bool) {

	strBuilder.WriteString(`{"@type":"koral:term","match":"match:`)
	if match {
		strBuilder.WriteString("eq")
	} else {
		strBuilder.WriteString("ne")
	}
	strBuilder.WriteString(`","foundry":"`)
	strBuilder.WriteString(term.Foundry)
	strBuilder.WriteString(`","layer":"`)
	strBuilder.WriteString(term.Layer)
	strBuilder.WriteString(`","key":"`)
	strBuilder.WriteString(term.Key)
	strBuilder.WriteString(`"}`)
}

func flatten() {

	// if a termGroup isan operand in a termGroup with the same relation/operation:
	// flatten the termGroup into the parent termGroup

	// if a termGroup has only a single term, remove the group
}

func replaceWrappedTerms(jsonString string, terms []Term) string {
	var err error

	if len(terms) == 1 {
		jsonString, err = sjson.Set(jsonString, "foundry", terms[0].Foundry)
		if err != nil {
			log.Error().Err(err).Msg("Error setting foundry")
		}
		jsonString, err = sjson.Set(jsonString, "layer", terms[0].Layer)
		if err != nil {
			log.Error().Err(err).Msg("Error setting layer")
		}
		jsonString, err = sjson.Set(jsonString, "key", terms[0].Key)
		if err != nil {
			log.Error().Err(err).Msg("Error setting key")
		}

		return jsonString
	}

	matchop := gjson.Get(jsonString, "match").String()

	/*
		foundry := gjson.Get(jsonString, "foundry").String()
		layer := gjson.Get(jsonString, "layer").String()
		key := gjson.Get(jsonString, "key").String()
		term := Term{foundry, layer, key}


		terms = append(terms, term)
	*/

	var strBuilder strings.Builder
	if matchop == "match:ne" {
		termGroup(&strBuilder, terms, false)
	} else {
		termGroup(&strBuilder, terms, true)
	}

	return strBuilder.String()

}

func replaceGroupedTerm(jsonString string, op []int, foundry string, layer string, key string) string {
	var err error

	strInt := "operands." + strconv.Itoa(op[0]) + "."
	jsonString, err = sjson.Set(jsonString, strInt+"foundry", foundry)
	if err != nil {
		log.Error().Err(err).Msg("Error setting foundry")
	}
	jsonString, err = sjson.Set(jsonString, strInt+"layer", layer)
	if err != nil {
		log.Error().Err(err).Msg("Error setting layer")
	}
	jsonString, err = sjson.Set(jsonString, strInt+"key", key)
	if err != nil {
		log.Error().Err(err).Msg("Error setting key")
	}

	if len(op) > 1 {
		for i := 1; i < len(op); i++ {
			jsonString, err = sjson.Delete(jsonString, "operands."+strconv.Itoa(op[i]))
			if err != nil {
				log.Error().Err(err).Msg("Error deleting operand")
			}
		}
	}

	return jsonString
}

/*
func replaceTermWithToken(jsonString string) string {
	// Replace the term with the token
	replacedString, err := sjson.Set(jsonString, "wrap.operands.0", token())
	if err != nil {
		return jsonString // Return the original string in case of an error
	}
	return replacedString

// case1: 1 -> 1 the term is an operand in a termGroup with the same relation/operation
// case2: 1 -> 1 the term is wrapped
// case3: 1 -> 1 the term is an operand in a termGroup with a different relation/operation
// case4: n -> 1 the term is an operand in a termGroup with the same relation/operation
// case5: n -> 1 the term is wrapped
// case6: n -> 1 the term is an operand in a termGroup with a different relation/operation
// case7: 1 -> n the term is an operand in a termGroup with the same relation/operation
// case8: 1 -> n the term is wrapped
// case9: 1 -> n the term is an operand in a termGroup with a different relation/operation
	}
*/

func Map(jsonStr string) string {

	obj := gjson.Get(jsonStr, "query")

	// value := gjson.Get(json, "name.last")

	/*

	   	// Modify the JSON structure recursively
	   	modifiedData := modifyJSON(ast.NewAny(data))

	   // Marshal the modified data back into a JSON string
	   	modifiedJSON, err := sonic.MarshalString(modifiedData)

	   	// Parse the JSON string into a generic interface{}
	   	var data interface{}

	   	err := sonic.UnmarshalString(jsonStr, data)

	   	if err != nil {
	   		log.Fatal("Error unmarshaling JSON:", err)
	   		return ""
	   	}



	   	if err != nil {
	   		log.Fatal("Error marshaling JSON:", err)
	   	}
	*/
	// Output the modified JSON string
	return obj.String() //modifyJSON(obj)
}

// Recursive function to modify JSON using Sonic library
//func modifyJSON(data gjson.Result) string {

// Check if data is a map
// if data.IsObject() {
/*
	dataMap := data.Map()

	koralType := dataMap["@type"].String()

	// Look for @type key

	switch koralType {
	case "koral:term":
		// Modify the key by adding 'hallo-' prefix

		// sjson.SetRaw(data.String())
		sjson.Set(data.Path(data.Bytes()), "key", "hallo-"+dataMap["key"].String())

		dataMap["key"] = "hallo-" + dataMap["key"].String()
		/*
			if key, found := data.GetString("key"); found {
				data.Set("key", "hallo-"+key)
			}
*/
/*
	case "koral:operation":
			// Handle the 'operators' key by recursively modifying each operator
			if operators, found := data.GetArray("operators"); found {
				for i := range operators {
					operators[i] = modifyJSON(operators[i])
				}
				data.Set("operators", operators)
			}
		}*/
/*
	// Recursively modify any nested objects
	data.ForEach(func(k string, v sonic.Any) {
		data.Set(k, modifyJSON(v))
	})
*/
//}
// Handle arrays by modifying elements recursively
/*
	if data.IsArray() {
		for i := range data.GetArray() {
			data.Set(i, modifyJSON(data.GetArray()[i]))
		}
	}
*/
/*
	return data
}
*/
