package handler

import (
	"net/http"
	"time"

	"gitee.ltd/lxh/wechat-robot/internal/types"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/session"
	logtoClient "github.com/logto-io/go/v2/client"
	"github.com/valyala/fasthttp/fasthttpadaptor"

	"gitee.ltd/lxh/wechat-robot/internal/config"
)

// 实现Logto会话存储接口
var store = session.New(session.Config{
	KeyLookup:    "cookie:logto-session",
	CookieSecure: false, // 开发环境可设成false
})

// LogtoLogin 重定向到Logto登录页面
func LogtoLogin(c *fiber.Ctx) error {
	// 加载配置
	cfg, err := config.Load()
	if err != nil {
		return c.Redirect("/error?error=系统错误，无法加载配置")
	}

	// 构建回调URL
	callbackURL := c.Protocol() + "://" + c.Hostname() + "/auth/logto/callback"
	//callbackURL := "https://wechat.0bug.dev/auth/logto/callback"

	// 创建Logto客户端配置
	logtoConfig := &logtoClient.LogtoConfig{
		Endpoint:  cfg.Auth.Logto.Endpoint,
		AppId:     cfg.Auth.Logto.AppId,
		AppSecret: cfg.Auth.Logto.AppSecret,
	}
	// 获取会话
	fiberSessionStorage := &types.LogtoSessionStorage{Store: store, Ctx: c}

	// 创建Logto客户端
	client := logtoClient.NewLogtoClient(logtoConfig, fiberSessionStorage)
	// 获取登录链接
	signInUri, err := client.SignInWithRedirectUri(callbackURL)
	if err != nil {
		return c.Redirect("/error?error=Logto登录错误: " + err.Error() + "。请在Logto控制台确认回调URI为: " + callbackURL)
	}
	// 去登录
	return c.Redirect(signInUri)
}

// LogtoCallback 处理Logto登录回调
func LogtoCallback(c *fiber.Ctx) error {
	// 加载配置
	cfg, err := config.Load()
	if err != nil {
		return c.Redirect("/error?error=系统错误，无法加载配置")
	}

	// 创建Logto客户端配置
	logtoConfig := &logtoClient.LogtoConfig{
		Endpoint:  cfg.Auth.Logto.Endpoint,
		AppId:     cfg.Auth.Logto.AppId,
		AppSecret: cfg.Auth.Logto.AppSecret,
	}
	// 获取会话
	fiberSessionStorage := &types.LogtoSessionStorage{Store: store, Ctx: c}
	// 创建Logto客户端
	client := logtoClient.NewLogtoClient(logtoConfig, fiberSessionStorage)

	r := &http.Request{}
	if err = fasthttpadaptor.ConvertRequest(c.Context(), r, true); err != nil {
		return c.Redirect("/error?error=转换请求错误: " + err.Error())
	}

	// 处理回调
	if err = client.HandleSignInCallback(r); err != nil {
		return c.Redirect("/error?error=Logto回调处理错误: " + err.Error())
	}

	// 设置auth_token cookie，使用logto前缀
	cookie := new(fiber.Cookie)
	cookie.Name = "auth_token"
	cookie.Value = "logto:auth"                     // 设置auth_token带有logto前缀
	cookie.Expires = time.Now().Add(24 * time.Hour) // 24小时过期
	cookie.HTTPOnly = true
	cookie.Path = "/"
	c.Cookie(cookie)

	// 重定向到机器人列表页面
	return c.Redirect("/admin/robots")
}

// LogtoLogout 处理Logto退出登录
func LogtoLogout(c *fiber.Ctx) error {
	// 加载配置
	cfg, err := config.Load()
	if err != nil {
		return c.Redirect("/error?error=系统错误，无法加载配置")
	}

	// 创建Logto客户端配置
	logtoConfig := &logtoClient.LogtoConfig{
		Endpoint:  cfg.Auth.Logto.Endpoint,
		AppId:     cfg.Auth.Logto.AppId,
		AppSecret: cfg.Auth.Logto.AppSecret,
	}
	// 获取会话
	fiberSessionStorage := &types.LogtoSessionStorage{Store: store, Ctx: c}
	// 创建Logto客户端
	client := logtoClient.NewLogtoClient(logtoConfig, fiberSessionStorage)

	// 构建登出后重定向URL
	postLogoutRedirectURL := c.Protocol() + "://" + c.Hostname()

	// 获取登出链接
	signOutUri, err := client.SignOut(postLogoutRedirectURL)
	if err != nil {
		return c.Redirect("/error?error=Logto登出错误: " + err.Error())
	}

	// 清除本地Cookie
	cookie := new(fiber.Cookie)
	cookie.Name = "auth_token"
	cookie.Value = ""
	cookie.Expires = time.Now().Add(-time.Hour) // 设置为过期
	cookie.HTTPOnly = true
	cookie.Path = "/"
	c.Cookie(cookie)

	// 重定向到Logto登出页面
	return c.Redirect(signOutUri)
}
