package mapper

import (
	"encoding/json"
	"fmt"

	"github.com/KorAP/KoralPipe-TermMapper/ast"
	"github.com/KorAP/KoralPipe-TermMapper/config"
	"github.com/KorAP/KoralPipe-TermMapper/matcher"
	"github.com/KorAP/KoralPipe-TermMapper/parser"
)

// Direction represents the mapping direction (A to B or B to A)
type Direction bool

const (
	AtoB Direction = true
	BtoA Direction = false
)

// String converts the Direction to its string representation
func (d Direction) String() string {
	if d {
		return "atob"
	}
	return "btoa"
}

// ParseDirection converts a string direction to Direction type
func ParseDirection(dir string) (Direction, error) {
	switch dir {
	case "atob":
		return AtoB, nil
	case "btoa":
		return BtoA, nil
	default:
		return false, fmt.Errorf("invalid direction: %s", dir)
	}
}

// Mapper handles the application of mapping rules to JSON objects
type Mapper struct {
	mappingLists map[string]*config.MappingList
	parsedRules  map[string][]*parser.MappingResult
}

// NewMapper creates a new Mapper instance from a list of MappingLists
func NewMapper(lists []config.MappingList) (*Mapper, error) {
	m := &Mapper{
		mappingLists: make(map[string]*config.MappingList),
		parsedRules:  make(map[string][]*parser.MappingResult),
	}

	// Store mapping lists by ID
	for _, list := range lists {
		if _, exists := m.mappingLists[list.ID]; exists {
			return nil, fmt.Errorf("duplicate mapping list ID found: %s", list.ID)
		}

		// Create a copy of the list to store
		listCopy := list
		m.mappingLists[list.ID] = &listCopy

		// Parse the rules immediately
		parsedRules, err := list.ParseMappings()
		if err != nil {
			return nil, fmt.Errorf("failed to parse mappings for list %s: %w", list.ID, err)
		}
		m.parsedRules[list.ID] = parsedRules
	}

	return m, nil
}

// MappingOptions contains the options for applying mappings
type MappingOptions struct {
	FoundryA    string
	LayerA      string
	FoundryB    string
	LayerB      string
	Direction   Direction
	AddRewrites bool
}

// ApplyQueryMappings applies the specified mapping rules to a JSON object
func (m *Mapper) ApplyQueryMappings(mappingID string, opts MappingOptions, jsonData any) (any, error) {
	// Validate mapping ID
	if _, exists := m.mappingLists[mappingID]; !exists {
		return nil, fmt.Errorf("mapping list with ID %s not found", mappingID)
	}

	// Get the parsed rules
	rules := m.parsedRules[mappingID]

	// Check if we have a wrapper object with a "query" field
	var queryData any
	var hasQueryWrapper bool

	if jsonMap, ok := jsonData.(map[string]any); ok {
		if query, exists := jsonMap["query"]; exists {
			queryData = query
			hasQueryWrapper = true
		}
	}

	// If no query wrapper was found, use the entire input
	if !hasQueryWrapper {
		// If the input itself is not a valid query object, return it as is
		if !isValidQueryObject(jsonData) {
			return jsonData, nil
		}
		queryData = jsonData
	} else if queryData == nil || !isValidQueryObject(queryData) {
		// If we have a query wrapper but the query is nil or not a valid object,
		// return the original data
		return jsonData, nil
	}

	// Store rewrites if they exist
	var oldRewrites any
	if queryMap, ok := queryData.(map[string]any); ok {
		if rewrites, exists := queryMap["rewrites"]; exists {
			oldRewrites = rewrites
			delete(queryMap, "rewrites")
		}
	}

	// Convert input JSON to AST
	jsonBytes, err := json.Marshal(queryData)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal input JSON: %w", err)
	}

	node, err := parser.ParseJSON(jsonBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to parse JSON into AST: %w", err)
	}

	// Store whether the input was a Token
	isToken := false
	var tokenWrap ast.Node
	if token, ok := node.(*ast.Token); ok {
		isToken = true
		tokenWrap = token.Wrap
		node = tokenWrap
	}

	// Store original node for rewrite if needed
	var originalNode ast.Node
	if opts.AddRewrites {
		originalNode = node.Clone()
	}

	// Pre-check foundry/layer overrides to optimize processing
	var patternFoundry, patternLayer, replacementFoundry, replacementLayer string
	if opts.Direction { // true means AtoB
		patternFoundry, patternLayer = opts.FoundryA, opts.LayerA
		replacementFoundry, replacementLayer = opts.FoundryB, opts.LayerB
	} else {
		patternFoundry, patternLayer = opts.FoundryB, opts.LayerB
		replacementFoundry, replacementLayer = opts.FoundryA, opts.LayerA
	}

	// Create a pattern cache key for memoization
	type patternCacheKey struct {
		ruleIndex     int
		foundry       string
		layer         string
		isReplacement bool
	}
	patternCache := make(map[patternCacheKey]ast.Node)

	// Apply each rule to the AST
	for i, rule := range rules {
		// Create pattern and replacement based on direction
		var pattern, replacement ast.Node
		if opts.Direction { // true means AtoB
			pattern = rule.Upper
			replacement = rule.Lower
		} else {
			pattern = rule.Lower
			replacement = rule.Upper
		}

		// Extract the inner nodes from the pattern and replacement tokens
		if token, ok := pattern.(*ast.Token); ok {
			pattern = token.Wrap
		}
		if token, ok := replacement.(*ast.Token); ok {
			replacement = token.Wrap
		}

		// First, quickly check if the pattern could match without creating a full matcher
		// This is a lightweight pre-check to avoid expensive operations
		if !m.couldPatternMatch(node, pattern) {
			continue
		}

		// Get or create pattern with overrides
		patternKey := patternCacheKey{ruleIndex: i, foundry: patternFoundry, layer: patternLayer, isReplacement: false}
		processedPattern, exists := patternCache[patternKey]
		if !exists {
			// Clone pattern only when needed
			processedPattern = pattern.Clone()
			// Apply foundry and layer overrides only if they're non-empty
			if patternFoundry != "" || patternLayer != "" {
				ast.ApplyFoundryAndLayerOverrides(processedPattern, patternFoundry, patternLayer)
			}
			patternCache[patternKey] = processedPattern
		}

		// Create a temporary matcher to check for actual matches
		tempMatcher, err := matcher.NewMatcher(ast.Pattern{Root: processedPattern}, ast.Replacement{Root: &ast.Term{}})
		if err != nil {
			return nil, fmt.Errorf("failed to create temporary matcher: %w", err)
		}

		// Only proceed if there's an actual match
		if !tempMatcher.Match(node) {
			continue
		}

		// Get or create replacement with overrides (lazy evaluation)
		replacementKey := patternCacheKey{ruleIndex: i, foundry: replacementFoundry, layer: replacementLayer, isReplacement: true}
		processedReplacement, exists := patternCache[replacementKey]
		if !exists {
			// Clone replacement only when we have a match
			processedReplacement = replacement.Clone()
			// Apply foundry and layer overrides only if they're non-empty
			if replacementFoundry != "" || replacementLayer != "" {
				ast.ApplyFoundryAndLayerOverrides(processedReplacement, replacementFoundry, replacementLayer)
			}
			patternCache[replacementKey] = processedReplacement
		}

		// Create the actual matcher and apply replacement
		actualMatcher, err := matcher.NewMatcher(ast.Pattern{Root: processedPattern}, ast.Replacement{Root: processedReplacement})
		if err != nil {
			return nil, fmt.Errorf("failed to create matcher: %w", err)
		}
		node = actualMatcher.Replace(node)
	}

	// Wrap the result in a token if the input was a token
	var result ast.Node
	if isToken {
		result = &ast.Token{Wrap: node}
	} else {
		result = node
	}

	// Convert AST back to JSON
	resultBytes, err := parser.SerializeToJSON(result)
	if err != nil {
		return nil, fmt.Errorf("failed to serialize AST to JSON: %w", err)
	}

	// Parse the JSON string back into
	var resultData any
	if err := json.Unmarshal(resultBytes, &resultData); err != nil {
		return nil, fmt.Errorf("failed to parse result JSON: %w", err)
	}

	// Add rewrites if enabled and node was changed
	if opts.AddRewrites && !ast.NodesEqual(node, originalNode) {
		// Create rewrite object
		rewrite := map[string]any{
			"@type":  "koral:rewrite",
			"editor": "termMapper",
		}

		// Check if the node types are different (structural change)
		if originalNode.Type() != node.Type() {
			// Full node replacement
			originalBytes, err := parser.SerializeToJSON(originalNode)
			if err != nil {
				return nil, fmt.Errorf("failed to serialize original node for rewrite: %w", err)
			}
			var originalJSON any
			if err := json.Unmarshal(originalBytes, &originalJSON); err != nil {
				return nil, fmt.Errorf("failed to parse original node JSON for rewrite: %w", err)
			}
			rewrite["original"] = originalJSON
		} else if term, ok := originalNode.(*ast.Term); ok && ast.IsTermNode(node) {
			// Check which attributes changed
			newTerm := node.(*ast.Term)
			if term.Foundry != newTerm.Foundry {
				rewrite["scope"] = "foundry"
				rewrite["original"] = term.Foundry
			} else if term.Layer != newTerm.Layer {
				rewrite["scope"] = "layer"
				rewrite["original"] = term.Layer
			} else if term.Key != newTerm.Key {
				rewrite["scope"] = "key"
				rewrite["original"] = term.Key
			} else if term.Value != newTerm.Value {
				rewrite["scope"] = "value"
				rewrite["original"] = term.Value
			} else {
				// No specific attribute changed, use full node replacement
				originalBytes, err := parser.SerializeToJSON(originalNode)
				if err != nil {
					return nil, fmt.Errorf("failed to serialize original node for rewrite: %w", err)
				}
				var originalJSON any
				if err := json.Unmarshal(originalBytes, &originalJSON); err != nil {
					return nil, fmt.Errorf("failed to parse original node JSON for rewrite: %w", err)
				}
				rewrite["original"] = originalJSON
			}
		} else {
			// Full node replacement
			originalBytes, err := parser.SerializeToJSON(originalNode)
			if err != nil {
				return nil, fmt.Errorf("failed to serialize original node for rewrite: %w", err)
			}
			var originalJSON any
			if err := json.Unmarshal(originalBytes, &originalJSON); err != nil {
				return nil, fmt.Errorf("failed to parse original node JSON for rewrite: %w", err)
			}
			rewrite["original"] = originalJSON
		}

		// Add rewrite to the node
		if resultMap, ok := resultData.(map[string]any); ok {
			if wrapMap, ok := resultMap["wrap"].(map[string]any); ok {
				rewrites, exists := wrapMap["rewrites"]
				if !exists {
					rewrites = []any{}
				}
				if rewritesList, ok := rewrites.([]any); ok {
					wrapMap["rewrites"] = append(rewritesList, rewrite)
				} else {
					wrapMap["rewrites"] = []any{rewrite}
				}
			}
		}
	}

	// Restore rewrites if they existed
	if oldRewrites != nil {
		// Process old rewrites through AST to ensure backward compatibility
		if rewritesList, ok := oldRewrites.([]any); ok {
			processedRewrites := make([]any, len(rewritesList))
			for i, rewriteData := range rewritesList {
				// Marshal and unmarshal each rewrite to apply backward compatibility
				rewriteBytes, err := json.Marshal(rewriteData)
				if err != nil {
					return nil, fmt.Errorf("failed to marshal old rewrite %d: %w", i, err)
				}
				var rewrite ast.Rewrite
				if err := json.Unmarshal(rewriteBytes, &rewrite); err != nil {
					return nil, fmt.Errorf("failed to unmarshal old rewrite %d: %w", i, err)
				}
				// Marshal back to get the transformed version
				transformedBytes, err := json.Marshal(&rewrite)
				if err != nil {
					return nil, fmt.Errorf("failed to marshal transformed rewrite %d: %w", i, err)
				}
				var transformedRewrite any
				if err := json.Unmarshal(transformedBytes, &transformedRewrite); err != nil {
					return nil, fmt.Errorf("failed to unmarshal transformed rewrite %d: %w", i, err)
				}
				processedRewrites[i] = transformedRewrite
			}
			if resultMap, ok := resultData.(map[string]any); ok {
				resultMap["rewrites"] = processedRewrites
			}
		} else {
			// If it's not a list, restore as-is
			if resultMap, ok := resultData.(map[string]any); ok {
				resultMap["rewrites"] = oldRewrites
			}
		}
	}

	// If we had a query wrapper, put the transformed data back in it
	if hasQueryWrapper {
		if wrapper, ok := jsonData.(map[string]any); ok {
			wrapper["query"] = resultData
			return wrapper, nil
		}
	}

	return resultData, nil
}

// isValidQueryObject checks if the query data is a valid object that can be processed
func isValidQueryObject(data any) bool {
	// Check if it's a map
	queryMap, ok := data.(map[string]any)
	if !ok {
		return false
	}

	// Check if it has the required @type field
	if _, ok := queryMap["@type"]; !ok {
		return false
	}

	return true
}

// couldPatternMatch performs a lightweight check to see if a pattern could potentially match a node
// This is an optimization to avoid expensive operations when there's clearly no match possible
func (m *Mapper) couldPatternMatch(node, pattern ast.Node) bool {
	if pattern == nil {
		return true
	}
	if node == nil {
		return false
	}

	// Handle Token wrappers
	if token, ok := pattern.(*ast.Token); ok {
		pattern = token.Wrap
	}
	if token, ok := node.(*ast.Token); ok {
		node = token.Wrap
	}

	// For simple terms, check basic compatibility
	if patternTerm, ok := pattern.(*ast.Term); ok {
		// Check if there's any term in the node structure that could match
		return m.hasMatchingTerm(node, patternTerm)
	}

	// For TermGroups, we need to check all possible matches
	if patternGroup, ok := pattern.(*ast.TermGroup); ok {
		if patternGroup.Relation == ast.OrRelation {
			// For OR relations, any operand could match
			for _, op := range patternGroup.Operands {
				if m.couldPatternMatch(node, op) {
					return true
				}
			}
			return false
		} else {
			// For AND relations, all operands must have potential matches
			for _, op := range patternGroup.Operands {
				if !m.couldPatternMatch(node, op) {
					return false
				}
			}
			return true
		}
	}

	// For other cases, assume they could match (conservative approach)
	return true
}

// hasMatchingTerm checks if there's any term in the node structure that could match the pattern term
func (m *Mapper) hasMatchingTerm(node ast.Node, patternTerm *ast.Term) bool {
	if node == nil {
		return false
	}

	switch n := node.(type) {
	case *ast.Term:
		// Check if this term could match the pattern
		// We only check key as that's the most distinctive attribute
		return n.Key == patternTerm.Key
	case *ast.TermGroup:
		// Check all operands
		for _, op := range n.Operands {
			if m.hasMatchingTerm(op, patternTerm) {
				return true
			}
		}
		return false
	case *ast.Token:
		return m.hasMatchingTerm(n.Wrap, patternTerm)
	case *ast.CatchallNode:
		if n.Wrap != nil && m.hasMatchingTerm(n.Wrap, patternTerm) {
			return true
		}
		for _, op := range n.Operands {
			if m.hasMatchingTerm(op, patternTerm) {
				return true
			}
		}
		return false
	default:
		return false
	}
}
