package sysconfig

import (
	"bindbox-game/internal/pkg/logger"
	"bindbox-game/internal/repository/mysql"
	"bindbox-game/internal/repository/mysql/dao"
	"bindbox-game/internal/repository/mysql/model"
	"context"
	"time"
)

type Service interface {
	GetByKey(ctx context.Context, key string) (*model.SystemConfigs, error)
	UpsertByKey(ctx context.Context, key string, value string, remark string) (*model.SystemConfigs, error)
	ModifyByID(ctx context.Context, id int64, value *string, remark *string) error
	DeleteByID(ctx context.Context, id int64) error
	List(ctx context.Context, page int, pageSize int, keyword string) (items []*model.SystemConfigs, total int64, err error)
}

type service struct {
	logger logger.CustomLogger
	readDB *dao.Query
}

func New(l logger.CustomLogger, db mysql.Repo) Service {
	return &service{logger: l, readDB: dao.Use(db.GetDbR())}
}

func (s *service) GetByKey(ctx context.Context, key string) (*model.SystemConfigs, error) {
	return s.readDB.SystemConfigs.WithContext(ctx).ReadDB().Where(s.readDB.SystemConfigs.ConfigKey.Eq(key)).Take()
}

func (s *service) UpsertByKey(ctx context.Context, key string, value string, remark string) (*model.SystemConfigs, error) {
	q := s.readDB.SystemConfigs.WithContext(ctx)
	m, err := q.Where(s.readDB.SystemConfigs.ConfigKey.Eq(key)).Take()
	if err == nil && m != nil {
		_, e := q.Where(s.readDB.SystemConfigs.ID.Eq(m.ID)).Updates(map[string]any{"config_value": value, "remark": remark})
		if e != nil {
			return nil, e
		}
		m.ConfigValue = value
		m.Remark = remark
		return m, nil
	}
	m = &model.SystemConfigs{ConfigKey: key, ConfigValue: value, Remark: remark}
	if e := q.Create(m); e != nil {
		return nil, e
	}
	return m, nil
}

func (s *service) ModifyByID(ctx context.Context, id int64, value *string, remark *string) error {
	set := map[string]any{}
	if value != nil {
		set["config_value"] = *value
	}
	if remark != nil {
		set["remark"] = *remark
	}
	if len(set) == 0 {
		return nil
	}
	_, err := s.readDB.SystemConfigs.WithContext(ctx).Where(s.readDB.SystemConfigs.ID.Eq(id)).Updates(set)
	return err
}

func (s *service) DeleteByID(ctx context.Context, id int64) error {
	_, err := s.readDB.SystemConfigs.WithContext(ctx).Where(s.readDB.SystemConfigs.ID.Eq(id)).Updates(map[string]any{"deleted_at": time.Now()})
	return err
}

func (s *service) List(ctx context.Context, page int, pageSize int, keyword string) (items []*model.SystemConfigs, total int64, err error) {
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 20
	}
	q := s.readDB.SystemConfigs.WithContext(ctx).ReadDB()
	if keyword != "" {
		q = q.Where(s.readDB.SystemConfigs.ConfigKey.Like("%" + keyword + "%"))
	}
	total, err = q.Count()
	if err != nil {
		return
	}
	items, err = q.Order(s.readDB.SystemConfigs.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find()
	return
}
