package api

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/tidbcloud/account/internel/svc/orgsso"

	"github.com/tidbcloud/account/central/utils"

	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

const actionRedirectUrlFormat = "https://%s/continue?session_token=%s&state=%s"

func ActionCallbackHandler(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	token := query.Get("session_token")
	state := query.Get("state")

	tilog.Info(r.Context(), "ActionCallbackHandler receive action callback request", zap.Any("token", token), zap.Any("state", state))

	svc, _ := orgsso.GetActionCallbackSvc()
	token, err := svc.HandleActionCallback(r.Context(), state, token)
	if err != nil {
		tilog.Warn(r.Context(), "ActionCallbackHandler HandleActionCallback error", zap.Any("err", err))
	}

	redirectUrl := fmt.Sprintf(actionRedirectUrlFormat, config.Global().SSOConfig.Auth0Domain, token, state)

	tilog.Info(r.Context(), "ActionCallbackHandler complete", zap.Any("redirectUrl", redirectUrl))

	http.Redirect(w, r, redirectUrl, http.StatusFound)
}

func ActionVerifyHandler(w http.ResponseWriter, r *http.Request) {
	bm := utils.Begin(r.Context(), "ActionVerifyHandler")
	defer bm.OnExit(r.Context())

	query := r.URL.Query()
	token := query.Get("session_token")

	tilog.Info(r.Context(), "ActionVerifyHandler receive action verify request", zap.Any("token", token))

	svc, _ := orgsso.GetActionCallbackSvc()
	actionOrgInfo, err := svc.HandleActionVerify(r.Context(), token)
	if err != nil {
		tilog.Warn(r.Context(), "ActionVerifyHandler HandleActionVerify error", zap.Any("err", err))

		errRet := ActionErrRet{
			ErrMessage: err.Error(),
		}
		marshal, _ := json.Marshal(errRet)

		w.WriteHeader(http.StatusUnauthorized)
		_, err := w.Write(marshal)
		if err != nil {
			tilog.Warn(r.Context(), "ActionVerifyHandler write body err", zap.Any("err", err))
		}
		return
	}

	marshal, _ := json.Marshal(actionOrgInfo)
	w.WriteHeader(http.StatusOK)
	_, err = w.Write(marshal)
	if err != nil {
		tilog.Warn(r.Context(), "ActionVerifyHandler write body err", zap.Any("err", err))
	}
}

type ActionErrRet struct {
	ErrMessage string `json:"err_message"`
}
