package Wx

import (
	"context"
	"wechat-api/ent/wx"
	"wechat-api/hook"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"
	"wechat-api/internal/utils/dberrorhandler"

	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"github.com/zeromicro/go-zero/core/logx"
)

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

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

func (l *UpdateWxLogic) UpdateWx(req *types.WxInfo) (resp *types.BaseMsgResp, err error) {
	isAdmin := l.ctx.Value("isAdmin").(bool)

	wxinfo, err := l.svcCtx.DB.Wx.Query().
		Where(
			wx.IDEQ(*req.Id),
		).
		WithAgent().
		Only(l.ctx)
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
	}

	if isAdmin {
		tx, err := l.svcCtx.DB.Tx(context.Background())

		if err != nil {
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}

		err = tx.Wx.UpdateOneID(*req.Id).
			SetNotNilCallback(req.Callback).
			SetNotNilAgentID(req.AgentId).
			SetNotNilOrganizationID(req.OrganizationId).
			SetNotNilAPIBase(req.ApiBase).
			SetNotNilAPIKey(req.ApiKey).
			Exec(l.ctx)

		if req.Callback != nil && *req.Callback != "" {
			serverinfo, serverErr := tx.Server.Get(l.ctx, wxinfo.ServerID)
			if serverErr != nil {
				_ = tx.Rollback()
				return nil, dberrorhandler.DefaultEntError(l.Logger, serverErr, req)
			}
			hook := hook.NewHook(serverinfo.PrivateIP, serverinfo.AdminPort, wxinfo.Port)
			loginStatus, _ := hook.IsLoginStatus()
			if err != nil {
				_ = tx.Rollback()
				return nil, err
			}
			if loginStatus.Onlinestatus == "3" {
				err = hook.ConfigureMsgRecive("1", *req.Callback)
				if err != nil {
					_ = tx.Rollback()
					return nil, err
				}
			}
		}

		if err != nil {
			_ = tx.Rollback()
			l.Error("更新失败", err)
			return nil, err
		}
		// 所有操作成功，提交事务
		err = tx.Commit()
		if err != nil {
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}
	} else {
		organizationId := l.ctx.Value("organizationId").(uint64)
		err = l.svcCtx.DB.Wx.UpdateOneID(*req.Id).
			Where(wx.OrganizationID(organizationId)).
			SetNotNilAgentID(req.AgentId).
			Exec(l.ctx)
		if err != nil {
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}
	}
	l.svcCtx.Rds.HDel(l.ctx, "wx_info", wxinfo.Wxid)
	return &types.BaseMsgResp{Msg: errormsg.UpdateSuccess}, nil
}
