package main

import (
	"container/list"
	"fmt"
	"log/slog"
	"time"

	twitter "github.com/g8rswimmer/go-twitter/v2"
)

/*

处理三种情况：

1. idx 为空；
2. idx 正常匹配
3. idx 没有匹配上
x 4. 到最后也没匹配上，或者超过了多少页。 外面处理；

*/

type Idx struct {
	idx    []UserTask
	newIdx []UserTask
	//taskId string
	List *list.List
}

func NewIdx(i []UserTask) *Idx {
	return &Idx{
		idx:    i,
		newIdx: make([]UserTask, 0, 10),
		List:   list.New(),
	}
}

func (s *Idx) Idx(page []UserTask) (bool, *list.List) {

	if len(s.newIdx) == 0 {
		for k, v := range page {
			s.newIdx = append(s.newIdx, v)
			if k > 5 {
				break
			}
		}
	}

	if s.idx != nil && len(s.idx) == 0 {

		newList := list.New()

		for _, v := range page {
			newList.PushFront(v)
		}

		s.idx = s.newIdx
		s.newIdx = make([]UserTask, 0, 10)

		return true, newList
	}

	//TODO 匹配多个元素，防止用户取消；
	for k, v := range page {

		match := false

		for ik, iv := range s.idx {
			slog.Info("match", "idx", iv.UserId, "page user id", v.UserId, "page user name", v.UserName)
			if v.UserId == iv.UserId {
				match = true
				break
				_, _ = k, ik
			}
		}

		if match {

			newList := s.List
			s.List = list.New()
			//idx
			s.idx = s.newIdx
			s.newIdx = make([]UserTask, 0, 10)

			fmt.Println("newList", "new users", newList.Len())

			return true, newList

		} else {
			s.List.PushFront(v)
		}
	}
	return false, nil
}

type PageUsers struct {
	idx *Idx
}

func NewPageUsers(idx *Idx) *PageUsers {

	return &PageUsers{
		idx: idx,
	}
}

type req func(tweetId string, next string) ([]*twitter.UserObj, string, *twitter.RateLimit, error)

/*
TODO 最后一页的标识，没有处理；
*/
func (p *PageUsers) Request(tweetId string, next string, f req) ([]UserTask, error) {

	//users, next, rt, err := p.cli.TweetLikingUsers(tweetId, next)

	users, newNext, rt, err := f(tweetId, next)
	if err != nil {
		return nil, err
	}
	slog.Debug("Request", "tweet id", tweetId, "next", newNext, "len(users)", len(users))

	// wait rate limit.
	if rt != nil && rt.Remaining == 0 {
		time.Sleep(time.Until(rt.Reset.Time().Add(500 * time.Millisecond)))
	}

	taskUser := userObjectToUserTask(users)

	// 查询最新的一页 followers, 去历史中匹配。
	// 如果已经与历史记录相连接，表明已经完成了查询，不必再继续查next.
	ok, l := p.idx.Idx(taskUser)
	if ok {
		res := make([]UserTask, 0, l.Len())
		for e := l.Front(); e != nil; e = e.Next() {
			if user, ok := e.Value.(UserTask); ok {
				res = append(res, user)
			}
		}
		return res, nil
	}
	return p.Request(tweetId, newNext, f)
}

func userObjectToUserTask(pageUsers []*twitter.UserObj) []UserTask {

	res := make([]UserTask, 0, len(pageUsers))

	for _, v := range pageUsers {
		res = append(res, UserTask{
			//TaskId   string `json:"task_id"`
			UserId:   v.ID,       //string `json:"user_id"`
			UserName: v.UserName, //string `json:"user_name"`
		})
	}

	return res
}
