package logging

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"time"
)

// Logger provides structured logging
type Logger struct {
	level  string
	fields map[string]interface{}
}

// NewLogger creates a new logger
func NewLogger(level string) *Logger {
	return &Logger{
		level:  level,
		fields: make(map[string]interface{}),
	}
}

// WithField adds a field to the logger
func (l *Logger) WithField(key string, value interface{}) *Logger {
	newLogger := &Logger{
		level:  l.level,
		fields: make(map[string]interface{}),
	}
	for k, v := range l.fields {
		newLogger.fields[k] = v
	}
	newLogger.fields[key] = value
	return newLogger
}

// Info logs an info message
func (l *Logger) Info(ctx context.Context, message string) {
	l.log(ctx, "info", message, nil)
}

// Error logs an error message
func (l *Logger) Error(ctx context.Context, message string, err error) {
	l.log(ctx, "error", message, map[string]interface{}{
		"error": err.Error(),
	})
}

// Warn logs a warning message
func (l *Logger) Warn(ctx context.Context, message string) {
	l.log(ctx, "warn", message, nil)
}

// Debug logs a debug message
func (l *Logger) Debug(ctx context.Context, message string) {
	l.log(ctx, "debug", message, nil)
}

// log logs a message with structured fields
func (l *Logger) log(ctx context.Context, level, message string, extraFields map[string]interface{}) {
	entry := map[string]interface{}{
		"timestamp": time.Now().UTC().Format(time.RFC3339),
		"level":     level,
		"message":   message,
	}

	// Add logger fields
	for k, v := range l.fields {
		entry[k] = v
	}

	// Add extra fields
	if extraFields != nil {
		for k, v := range extraFields {
			entry[k] = v
		}
	}

	// Sanitize PII
	entry = sanitizePII(entry)

	// Output as JSON
	jsonBytes, err := json.Marshal(entry)
	if err != nil {
		log.Printf("Failed to marshal log entry: %v", err)
		return
	}

	fmt.Fprintln(os.Stdout, string(jsonBytes))
}

// sanitizePII removes or masks PII from log entries
func sanitizePII(entry map[string]interface{}) map[string]interface{} {
	sanitized := make(map[string]interface{})
	for k, v := range entry {
		// Mask sensitive fields
		if k == "password" || k == "api_key" || k == "token" {
			sanitized[k] = "***REDACTED***"
		} else {
			sanitized[k] = v
		}
	}
	return sanitized
}

