package observability

import (
	"context"
	"log"
	"net/url"
	"time"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)

// InitTracer 初始化 OpenTelemetry tracer.
//
// endpoint 为 "http://host:port" 格式（如 "http://localhost:4318"）；
// 为空时跳过初始化（tracing disabled）。
//
// 返回 shutdown 函数，应在服务退出时调用以 flush 待发送 span.
func InitTracer(serviceName, endpoint string) func() {
	if endpoint == "" {
		log.Println("OTEL endpoint not set, tracing disabled")
		return func() {}
	}

	u, err := url.Parse(endpoint)
	if err != nil || u.Host == "" {
		log.Printf("invalid OTEL endpoint %q, tracing disabled", endpoint)
		return func() {}
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	exporter, err := otlptracehttp.New(ctx,
		otlptracehttp.WithEndpoint(u.Host),
		otlptracehttp.WithInsecure(),
	)
	if err != nil {
		log.Printf("failed to create OTLP exporter: %v, tracing disabled", err)
		return func() {}
	}

	res, err := resource.New(ctx,
		resource.WithAttributes(semconv.ServiceName(serviceName)),
	)
	if err != nil {
		log.Printf("failed to create resource: %v", err)
		return func() {}
	}

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(res),
	)
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
		propagation.TraceContext{},
		propagation.Baggage{},
	))

	log.Printf("OpenTelemetry tracer initialized for %s (endpoint=%s)", serviceName, u.Host)
	return func() {
		shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		if err := tp.Shutdown(shutdownCtx); err != nil {
			log.Printf("failed to shutdown tracer: %v", err)
		}
	}
}
