package Wx

import (
	"context"
	"github.com/zeromicro/go-zero/core/errorx"
	"math/rand"
	"strconv"
	"time"
	"wechat-api/ent"
	"wechat-api/ent/wx"
	"wechat-api/hook"
	"wechat-api/internal/utils/dberrorhandler"

	"github.com/suyuan32/simple-admin-common/msg/errormsg"
	"wechat-api/internal/svc"
	"wechat-api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

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

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

func (l *CreateWxLogic) CreateWx(req *types.WxInfo) (*types.BaseMsgResp, error) {
	isAdmin := l.ctx.Value("isAdmin").(bool)
	if !isAdmin {
		l.Error("没有权限,请联系管理员", nil)
		return nil, errorx.NewDefaultError("没有权限,请联系管理员")
	}
	// 获取服务器信息
	server, err := l.svcCtx.DB.Server.Get(l.ctx, *req.ServerId)
	if err != nil {
		l.Error("获取服务器信息失败", err)
		return nil, err
	}

	hook := hook.NewHook(server.PrivateIP, server.AdminPort, *req.Port)

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

	if portOccupied.Occupied == "1" {
		l.Error("端口已占用,请改用其他端口", err)
		return nil, err
	}

	_, err = l.svcCtx.DB.Wx.Query().Where(wx.ServerIDEQ(server.ID)).Where(wx.PortEQ(*req.Port)).Limit(1).Only(l.ctx)
	if err != nil && !ent.IsNotFound(err) {
		l.Error("查询微信信息失败", err)
		return nil, err
	}

	if ent.IsNotFound(err) {
		wxid := strconv.Itoa(rand.New(rand.NewSource(time.Now().UnixNano())).Intn(1000000))
		_, err := l.svcCtx.DB.Wx.Create().
			SetServerID(*req.ServerId).
			SetPort(*req.Port).
			SetCallback(*req.Callback).
			SetOrganizationID(*req.OrganizationId).
			SetNotNilAPIBase(req.ApiBase).
			SetNotNilAPIKey(req.ApiKey).
			SetWxid(wxid).
			SetStatus(0).
			Save(l.ctx)
		if err != nil {
			return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
		}
	} else {
		l.Error("端口已使用,请使用其他端口", err)
		return nil, err
	}

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