package main

import "encoding/json"

func VerifyFollowerInDb(userId, followerId string) (bool, error) {

	_, count, err := client.From("followers").Select("*", "exact", false).Eq("task_id", userId).Eq("user_id", followerId).Execute()

	if err != nil {
		return false, err
	}

	return count == 1, nil
}

func VerifyRetweeterInDb(tweetId, retweeter string) (bool, error) {

	_, count, err := client.From("retweeters").Select("*", "exact", false).Eq("task_id", tweetId).Eq("user_id", retweeter).Execute()

	if err != nil {
		return false, err
	}

	return count == 1, nil
}

func VerifyLikeInDb(tweetId, userId string) (bool, error) {

	_, count, err := client.From("tweet_liking_users").Select("*", "exact", false).Eq("task_id", tweetId).Eq("user_id", userId).Execute()

	if err != nil {
		return false, err
	}

	return count == 1, nil
}

func AddTaskInsert(req AddTaskReq, followerCount int) error {

	task := TaskInDB{
		User:          req.User,
		TaskType:      req.TaskType,
		TaskId:        req.TaskId,
		Start:         true,
		Stop:          false,
		FollowerCount: followerCount,
	}

	res, _, err := client.From("tasks").Insert(task, true, "", "representation", "").Execute()

	_ = res

	return err
}

func UpdateFollowerTaskCount(taskId, taskType, userId string, fc int) error {

	res, _, err := client.From("tasks").Update(&struct {
		FC int `json:"follower_count"`
	}{
		FC: fc,
	}, "", "exact").Eq("task_type", taskType).Eq("task_id", taskId).Eq("task_type", taskType).Execute()

	_ = res

	return err
}

func StopTaskUpdate(req AddTaskReq) error {

	//res, _, err := client.From("tasks").Insert(task, true, "", "representation", "").Execute()

	res, _, err := client.From("tasks").Update(&struct {
		Stop bool `json:"stop"`
	}{
		Stop: true,
	}, "", "exact").Eq("task_type", req.TaskType).Eq("task_id", req.TaskId).Execute()

	_ = res

	return err

}

type ProjectInDb struct {
	ProjectReq
	UserInfo
	Available bool `json:"available"`
}

type UserInfo struct {
	UserId   string `json:"user_id"`
	UserName string `json:"username"`
	Name     string `json:"name"`
}

func AddOrUpdateProject(cfg ProjectReq, user UserInfo) error {

	project := ProjectInDb{
		ProjectReq: cfg,
		UserInfo:   user,
		Available:  true,
	}

	res, _, err := client.From("project").Insert(project, true, "", "representation", "").Execute()

	_ = res

	return err
}

func QueryProjectByKeysAndToken(cfg ProjectReq) (UserInfo, bool, error) {

	data, count, err := client.From("project").Select("*", "exact", false).Eq("api_key", cfg.ApiKey).Eq("api_key_secret", cfg.ApiKeySecrect).Eq("token", cfg.Token).Eq("access_token", cfg.AccessToken).Eq("access_token_secret", cfg.AccessTokenSecret).Execute()

	if err != nil {
		return UserInfo{}, false, err
	}

	if count == 0 {
		return UserInfo{}, false, nil
	}

	res := make([]ProjectInDb, 0, count)

	if err := json.Unmarshal(data, &res); err != nil {
		return UserInfo{}, false, err
	}

	if len(res) > 0 {
		return res[0].UserInfo, count >= 1, nil
	}

	return UserInfo{}, count >= 1, nil
}

func CheckTaskExist(userId, taskId, taskType string) (bool, error) {

	_, count, err := client.From("tasks").Select("*", "exact", false).Eq("user_id", userId).Eq("task_id", taskId).Eq("task_type", taskType).Eq("stop", "false").Execute()

	if err != nil {
		return false, err
	}

	return count >= 1, nil

}

func CheckFollowerTaskAndAccountCount() (bool, error) {

	fc, err := FollowerTaskCount()
	if err != nil {
		return false, err
	}

	ac, err := AvailableAccountCount()

	if err != nil {
		return false, err
	}

	return fc < ac, nil
}

func FollowerTaskCount() (int64, error) {

	_, count, err := client.From("tasks").Select("*", "exact", false).Eq("stop", "false").Execute()

	if err != nil {
		return 0, err
	}

	return count, nil

}

func AvailableAccountCount() (int64, error) {

	_, count, err := client.From("accounts").Select("*", "exact", false).Eq("available", "false").Execute()

	if err != nil {
		return 0, err
	}

	return count, nil
}

func QueryProjectByUserId(userId string) ([]ProjectInDb, bool, error) {

	data, count, err := client.From("project").Select("*", "exact", false).Eq("user_id", userId).Execute()

	if err != nil {
		return nil, false, err
	}

	res := make([]ProjectInDb, 0, count)

	if err := json.Unmarshal(data, &res); err != nil {
		return nil, false, err
	}

	return res, count >= 1, nil

}

func QueryProjectByUserIdAndName(userName, userId string) (bool, error) {

	_, count, err := client.From("project").Select("*", "exact", false).Eq("user_id", userId).Eq("username", userName).Execute()

	if err != nil {
		return false, err
	}

	return count >= 1, nil

}

func QueryAvailableProject() ([]ProjectInDb, error) {

	data, count, err := client.From("project").Select("*", "exact", false).Eq("available", "true").Execute()

	if err != nil {
		return nil, err
	}

	res := make([]ProjectInDb, 0, count)

	if err := json.Unmarshal(data, &res); err != nil {
		return nil, err
	}

	return res, nil

}
