package db

import (
	"crypto/rand"
	"fmt"
	"math/big"
	"slices"
	"time"

	"github.com/tidbcloud/jiraport/pkg/entity"
)

func (c *Client) SelectAssigneeFromCandidate(emails []string) (string, error) {
	if len(emails) == 0 {
		return "", fmt.Errorf("no candidate to select")
	}
	assignHistories := make([]*entity.AssignHistory, 0)
	// asc order
	db := c.dataDB.Order("last_assign_time").Where("assignee_email in ?", emails).Find(&assignHistories)
	if db.Error != nil {
		return emails[0], db.Error
	}
	var res string
	if len(assignHistories) == len(emails) {
		// pick the earliest assigned one.
		res = assignHistories[0].AssigneeEmail
	} else {
		// rand assign when some one has not been assigned
		assignedList := make([]string, 0)
		for _, assigned := range assignHistories {
			assignedList = append(assignedList, assigned.AssigneeEmail)
		}
		unassignedList := make([]string, 0)
		for _, candidate := range emails {
			if !slices.Contains(assignedList, candidate) {
				unassignedList = append(unassignedList, candidate)
			}
		}
		n, err := rand.Int(rand.Reader, big.NewInt(int64(len(unassignedList))))
		if err != nil {
			return emails[0], err
		}
		res = unassignedList[n.Int64()]
	}

	history := entity.AssignHistory{AssigneeEmail: res, LastAssignTime: time.Now()}

	db = c.dataDB.FirstOrCreate(&history)
	if db.Error != nil {
		return emails[0], db.Error
	}

	// 更新 LastAssignTime
	history.LastAssignTime = time.Now()

	// 保存记录
	db = c.dataDB.Model(&history).Updates(entity.AssignHistory{LastAssignTime: time.Now()})
	if db.Error != nil {
		return emails[0], db.Error
	}
	return res, nil
}
