package controllers

import (
	"fmt"

	"knowledge/models/friendagent"
	"knowledge/modules/structs"

	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/middleware/jwt"
)

// FriendAgentController 运幄用户 × 云端 Friend Agent 的 HTTP 入口
type FriendAgentController struct{}

// bridge WS Bridge 单例（懒初始化，依赖 friendAgentModel）
var agentBridge *friendagent.Bridge

func getAgentBridge() *friendagent.Bridge {
	if agentBridge == nil {
		agentBridge = friendagent.NewBridge(&friendAgentModel)
	}
	return agentBridge
}

// Bridge 暴露 Bridge 实例（main.go 注册 connector 回连路由用）
func (c *FriendAgentController) Bridge() *friendagent.Bridge {
	return getAgentBridge()
}

// GetWS WS 升级入口（JWT 中间件已鉴权），转发给 Bridge 消息循环
func (c *FriendAgentController) GetWS(ctx iris.Context) {
	if !friendAgentModel.Enabled() {
		ctx.StatusCode(iris.StatusServiceUnavailable)
		ctx.JSON(iris.Map{"success": false, "msg": "Agent 功能未启用"})
		return
	}
	userID := currentUserID(ctx)
	getAgentBridge().HandleWS(ctx.ResponseWriter(), ctx.Request(), userID)
}

func currentUserID(ctx iris.Context) string {
	user := jwt.Get(ctx).(*structs.UserJWT)
	return fmt.Sprintf("%d", user.UserID)
}

// PostInitialize 一键初始化（幂等）：已就绪返回 200，正在收敛返回 202 继续轮询
func (c *FriendAgentController) PostInitialize(ctx iris.Context) {
	if !friendAgentModel.Enabled() {
		ctx.JSON(iris.Map{"success": false, "msg": "Agent 功能未启用"})
		return
	}
	userID := currentUserID(ctx)
	binding, err := friendAgentModel.InitializeAgent(userID)
	if err != nil {
		status := 500
		if binding != nil && binding.State == structs.FriendAgentStateFailed {
			status = 500
		}
		ctx.StatusCode(status)
		ctx.JSON(iris.Map{"success": false, "msg": err.Error(), "state": bindingState(binding)})
		return
	}
	ctx.JSON(iris.Map{
		"success": true,
		"data":    bindingView(binding),
	})
}

// GetStatus 实例实时状态查询（同步回绑定表）
func (c *FriendAgentController) GetStatus(ctx iris.Context) {
	if !friendAgentModel.Enabled() {
		ctx.JSON(iris.Map{"success": false, "msg": "Agent 功能未启用"})
		return
	}
	inst, binding, err := friendAgentModel.GetStatus(currentUserID(ctx))
	if err != nil {
		ctx.JSON(iris.Map{"success": false, "msg": err.Error()})
		return
	}
	resp := iris.Map{"success": true, "binding": bindingView(binding)}
	if inst != nil {
		resp["instance"] = iris.Map{
			"id":                inst.ID,
			"name":              inst.Name,
			"process_state":     inst.ProcessState,
			"health_state":      inst.HealthState,
			"config_state":      inst.ConfigState,
			"extension_state":   inst.ExtensionState,
			"desired_run_state": inst.DesiredRunState,
			"last_error":        inst.LastError,
		}
	}
	ctx.JSON(resp)
}

// PostEnable 开关 Agent（desired_run_state running/stopped）
func (c *FriendAgentController) PostEnable(ctx iris.Context) {
	if !friendAgentModel.Enabled() {
		ctx.JSON(iris.Map{"success": false, "msg": "Agent 功能未启用"})
		return
	}
	var body struct {
		Enabled bool `json:"enabled"`
	}
	if err := ctx.ReadJSON(&body); err != nil {
		ctx.JSON(iris.Map{"success": false, "msg": "参数错误"})
		return
	}
	binding, err := friendAgentModel.SetEnabled(currentUserID(ctx), body.Enabled)
	if err != nil {
		ctx.JSON(iris.Map{"success": false, "msg": err.Error()})
		return
	}
	ctx.JSON(iris.Map{"success": true, "data": bindingView(binding)})
}

// PostDelete 删除实例与绑定
func (c *FriendAgentController) PostDelete(ctx iris.Context) {
	if !friendAgentModel.Enabled() {
		ctx.JSON(iris.Map{"success": false, "msg": "Agent 功能未启用"})
		return
	}
	if err := friendAgentModel.DeleteAgent(currentUserID(ctx)); err != nil {
		ctx.JSON(iris.Map{"success": false, "msg": err.Error()})
		return
	}
	ctx.JSON(iris.Map{"success": true})
}

func bindingState(b *structs.UserFriendAgent) string {
	if b == nil {
		return ""
	}
	return b.State
}

func bindingView(b *structs.UserFriendAgent) iris.Map {
	if b == nil {
		return nil
	}
	return iris.Map{
		"user_id":        b.UserID,
		"instance_id":    b.InstanceID,
		"deploy_id":      b.DeployID,
		"state":          b.State,
		"last_error":     b.LastError,
		"initialized_at": b.InitializedAt,
		"converged_at":   b.ConvergedAt,
	}
}

var _ = friendagent.Config{} // 保持 import 稳定
