package controllers

import (
	"ai_developer_admin/libs/odysseus"
	"ai_developer_admin/libs/postgres"
	"ai_developer_admin/libs/registry"
	"ai_developer_admin/models"
	"encoding/json"
	"fmt"
	"github.com/beego/beego/orm"
	"github.com/beego/beego/v2/core/logs"
	"net/http"
	"strconv"
)

type ExplorerController struct {
	MainController
}

func (server *ExplorerController) Statistics() {
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err := json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest)
	if err != nil {
		server.respond(models.NoRequestBody, err.Error())
		return
	}
	//if appRequest.WorkerAcc == "" {
	//	server.respond(models.MissingParameter, "Missing worker_acc parameter")
	//	return
	//}

	countQB, _ := orm.NewQueryBuilder("mysql")
	countQB.Select("count(*),sum(workload) AS workload").
		From("bills")
	sql := countQB.String()
	taskCount, err := postgres.QueryBills(sql)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}

	count := int64(0)
	workload := int64(0)
	if len(taskCount) > 0 {
		task := taskCount[0]
		count, _ = strconv.ParseInt(task.Count, 10, 64)
		workload, _ = strconv.ParseInt(task.Workload, 10, 64)
	}

	_, total, _ := registry.NodeManagersByPage(0, 10)

	responseData := struct {
		TotalWorkload int64 `json:"total_workload"`
		TotalTask     int64 `json:"total_task"`
		TotalCalls    int64 `json:"total_calls"`
		NodeNums      int   `json:"node_nums"`
	}{
		TotalWorkload: workload,
		TotalTask:     count,
		TotalCalls:    count,
		NodeNums:      total,
	}
	server.respond(http.StatusOK, "", responseData)
}

func (server *ExplorerController) AddressByIP() {
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	_ = json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest, string(body))
	if appRequest.Ips == nil || (appRequest.Ips != nil && len(appRequest.Ips) <= 0) {
		server.respond(models.MissingParameter, "Missing ips parameter")
		return
	}
}

func (server *ExplorerController) AllNode() {
	data, err := registry.NodeManagers()
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	server.respond(http.StatusOK, "", data)
}

func (server *ExplorerController) NodeByPage() {
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err := json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest, string(body))

	if appRequest.Page > 0 {
		appRequest.Page = appRequest.Page - 1
	}

	if appRequest.Size == 0 {
		appRequest.Size = 10
	}
	data, total, err := registry.NodeManagersByPage(int(appRequest.Size), int(appRequest.Page))
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	responseData := struct {
		Total int64       `json:"total"`
		Data  interface{} `json:"data,omitempty"`
	}{
		Total: int64(total),
		Data:  data,
	}
	server.respond(http.StatusOK, "", responseData)
}

func (server *ExplorerController) Tasks() {
	body := server.Ctx.Input.RequestBody
	appRequest := models.AppRequest{}
	err := json.Unmarshal(body, &appRequest) //解析body中数据
	logs.Debug("appRequest", appRequest, string(body))

	if appRequest.Page == 0 {
		appRequest.Page = 1
	}
	if appRequest.Size == 0 {
		appRequest.Size = 10
	}
	offset := (appRequest.Page - 1) * appRequest.Size
	size := appRequest.Page * appRequest.Size

	if appRequest.WorkerAcc == "" {
		server.respond(models.MissingParameter, "Missing worker_acc parameter")
		return
	}

	countQB, _ := orm.NewQueryBuilder("mysql")
	countQB.Select("count(*)").
		From("bills").Where(fmt.Sprintf("worker_acc = '%s'", appRequest.WorkerAcc))

	queryQB, _ := orm.NewQueryBuilder("mysql")
	queryQB.Select("id", "fee", "type", "time", "exec_duration", "workload", "profit_acc", "worker_acc", "result").
		From("bills").Where(fmt.Sprintf("worker_acc = '%s'", appRequest.WorkerAcc))

	sql := countQB.String()
	total, err := postgres.QueryTotal(sql)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}
	logs.Debug("total = %d", total)
	var responseTasks []models.Bills
	if total == 0 {
		responseData := struct {
			Total int64       `json:"total"`
			Data  interface{} `json:"data,omitempty"`
		}{
			Total: total,
			Data:  responseTasks,
		}
		server.respond(http.StatusOK, "", responseData)
		return
	}

	queryQB.OrderBy("time").Desc()
	sql = fmt.Sprintf("%s LIMIT %d,%d;", queryQB.String(), offset, size)
	data, err := postgres.QueryBills(sql)
	if err != nil {
		server.respond(models.BusinessFailed, err.Error())
		return
	}

	for _, task := range data {
		//apiPath := ""
		//model := ""
		baseModel := ""
		//kind := 1
		typeDe := 1
		taskId, err := strconv.Atoi(task.Type)
		if err == nil {
			taskType, _ := odysseus.GetTaskType(int64(taskId))
			if taskType != nil {
				//apiPath = taskType.ApiPath
				//model = taskType.Model
				baseModel = taskType.BaseModel
				//kind = taskType.Kind
				typeDe = taskType.Type
			}
		}

		reTask := models.Bills{
			Id:     task.Id,
			Type:   models.ModelType(typeDe).String(),
			Time:   task.Time,
			Result: task.Result,
			//ApiPath:   apiPath,
			//Model:     model,
			BaseModel: baseModel,
			//Kind:      models.TaskKind(kind).EnString(),
			//Desc:      desc,
			Workload:  task.Workload,
			ProfitAcc: task.ProfitAcc,
			//WorkerAcc: task.WorkerAcc,
		}
		responseTasks = append(responseTasks, reTask)
	}
	responseData := struct {
		Total int64       `json:"total"`
		Data  interface{} `json:"data,omitempty"`
	}{
		Total: total,
		Data:  responseTasks,
	}
	server.respond(http.StatusOK, "", responseData)
}
