package api

import (
	"errors"
	"git.lumeweb.com/LumeWeb/gitea-github-proxy/config"
	"go.uber.org/zap"
	"net/http"
)

type setupApi struct {
	config *config.Config
	logger *zap.Logger
	oauth  *oauth
}

func newSetupApi(config *config.Config, logger *zap.Logger, oauth *oauth) *setupApi {
	return &setupApi{config: config, logger: logger, oauth: oauth}
}

func (s setupApi) setupHandler(w http.ResponseWriter, r *http.Request) {
	status := getAuthedStatusFromRequest(r)

	if status {
		redirectCookie := getCookie(r, REDIRECT_AFTER_AUTH)
		if redirectCookie != "" {
			deleteCookie(w, REDIRECT_AFTER_AUTH)
			http.Redirect(w, r, redirectCookie, http.StatusFound)
			return
		}

		w.Header().Set("Content-Type", "text/plain")
		w.WriteHeader(http.StatusOK)
		w.Write([]byte("Setup is complete, you are authorized to use the proxy."))
		return
	}

	http.Redirect(w, r, s.oauth.authUrl(), http.StatusFound)
}
func (s setupApi) callbackHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Query().Get("error") != "" {
		http.Error(w, errors.Join(errors.New("Error authorizing with Gitea: "), errors.New(r.URL.Query().Get("error"))).Error(), http.StatusBadRequest)
	}

	code := r.URL.Query().Get("code")
	if len(code) == 0 {
		http.Error(w, "No code provided", http.StatusBadRequest)
		return
	}

	token, err := s.oauth.config().Exchange(r.Context(), code)
	if err != nil {
		http.Error(w, "Failed to exchange code for token", http.StatusInternalServerError)
		return
	}

	setAuthCookie(token.AccessToken, s.config.Domain, w)

	http.Redirect(w, r, "/setup", http.StatusFound)
}

func setupApiRoutes(params RouteParams) {
	r := params.R

	setupRouter := r.PathPrefix("/setup").Subrouter()
	setupRouter.Use(giteaOauthVerifyMiddleware(params.Config))

	setupApi := newSetupApi(params.Config, params.Logger, newOauth(params.Config, params.Logger))
	setupRouter.HandleFunc("", setupApi.setupHandler).Methods("GET")
	setupRouter.HandleFunc("/callback", setupApi.callbackHandler).Methods("GET")
}