// Package robot -----------------------------
// @file      : replyRuler.go
// @author    : JJXu
// @contact   : wavingbear@163.com
// @time      : 2025/6/13 17:39
// -------------------------------------------
package robot

import (
	"context"
	"fonchain-fiee/api/accountFiee"
	"fonchain-fiee/pkg/common/ws"
	"fonchain-fiee/pkg/service"
	"fonchain-fiee/pkg/service/asChat/consts"
	"fonchain-fiee/pkg/service/asChat/dto"
	"strings"
	"time"
)

type Reply struct {
	Response string
	Rules    []IRule
}

func (r *Reply) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, msg *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
	for _, rule := range r.Rules {
		hit, runTime, logic = rule.Hit(eventType, chatUser, wsClient, msg, robotInfo)
		if hit {
			return
		}
	}
	return
}

type IRule interface {
	Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, msg *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error)
}

func NewReplyWhenHitKeywords(keywords []string) IRule {
	return &ReplyWhenHitKeywords{Keywords: keywords}
}

// KeywordsRuleChecker 关键字回复
type ReplyWhenHitKeywords struct {
	Keywords []string `json:"keywords"`
}

func (k ReplyWhenHitKeywords) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
	if record == nil {
		return
	}
	for _, v := range k.Keywords {
		if strings.Contains(record.Content, v) {
			hit = true
			break
		}
	}
	logic = func(msg string) error {
		var notice = dto.MessageListType{}
		notice.BuildMessage(record)
		_, err := consts.ChatRoom.SendSessionMessage(robotInfo, record.SessionId, ws.NewChatMsgType, notice)
		return err
	}
	return
}

// 用户打开聊天会话直接发送
func NewReplyWhenUserJoinSession() IRule {
	return &ReplyWhenUserJoinSession{}
}

type ReplyWhenUserJoinSession struct {
}

func (k ReplyWhenUserJoinSession) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
	if eventType != ws.EventUserJoin {
		return
	}
	if wsClient == nil {
		return
	}
	ctx := context.Background()
	queryRes, err := service.AccountFieeProvider.GetChatRecordList(ctx, &accountFiee.GetChatRecordListRequest{
		Query: &accountFiee.ChatRecordData{
			SessionId: wsClient.SessionId,
		},
		Page:     1,
		PageSize: 1,
		Order:    "created_at desc",
	})
	if err != nil {
		return
	}
	//如果最近一次的消息也是机器人发送的,就不再发送了
	for i, v := range queryRes.List {
		if i == 0 {
			if v.UserId == robotInfo.ID {
				return
			} else {
				break
			}
		}
	}
	hit = true
	logic = func(msg string) error {
		var notice = dto.MessageListType{}
		newRecord := &accountFiee.ChatRecordData{
			SessionId: wsClient.SessionId,
			UserId:    wsClient.UserId,
			Name:      wsClient.SessionId,
			Avatar:    robotInfo.Avatar,
			MsgType:   1,
			Content:   msg,
		}
		notice.BuildMessage(newRecord)
		_, err = consts.ChatRoom.SendSessionMessage(robotInfo, wsClient.SessionId, ws.NewChatMsgType, notice)
		return err
	}
	return
}

// 客服
func NewReplyWhenWaiterNoAction(delaySecond time.Duration) *ReplyWhenWaiterNoAction {
	return &ReplyWhenWaiterNoAction{
		DelaySecond: delaySecond,
	}
}

type ReplyWhenWaiterNoAction struct {
	DelaySecond time.Duration
}

func (k *ReplyWhenWaiterNoAction) Hit(eventType ws.EventType, chatUser *accountFiee.ChatUserData, wsClient *ws.Client, record *accountFiee.ChatRecordData, robotInfo *accountFiee.ChatUserData) (hit bool, runTime time.Time, logic func(msg string) error) {
	runTime = time.Now().Add(k.DelaySecond * time.Second)
	logic = func(msg string) error {
		var notice = dto.MessageListType{}
		notice.BuildMessage(record)
		_, err := consts.ChatRoom.SendSessionMessage(robotInfo, record.SessionId, ws.NewChatMsgType, notice)
		return err
	}
	return

}