package mysql

import (
	"context"

	v1 "github.com/pingcap-inc/pingcat/model/v1"
	"gorm.io/gorm"

	"github.com/pingcap-inc/pchub/pkg/log"
)

type message struct {
	db *gorm.DB
}

func newMessage(ds *datastore) *message {
	return &message{db: ds.db}
}

func (m *message) GetLastSessionMsg(ctx context.Context, larkUserID string) (*v1.Message, error) {
	var msg v1.Message
	err := m.db.
		Where("scene = 'LarkP2P'").
		Where("senderLarkID = ? OR receiverLarkID = ?", larkUserID, larkUserID).
		Order("createdAt desc").
		First(&msg).
		Error

	return &msg, dbNotFoundErrorWrap(err)
}

func (m *message) GetByID(_ context.Context, id string) (*v1.Message, error) {
	var msg v1.Message
	err := m.db.
		Where("id = ?", id).
		First(&msg).
		Error

	return &msg, dbNotFoundErrorWrap(err)
}

func (m *message) ListThreadMsgs(ctx context.Context, pid string) ([]*v1.Message, error) {
	var pmsgs []*v1.Message
	var msg *v1.Message
	db := m.db.Session(&gorm.Session{})
	err := db.
		Where("id = ?", pid).
		First(&msg).
		Error
	if err != nil {
		log.L(ctx).Warn("parent msg not found")
	} else {
		err = db.
			Where("id IN (?)", msg.FlatParentIDs).
			Order("createdAt asc").
			Find(&pmsgs).
			Error
		if err != nil {
			log.L(ctx).Warn("error when retrieve ancestor messages")
		}
	}

	msgs := make([]*v1.Message, 0)
	msgs = append(msgs, pmsgs...)
	if msg != nil {
		msgs = append(msgs, msg)
	}

	return msgs, err
}

func (m *message) Create(ctx context.Context, msg *v1.Message) (*v1.Message, error) {
	err := m.db.
		Create(msg).
		Error
	if err != nil {
		return nil, err
	}

	return msg, nil
}
