package otel

import (
	"context"
	"time"

	"github.com/gogf/gf/v2/os/glog"
	otellog "go.opentelemetry.io/otel/log"
)

// LogHandler 自定义日志处理器，将GoFrame日志发送到OpenTelemetry
func LogHandler(ctx context.Context, in *glog.HandlerInput) {
	if globalManager != nil && globalManager.IsLoggingEnabled() {
		logger := globalManager.CreateLogger("")

		// 创建日志记录
		record := otellog.Record{}
		record.SetTimestamp(in.Time)
		record.SetObservedTimestamp(time.Now())
		record.SetSeverityText(in.LevelFormat)
		record.SetBody(otellog.StringValue(in.String()))

		// 添加基本属性
		attributes := []otellog.KeyValue{
			otellog.String("service.name", globalManager.GetConfig().ServiceName),
			otellog.String("level", in.LevelFormat),
			otellog.String("trace_id", in.TraceId),
		}

		// 添加调用者信息
		if in.CallerFunc != "" {
			attributes = append(attributes, otellog.String("caller.function", in.CallerFunc))
		}
		if in.CallerPath != "" {
			attributes = append(attributes, otellog.String("caller.file", in.CallerPath))
		}

		// 添加前缀信息
		if in.Prefix != "" {
			attributes = append(attributes, otellog.String("prefix", in.Prefix))
		}

		// 添加堆栈信息（如果有错误）
		if in.LevelFormat == "ERRO" || in.LevelFormat == "CRIT" {
			if in.Stack != "" {
				attributes = append(attributes, otellog.String("stack", in.Stack))
			}
		}

		// 添加上下文信息
		if in.CtxStr != "" {
			attributes = append(attributes, otellog.String("ctx", in.CtxStr))
		}

		record.AddAttributes(attributes...)

		// 发送日志
		logger.Emit(ctx, record)
	}

	// 继续执行下一个处理器
	in.Next(ctx)
}

// EnhancedLogHandler 增强版日志处理器，支持更多配置选项
type EnhancedLogHandler struct {
	manager        *Manager
	includeStack   bool
	includeContext bool
	customAttrs    func(*glog.HandlerInput) []otellog.KeyValue
}

// NewEnhancedLogHandler 创建增强版日志处理器
func NewEnhancedLogHandler(manager *Manager) *EnhancedLogHandler {
	return &EnhancedLogHandler{
		manager:        manager,
		includeStack:   true,
		includeContext: true,
		customAttrs:    nil,
	}
}

// WithIncludeStack 设置是否包含堆栈信息
func (h *EnhancedLogHandler) WithIncludeStack(include bool) *EnhancedLogHandler {
	h.includeStack = include
	return h
}

// WithIncludeContext 设置是否包含上下文信息
func (h *EnhancedLogHandler) WithIncludeContext(include bool) *EnhancedLogHandler {
	h.includeContext = include
	return h
}

// WithCustomAttributes 设置自定义属性函数
func (h *EnhancedLogHandler) WithCustomAttributes(fn func(*glog.HandlerInput) []otellog.KeyValue) *EnhancedLogHandler {
	h.customAttrs = fn
	return h
}

// Handle 处理日志
func (h *EnhancedLogHandler) Handle(ctx context.Context, in *glog.HandlerInput) {
	if !h.manager.IsLoggingEnabled() {
		in.Next(ctx)
		return
	}

	logger := h.manager.CreateLogger("")

	// 创建日志记录
	record := otellog.Record{}
	record.SetTimestamp(in.Time)
	record.SetObservedTimestamp(time.Now())
	record.SetSeverityText(in.LevelFormat)
	record.SetBody(otellog.StringValue(in.String()))

	// 基本属性
	attributes := []otellog.KeyValue{
		otellog.String("service.name", h.manager.GetConfig().ServiceName),
		otellog.String("level", in.LevelFormat),
		otellog.String("trace_id", in.TraceId),
	}

	// 调用者信息
	if in.CallerFunc != "" {
		attributes = append(attributes, otellog.String("caller.function", in.CallerFunc))
	}
	if in.CallerPath != "" {
		attributes = append(attributes, otellog.String("caller.file", in.CallerPath))
	}

	// 前缀信息
	if in.Prefix != "" {
		attributes = append(attributes, otellog.String("prefix", in.Prefix))
	}

	// 堆栈信息
	if h.includeStack && (in.LevelFormat == "ERRO" || in.LevelFormat == "CRIT") && in.Stack != "" {
		attributes = append(attributes, otellog.String("stack", in.Stack))
	}

	// 上下文信息
	if h.includeContext && in.CtxStr != "" {
		attributes = append(attributes, otellog.String("ctx", in.CtxStr))
	}

	// 自定义属性
	if h.customAttrs != nil {
		attributes = append(attributes, h.customAttrs(in)...)
	}

	// 异步信息
	if in.IsAsync {
		attributes = append(attributes, otellog.Bool("async", true))
	}

	record.AddAttributes(attributes...)

	// 发送日志
	logger.Emit(ctx, record)

	// 继续执行下一个处理器
	in.Next(ctx)
}
