package main

import (
	"net/http"
	"net/url"

	"github.com/gookit/goutil/dump"
	"zeevdiukman.com/zprox/internal/config"
	"zeevdiukman.com/zprox/pkg/helper"
)

func CallbackHandler(w http.ResponseWriter, r *http.Request) {
	configData := config.Get()

	// ctx := context.Background()
	query := r.URL.Query()

	code := query.Get("code")
	state := query.Get("state")

	verifier := appData.SessionManager.GetString(r.Context(), "code_verifier")
	if verifier == "" {
		http.Error(w, "Code verifier not found in session", http.StatusBadRequest)
		return
	}
	expectedState := appData.SessionManager.GetString(r.Context(), "state")
	if state != expectedState {
		http.Error(w, "Invalid state parameter", http.StatusBadRequest)
		return
	}
	originalURL, err := decodeState(state)
	if err != nil {
		dump.P(err.Error())
		http.Error(w, "Invalid state", http.StatusBadRequest)
		return
	}
	dump.P("Original_Path: " + originalURL)
	// originalPath := appData.SessionManager.GetString(r.Context(), "original_path")

	authName := configData.GetAuthNameByDomain(r.Host)
	token, fullResponse, e := exchangeCode(code, verifier, authName)
	if e != nil {
		dump.Println("exchangeCode: " + e.Error())
	}

	appData.SessionManager.Put(r.Context(), "access_token", token.AccessToken)
	appData.SessionManager.Put(r.Context(), "full_token", fullResponse)

	// SetAuthHeader(w, token.AccessToken)
	// http.Redirect(w, r, originalPath, http.StatusFound)
	http.Redirect(w, r, originalURL, http.StatusFound)
}
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
	configData := config.Get()

	//TODO: only after returninig, delete the session!
	appData.SessionManager.Remove(r.Context(), "access_token")
	appData.SessionManager.Remove(r.Context(), "full_token")

	authName := configData.DataMaps.DomainToAuth[r.Host]
	a := configData.AuthMap[authName]
	u := a.OpenID.EndPoints.Logout
	http.Redirect(w, r, u, http.StatusFound)

}

func LoginHandler(w http.ResponseWriter, r *http.Request) {
	configData := config.Get()

	authName := configData.DataMaps.DomainToAuth[r.Host]

	// state := helper.RandStringByBits(64)
	nonce := helper.RandStringByBits(64)
	authURL, _ := url.Parse(configData.AuthMap[authName].OpenID.EndPoints.Auth)
	query := authURL.Query()

	codeVerifier, _ := generateCodeVerifier()
	codeChallenge := generateCodeChallenge(codeVerifier)

	originalPath := appData.SessionManager.GetString(r.Context(), "original_path")
	state := generateState(url.QueryEscape(originalPath))
	query.Set("client_id", configData.AuthMap[authName].OpenID.ClientID)
	query.Set("response_type", "code")
	query.Set("scope", "openid")
	query.Set("redirect_uri", configData.AuthMap[authName].OpenID.RedirectURI)
	query.Set("code_challenge", codeChallenge)
	query.Set("code_challenge_method", "S256")
	query.Set("state", state)
	query.Set("nonce", nonce)
	authURL.RawQuery = query.Encode()
	appData.SessionManager.Put(r.Context(), "state", state)
	appData.SessionManager.Put(r.Context(), "code_verifier", codeVerifier)
	http.Redirect(w, r, authURL.String(), http.StatusFound)
}
