package mysql

import (
	"context"
	"strings"

	"gorm.io/gorm"

	v1 "github.com/pingcap-inc/pchub/model/v1"
)

type larkChat struct {
	db *gorm.DB
}

func newLarkChat(ds *datastore) *larkChat {
	return &larkChat{db: ds.db}
}

func (lc *larkChat) MGetByLarkIDs(ctx context.Context, larkIDs []string) ([]*v1.LartChat, error) {
	var res []*v1.LartChat
	d := lc.db.
		Where("chatLarkID IN (?)", larkIDs).
		Find(&res)

	return res, dbNotFoundErrorWrap(d.Error)
}

func (lc *larkChat) Search(_ context.Context, kw string) ([]*v1.LartChat, error) {
	var res []*v1.LartChat

	kw = strings.ReplaceAll(kw, "'", "")
	kw = strings.ReplaceAll(kw, "%", "")

	d := lc.db.
		Where("LOWER(name) like '%" + kw + "%'").
		Order("name asc").
		Limit(20).
		Find(&res)

	return res, dbNotFoundErrorWrap(d.Error)
}

func (lc *larkChat) ListAll(ctx context.Context) ([]*v1.LartChat, error) {
	var res []*v1.LartChat
	d := lc.db.
		Find(&res)

	return res, dbNotFoundErrorWrap(d.Error)
}

func (lc *larkChat) Sync(ctx context.Context, news, updates []*v1.LartChat, delLarkIDs []string) error {
	tx := lc.db.Begin()

	// new
	if len(news) > 0 {
		err := tx.Create(news).Error
		if err != nil {
			tx.Rollback()

			return err
		}
	}

	// update
	for _, g := range updates {
		err := tx.Save(&g).Error
		if err != nil {
			tx.Rollback()

			return err
		}
	}

	// del
	if len(delLarkIDs) > 0 {
		err := tx.Unscoped().Where("chatLarkID IN (?)", delLarkIDs).Delete(&v1.LartChat{}).Error
		if err != nil {
			tx.Rollback()

			return err
		}
	}

	tx.Commit()

	return nil
}
