package logic

import (
	"fusenapi/utils/auth"
	"fusenapi/utils/basic"
	"log"
	"net/http"
	"net/url"
	"time"

	"context"

	"fusenapi/server/home-user-auth/internal/svc"
	"fusenapi/server/home-user-auth/internal/types"

	"github.com/474420502/requests"
	"github.com/zeromicro/go-zero/core/logx"
	"golang.org/x/net/proxy"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"gorm.io/gorm"
)

type UserGoogleLoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserGoogleLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserGoogleLoginLogic {
	return &UserGoogleLoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserGoogleLoginLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
	log.Println(r, w)
}

func (l *UserGoogleLoginLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
	log.Println(resp.Message)
	http.Redirect(w, r, "http://localhost:8080?token="+resp.Message, http.StatusMovedPermanently)
	// log.Println(r, w)
}

func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, userinfo *auth.UserInfo) (resp *basic.Response) {
	// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
	// userinfo 传入值时, 一定不为null

	dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct)
	if err != nil {
		log.Fatal(err)
	}

	customClient := &http.Client{
		Transport: &http.Transport{
			Dial: dialer.Dial,
		},
	}

	ctx := context.WithValue(context.Background(), oauth2.HTTPClient, customClient)

	var googleOauthConfig = &oauth2.Config{
		RedirectURL:  "http://localhost:9900/api/user/oauth2/login/google",
		ClientID:     l.svcCtx.Config.OAuth.Google.Appid,
		ClientSecret: l.svcCtx.Config.OAuth.Google.Secret,
		Scopes:       []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"},
		Endpoint:     google.Endpoint,
	}

	token, err := googleOauthConfig.Exchange(ctx, req.Code)
	if err != nil {
		logx.Error(err)
		resp.SetStatus(basic.CodeApiErr)
	}
	ses := requests.NewSession()
	ses.Config().SetProxy("socks5://127.0.0.1:1080") // 代理 为了测试功能

	r, err := ses.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken).Execute()
	if err != nil {
		logx.Error(err)
		return resp.SetStatus(basic.CodeOAuthGoogleApiErr)
	}

	log.Println(r.Json())

	googleId := r.Json().Get("id").Int()
	return resp.Set(304, "21321321")
	user, err := l.svcCtx.AllModels.FsUser.FindUserByGoogleId(context.TODO(), googleId)
	log.Println(user)
	if err != nil {
		if err != gorm.ErrRecordNotFound {
			logx.Error(err)

			return resp.SetStatus(basic.CodeDbSqlErr)
		}

		// 如果密码匹配,则生成 JWT Token。
		nowSec := time.Now().Unix()
		jwtToken, err := auth.GenerateJwtToken(&l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, nowSec, 0, 0)

		// 如果生成 JWT Token 失败,则抛出错误并返回未认证的状态码。
		if err != nil {
			logx.Error(err)
			return resp.SetStatus(basic.CodeServiceErr)
		}

		return resp.SetRewriteHandler(func(w http.ResponseWriter, r *http.Request) {
			http.Redirect(w, r, "http://localhost:9900?token="+url.QueryEscape(jwtToken), http.StatusFound)
		})

	}

	return resp.SetStatus(basic.CodeOK)
}