package svc

import (
	"github.com/bwmarrin/snowflake"
	"github.com/casbin/casbin/v2"
	"github.com/redis/go-redis/v9"
	"github.com/zeromicro/go-zero/core/collection"
	"gorm.io/gorm"
	"time"
	"wechat-api/database"
	"wechat-api/database/dao/wechat/query"

	"github.com/suyuan32/simple-admin-core/rpc/coreclient"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest"
	"github.com/zeromicro/go-zero/zrpc"
	"wechat-api/ent"
	_ "wechat-api/ent/runtime"
	"wechat-api/internal/config"
	"wechat-api/internal/middleware"
	"wechat-api/internal/pkg/wechat_ws"
	mongo_model "wechat-api/mongo_model"
)

type ServiceContext struct {
	Config      config.Config
	Casbin      *casbin.Enforcer
	Authority   rest.Middleware
	Miniprogram rest.Middleware
	DB          *ent.Client //大家都不爱用，后边可以慢慢过渡到gorm的库
	WechatDB    *gorm.DB
	WechatQ     *query.Query
	CoreRpc     coreclient.Core
	Rds         redis.UniversalClient
	WechatWs    map[string]*wechat_ws.WechatWsClient
	Cache       *collection.Cache
	NodeID      *snowflake.Node
	MongoModel  *mongo_model.AllMongoModel
}

func NewServiceContext(c config.Config) *ServiceContext {

	rds := c.RedisConf.MustNewUniversalRedis()

	cbn := c.CasbinConf.MustNewCasbinWithOriginalRedisWatcher(c.CasbinDatabaseConf.Type, c.CasbinDatabaseConf.GetDSN(), c.RedisConf)

	db := ent.NewClient(
		ent.Log(logx.Info), // logger
		ent.Driver(c.DatabaseConf.NewNoCacheDriver()),
		ent.Debug(), // debug mode
	)

	// gorm 数据库连接
	wechatDb, err := database.InitWechatDB(c.DatabaseConf, c.Mode)
	if err != nil {
		logx.Error(err)
		panic("gorm 数据库连接失败")
	}
	wechatQ := query.Use(wechatDb)

	// 初始化 MongoDB 客户端
	all_mongo_model := mongo_model.SetupMongoModel(c.FastgptMongoConf.Url, c.FastgptMongoConf.DBName)

	coreRpc := coreclient.NewCore(zrpc.NewClientIfEnable(c.CoreRpc))

	wechatWs := make(map[string]*wechat_ws.WechatWsClient)

	for _, ws := range c.WebSocket {
		if ws.Type == "wechat" {
			client, err := wechat_ws.NewWechatWsClient(ws.Url, ws.Name, ws.Type)
			if err != nil {
				logx.Error(err)
			} else {
				logx.Info("建立ws client成功~", ws.Name)
				go client.ReadPump()
				go client.WritePump()
				wechatWs[ws.Name] = client
			}
		}
	}

	cache, err := collection.NewCache(time.Hour * 24 * 365)
	if err != nil {
		logx.Error(err)
		panic("本地缓存实例失败")
	}

	node, err := snowflake.NewNode(1)
	if err != nil {
		logx.Error(err)
		panic("雪花算法实例失败")
	}

	return &ServiceContext{
		Config:      c,
		Authority:   middleware.NewAuthorityMiddleware(cbn, rds, coreRpc).Handle,
		Miniprogram: middleware.NewMiniprogramMiddleware(cbn, rds, coreRpc, c).Handle,
		DB:          db,
		WechatDB:    wechatDb,
		WechatQ:     wechatQ,
		CoreRpc:     coreRpc,
		Rds:         rds,
		WechatWs:    wechatWs,
		Cache:       cache,
		NodeID:      node,
		MongoModel:  all_mongo_model,
	}
}
