package svc

import (
	"context"
	"entgo.io/ent/dialect/sql/schema"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/config"
	"git.noahlan.cn/noahlan/ntool/nmapper"
	"git.noahlan.cn/noahlan/ntool/nmapper/wrapper"
	"github.com/zeromicro/go-zero/core/service"
	"github.com/zeromicro/go-zero/core/stores/redis"

	"git.noahlan.cn/noahlan/ntool-biz/core/i18n"
	"git.noahlan.cn/noahlan/ntool-biz/zero/logz"
	"git.noahlan.cn/noahlan/ntool/nlog"
	"github.com/zeromicro/go-zero/core/logx"

	// required by schema hooks.
	_ "git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent/runtime"
)

type ServiceContext struct {
	Config config.Config
	DB     *ent.Client
	Redis  *redis.Redis

	Mapper         *nmapper.MapperObject
	Convert        *Convert
	DistrictHelper *DistrictHelper
}

func NewServiceContext(c config.Config) *ServiceContext {
	tmp := &ServiceContext{Config: c}

	nlog.MustSetup(logz.WrapConf(c.Log))
	logx.SetWriter(logz.NewWriter())

	// 配置多语言
	i18n.InitWithConfig(c.I18nConf)

	// redis
	tmp.Redis = redis.MustNewRedis(redis.RedisConf{
		Host: c.RedisConf.Addr,
		Type: c.RedisConf.Type,
		Pass: c.RedisConf.Password,
		Tls:  c.RedisConf.Tls,
	})

	// database
	dbOpts := make([]ent.Option, 0)
	dbOpts = append(dbOpts, ent.Log(nlog.Info))
	dbOpts = append(dbOpts, ent.Driver(c.DatabaseConf.NewNoCacheDriver()))
	if c.Mode == service.DevMode || c.Mode == service.TestMode {
		dbOpts = append(dbOpts, ent.Debug())
	}
	tmp.DB = ent.NewClient(dbOpts...)
	// 初始化数据库结构
	if err := tmp.DB.Schema.Create(context.Background(),
		schema.WithDropColumn(true),
		schema.WithDropIndex(true),
		schema.WithForeignKeys(false)); err != nil {
		nlog.Errorw("数据库错误", nlog.Field("err", err))
		panic(err)
	}

	// mapper
	tmp.Mapper = nmapper.NewMapper(nmapper.WithTypeWrapper(wrapper.StrWrapper()...))

	// convert
	tmp.Convert = NewConvert(tmp)

	// helper
	DistrictHelperInst.svcCtx = tmp
	tmp.DistrictHelper = DistrictHelperInst

	return tmp
}
