package usecase

import (
	errs "backend/pkg/library/errors"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"time"

	"backend/pkg/member/domain/usecase"
)

func (use *MemberUseCase) VerifyGoogleAuthResult(ctx context.Context, req usecase.VerifyAuthResultRequest) (usecase.GoogleTokenInfo, error) {
	var tokenInfo usecase.GoogleTokenInfo
	// 發送 Google Token Info API 請求
	body, err := use.fetchGoogleTokenInfo(ctx, req.Token)
	if err != nil {
		return tokenInfo, err
	}

	// 解析返回的 JSON 數據
	if err := json.Unmarshal(body, &tokenInfo); err != nil {
		return tokenInfo, errs.SysInternalError("failed to parse token info")
	}

	// 驗證 Token 資訊
	if err := validateGoogleTokenInfo(tokenInfo, use.Config.GoogleAuth.ClientID); err != nil {
		return tokenInfo, err
	}

	return tokenInfo, nil
}

// fetchGoogleTokenInfo 發送 Google TokenInfo API 請求並返回響應內容
func (use *MemberUseCase) fetchGoogleTokenInfo(ctx context.Context, token string) ([]byte, error) {
	uri := fmt.Sprintf("https://oauth2.googleapis.com/tokeninfo?id_token=%s", token)

	// 發送請求
	r, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
	if err != nil {
		return nil, errs.SvcThirdPartyErrorL(
			use.Logger,
			[]errs.LogField{
				{Key: "request URL", Val: uri},
				{Key: "func", Val: "fetchGoogleTokenInfo"},
			}, "failed to create request", err.Error())
	}

	resp, err := http.DefaultClient.Do(r)
	if err != nil {
		if errors.Is(ctx.Err(), context.DeadlineExceeded) {
			return nil, errs.SysTimeoutError("fetch google timeout")
		}

		return nil, errs.SvcThirdPartyErrorL(
			use.Logger,
			[]errs.LogField{
				{Key: "request URL", Val: uri},
				{Key: "method", Val: http.MethodGet},
				{Key: "func", Val: "fetchGoogleTokenInfo"},
			},
			"failed to request Google TokenInfo API",
		)
	}
	defer resp.Body.Close()

	// 檢查返回的 HTTP 狀態碼
	if resp.StatusCode != http.StatusOK {
		return nil, errs.SvcThirdPartyError(fmt.Sprintf("unexpected status code: %d", resp.StatusCode))
	}

	// 讀取響應內容
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, errs.SvcThirdPartyError("failed to read response body")
	}

	return body, nil
}

// validateGoogleTokenInfo 驗證 Google Token 資訊
func validateGoogleTokenInfo(tokenInfo usecase.GoogleTokenInfo, expectedClientID string) error {
	// **驗證 1: Token 是否過期**
	expiration, err := strconv.ParseInt(tokenInfo.Exp, 10, 64)
	if err != nil || expiration <= time.Now().UTC().Unix() {
		return errs.AuthExpiredError("token is expired")
	}

	// **驗證 2: Audience (aud) 是否與 Google Client ID 匹配**
	if tokenInfo.Aud != expectedClientID {
		return errs.SvcThirdPartyError("invalid audience")
	}

	// **驗證 3: 是否 email 已驗證**
	if tokenInfo.EmailVerified == "false" {
		return errs.SvcThirdPartyError("email is not verified")
	}

	return nil
}
