package utils

import (
	"encoding/json"
	"strings"
)

var sensitiveKeys = map[string]struct{}{
	"password":          {},
	"currentpassword":   {},
	"newpassword":       {},
	"oldpassword":       {},
	"token":             {},
	"accesstoken":       {},
	"access_token":      {},
	"refreshtoken":      {},
	"refresh_token":     {},
	"secret":            {},
	"clientsecret":      {},
	"client_secret":     {},
	"authorization":     {},
	"cookie":            {},
	"set-cookie":        {},
	"verificationcode":  {},
	"verification_code": {},
	"code":              {}, // Auth code (sensitive)
}

// MaskSensitiveJSON parses a JSON byte slice and masks values of sensitive keys.
// Returns the original data if it's not valid JSON.
func MaskSensitiveJSON(data []byte) []byte {
	if len(data) == 0 {
		return data
	}

	var obj interface{}
	if err := json.Unmarshal(data, &obj); err != nil {
		// Not a JSON object/array, return as is
		return data
	}

	masked := maskValue(obj)

	result, err := json.Marshal(masked)
	if err != nil {
		return data
	}
	return result
}

func maskValue(v interface{}) interface{} {
	switch val := v.(type) {
	case map[string]interface{}:
		newMap := make(map[string]interface{}, len(val))
		for k, v := range val {
			if isSensitive(k) {
				newMap[k] = "*****"
			} else {
				newMap[k] = maskValue(v)
			}
		}
		return newMap
	case []interface{}:
		newArr := make([]interface{}, len(val))
		for i, v := range val {
			newArr[i] = maskValue(v)
		}
		return newArr
	default:
		return val
	}
}

func isSensitive(key string) bool {
	// Check case-insensitive
	// Remove common separators for looser matching? No, stick to lowercase check for now.
	k := strings.ToLower(key)
	_, ok := sensitiveKeys[k]
	return ok
}
