package report

import (
	"encoding/json"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/log"
	"go.uber.org/zap"
	"gorm.io/gorm"

	"github.com/pingcap-inc/clinic/pkg/api/common"
	error2 "github.com/pingcap-inc/clinic/pkg/api/error"
	"github.com/pingcap-inc/clinic/pkg/db"
	"github.com/pingcap-inc/clinic/pkg/db/model"
	"github.com/pingcap-inc/clinic/pkg/rbac"
)

type ReportService struct {
	rbac *rbac.AuthCasbin
}

func NewReportService(rbac *rbac.AuthCasbin) *ReportService {
	return &ReportService{
		rbac: rbac,
	}
}

func (rs *ReportService) PutReport(c *gin.Context) {
	rid := c.Param("rid")
	if rid == "" {
		_ = c.Error(error2.ErrBadRequest.New("empty rid"))
		return
	}

	req := PutReportRequest{}
	err := c.BindJSON(&req)
	if err != nil {
		_ = c.Error(error2.ErrBadRequest.New("bad parameter"))
		return
	}

	resultJSON, err := json.Marshal(req.Result)
	if err != nil {
		_ = c.Error(error2.ErrBadRequest.New("invalid result"))
		return
	}

	err = model.UpdateReport(&db.Report{
		UUID:     rid,
		Status:   req.Status,
		Progress: req.Progress,
		Result:   string(resultJSON),
	})
	if err == gorm.ErrRecordNotFound {
		_ = c.Error(error2.ErrNotFound.New("report not exist"))
		return
	}
	if err != nil {
		log.Error("put report failed", zap.Error(err))
		_ = c.Error(error2.ErrInternal.New("db connection failed"))
		return
	}

	c.JSON(http.StatusOK, common.SuccessResponse())
}

type PutReportRequest struct {
	Status   string `json:"status"`
	Progress uint   `json:"progress"`
	Result   any    `json:"data"`
}
