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

import (
	"context"
	"fmt"
	"fonchain-fiee/api/accountFiee"
	"fonchain-fiee/pkg/common/ws"
	"fonchain-fiee/pkg/service"
	"fonchain-fiee/pkg/service/asChat/consts"
	"log"
	"sync"
	"time"
)

func NewRobot() *Robot {
	ctx := context.Background()
	robotQuery, err := service.AccountFieeProvider.GetChatUserList(ctx, &accountFiee.GetChatUserListRequest{
		Query: &accountFiee.ChatUserData{Role: 3},
		Page:  1, PageSize: 1,
	})
	if err != nil {
		panic("聊天机器人初始化失败,err:" + err.Error())
	}
	var robotInfo *accountFiee.ChatUserData
	if robotQuery.Total > 0 {
		robotInfo = robotQuery.List[0]
	} else {
		robotInfo = &accountFiee.ChatUserData{
			NickName: "阿泰",
			Role:     3,
			Origin:   "fontree",
		}
		createChatUserResp, errs := service.AccountFieeProvider.CreateChatUser(ctx, robotInfo)
		if errs != nil {
			panic("聊天机器人创建失败,err:" + errs.Error())
		}
		robotInfo = createChatUserResp.Data
	}
	r := &Robot{
		Info: robotInfo,
		EventListener: &ws.EventListener{
			Name: "robot1",
			ListenEvents: []ws.ListenEvent{ //只监听消息推送事件
				{ws.EventChatMessage, ws.EventProgressAfter},
			},
			Chan: make(ws.ListenEventChan),
		},
	}
	consts.ChatRoom.RegisterEventListener(r.EventListener)
	go r.Run()
	return r
}

type Robot struct {
	Info      *accountFiee.ChatUserData //机器人信息
	Rules     []Reply                   //回复规则
	DelayTask []RobotTask               //演示任务
	ticker    *time.Ticker              //定时器
	stopChan  chan struct{}             //停止管道
	isRunning bool                      //运行状态
	mu        sync.Mutex
	*ws.EventListener
}

func (r *Robot) Listen(record *accountFiee.ChatRecordData) {
	for _, replyRules := range r.Rules {
		for _, rule := range replyRules.Rules {
			hit, runTime, function := rule.Hit(record)
			if hit && function != nil {
				if runTime.IsZero() {
					go func() {
						err := function(r.Info.ID, replyRules.Response)
						if err != nil {
							log.Printf("聊天机器人[%d]回复消息失败:%v", r.Info.ID, err)
						}
					}()
				} else {
					r.mu.Lock()
					r.DelayTask = append(r.DelayTask, RobotTask{
						RunTime:  runTime,
						Run:      function,
						Response: replyRules.Response,
					})
					r.mu.Unlock()
					// 添加任务后启动定时任务(如果未运行)
					if !r.isRunning {
						go r.Run()
					}
				}
				break
			}
		}
	}
}

func (r *Robot) Run() {
	r.mu.Lock()
	if r.isRunning {
		r.mu.Unlock()
		return
	}
	r.isRunning = true
	r.ticker = time.NewTicker(time.Second)
	r.stopChan = make(chan struct{})
	r.mu.Unlock()

	defer func() {
		r.mu.Lock()
		r.isRunning = false
		if r.ticker != nil {
			r.ticker.Stop()
			r.ticker = nil
		}
		r.stopChan = nil
		r.mu.Unlock()
	}()

	for {
		select {
		case <-r.ticker.C:
			r.mu.Lock()
			if len(r.DelayTask) == 0 {
				r.mu.Unlock()
				break
				//return // 没有任务时退出
			}
			now := time.Now()
			var remainingTasks []RobotTask
			for _, task := range r.DelayTask {
				if now.After(task.RunTime) {
					// 执行任务
					go func() {
						err := task.Run(r.Info.ID, task.Response)
						if err != nil {
							log.Printf("聊天机器人[%d]回复消息失败:%v", r.Info.ID, err)
						}
					}()
				} else {
					// 保留未到期的任务
					remainingTasks = append(remainingTasks, task)
				}
			}
			r.DelayTask = remainingTasks
			r.mu.Unlock()
		case <-r.stopChan:
			return
		case event := <-r.EventListener.Chan:
			fmt.Sprintf("listen event:%#v\n", event)

		}
	}
}

// Stop 主动停止机器人的定时任务
func (r *Robot) Stop() {
	r.mu.Lock()
	if r.stopChan != nil {
		close(r.stopChan)
	}
	r.mu.Unlock()
}