package Wx

import (
	"context"
	"math/rand"
	"strconv"
	"time"
	"wechat-api/hook"

	"wechat-api/ent/wx"
	"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 DeleteWxLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

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

func (l *DeleteWxLogic) DeleteWx(req *types.IDReq) (resp *types.BaseMsgResp, err error) {
	isAdmin := l.ctx.Value("isAdmin").(bool)

	// 获取账号信息
	wxInfo, err := l.svcCtx.DB.Wx.Query().
		Where(
			wx.IDEQ(req.Id),
		).
		Only(l.ctx)
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
	}

	// 获取服务器信息
	serverInfo, err := l.svcCtx.DB.Server.Get(l.ctx, wxInfo.ServerID)
	if err != nil {
		l.Error("获取服务器信息失败", err)
		return nil, err
	}

	hook := hook.NewHook(serverInfo.PrivateIP, serverInfo.AdminPort, wxInfo.Port)

	//  判断端口是否被占用
	portOccupied, err := hook.GetPortOccupiedInfo(wxInfo.Port)
	if err != nil {
		l.Error("获取端口占用信息失败", err)
		return nil, err
	}

	if portOccupied.Occupied == "1" {
		// 判断账号是否正在登录
		loginStatus, err := hook.IsLoginStatus()
		if err != nil {
			return nil, err
		}

		if loginStatus.Onlinestatus == "3" {
			l.Error("请先退出账号再删除", nil)
			return nil, nil
		}
	}

	randNum := strconv.Itoa(rand.New(rand.NewSource(time.Now().UnixNano())).Intn(1000000))

	if isAdmin {
		err = l.svcCtx.DB.Wx.UpdateOneID(req.Id).
			SetWxid(randNum).
			SetPort(randNum).
			Exec(l.ctx)
		_, err = l.svcCtx.DB.Wx.Delete().Where(wx.IDEQ(req.Id)).Exec(l.ctx)
	} else {
		organizationId := l.ctx.Value("organizationId").(uint64)
		err = l.svcCtx.DB.Wx.UpdateOneID(req.Id).
			Where(wx.OrganizationID(organizationId)).
			SetWxid(randNum).
			SetPort(randNum).
			Exec(l.ctx)
		_, err = l.svcCtx.DB.Wx.Delete().Where(wx.IDEQ(req.Id), wx.OrganizationIDEQ(organizationId)).Exec(l.ctx)
	}

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

	return &types.BaseMsgResp{Msg: errormsg.DeleteSuccess}, nil
}
