package transports

import (
	"context"
	"encoding/json"
	"github.com/go-kit/kit/tracing/zipkin"
	kithttp "github.com/go-kit/kit/transport/http"
	"github.com/gorilla/mux"
	gozipkin "github.com/openzipkin/zipkin-go"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/tal-tech/go-zero/core/logx"
	"job_risk_third/internal/endpoints"
	"job_risk_third/internal/proto"
	"job_risk_third/pkg/utils"
	"net/http"
)

// MakeHttpHandler make http handler use mux
func MakeHttpHandler(_ context.Context, endpoint endpoints.JobRiskThirdEndpoint, zipkinTracer *gozipkin.Tracer) http.Handler {
	r := mux.NewRouter()
	zipkinServer := zipkin.HTTPServerTrace(zipkinTracer, zipkin.Name("http-transport"))

	options := []kithttp.ServerOption{
		kithttp.ServerErrorEncoder(MyErrorEncoder),
		zipkinServer,
	}
	r.Methods("POST").Path("/api/v1/push/feature_deal").Handler(kithttp.NewServer(
		endpoint.PushFeatureDealEndpoint,
		decodePushFeatureDealRequest,
		encodeResponse,
		options...,
	))
	r.Methods("POST").Path("/api/v1/push/user_info").Handler(kithttp.NewServer(
		endpoint.PushUserInfoEndpoint,
		decodePushUserInfoRequest,
		encodeResponse,
		options...,
	))
	r.Methods("POST").Path("/api/v1/push/feature_info").Handler(kithttp.NewServer(
		endpoint.PushFeatureInfoEndpoint,
		decodePushFeatureInfoRequest,
		encodeResponse,
		options...,
	))

	// create health check handler
	r.Methods("GET").Path("/health").Handler(kithttp.NewServer(
		endpoint.HealthCheckEndpoint,
		decodeHealthCheckRequest,
		encodeResponse,
		options...,
	))
	r.Path("/metrics").Handler(promhttp.Handler())
	return r
}

// decodeHealthCheckRequest decode request
func decodeHealthCheckRequest(_ context.Context, _ *http.Request) (interface{}, error) {
	return proto.HealthRequest{}, nil
}

func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json;charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func decodePushFeatureDealRequest(_ context.Context, r *http.Request) (interface{}, error) {
	if err := utils.Validation(r); err != nil {
		return nil, err
	}
	body := utils.Param(r, "__json_param__")
	var item proto.PushFeatureDealRequest
	err := json.Unmarshal([]byte(body), &item)
	if err != nil {
		logx.Error(err)
		return nil, utils.ErrorBadRequest
	}
	return item, nil
}
func decodePushUserInfoRequest(_ context.Context, r *http.Request) (interface{}, error) {
	if err := utils.Validation(r); err != nil {
		return nil, err
	}
	body := utils.Param(r, "__json_param__")
	var item proto.PushUserInfoRequest
	err := json.Unmarshal([]byte(body), &item)
	if err != nil {
		logx.Error(err)
		return nil, utils.ErrorBadRequest
	}
	return item, nil
}

func decodePushFeatureInfoRequest(_ context.Context, r *http.Request) (interface{}, error) {
	if err := utils.Validation(r); err != nil {
		return nil, err
	}
	body := utils.Param(r, "__json_param__")
	var item proto.PushFeatureInfoRequest
	err := json.Unmarshal([]byte(body), &item)
	if err != nil {
		logx.Error(err)
		return nil, utils.ErrorBadRequest
	}
	return item, nil
}