package opsapi

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/observability/pkg/common/message"
	"github.com/tidbcloud/observability/pkg/opsservice"
	"github.com/tidbcloud/observability/pkg/regionalapi/apiinterceptor"
)

// CreateHelmRelease
// @Summary create a HelmRelease CR
// @Description Creates a new HelmRelease custom resource in the specified namespace
// @Tags helmrelease
// @Accept json
// @Produce json
// @Param request body message.CreateHelmReleaseReq true "create HelmRelease request"
// @Success 202 {object} message.Result{data=message.CreateHelmReleaseResp}
// @Failure 400 {object} message.Result
// @Failure 409 {object} message.Result
// @Failure 500 {object} message.Result
// @Router /helmreleases [post]
func CreateHelmRelease(c *gin.Context) {
	req := &message.CreateHelmReleaseReq{}
	if ok := apiinterceptor.HandleJsonRequestFromBody(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().CreateHelmRelease(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusAccepted, resp)
		}
	}
}

// ListHelmReleases
// @Summary List HelmRelease CRs
// @Description Lists all HelmRelease custom resources, optionally filtered by namespace
// @Tags helmrelease
// @Accept json
// @Produce json
// @Param namespace query string false "namespace to filter by"
// @Param request query message.ListHelmReleasesReq true "list HelmReleases request"
// @Success 200 {object} message.Result{data=message.ListHelmReleasesResp}
// @Failure 500 {object} message.Result
// @Router /helmreleases [get]
func ListHelmReleases(c *gin.Context) {
	req := &message.ListHelmReleasesReq{}
	if ok := apiinterceptor.HandleJsonRequestFromQuery(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().ListHelmReleases(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusOK, resp)
		}
	}
}

// DiffHelmRelease
// @Summary diff a HelmRelease desired state
// @Description Compares requested HelmRelease desired state with live state and returns drift/adoption guard information
// @Tags helmrelease
// @Accept json
// @Produce json
// @Param request body message.DiffHelmReleaseReq true "diff HelmRelease request"
// @Success 200 {object} message.Result{data=message.DiffHelmReleaseResp}
// @Failure 400 {object} message.Result
// @Failure 500 {object} message.Result
// @Router /helmreleases/diff [post]
func DiffHelmRelease(c *gin.Context) {
	req := &message.DiffHelmReleaseReq{}
	if ok := apiinterceptor.HandleJsonRequestFromBody(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().DiffHelmRelease(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusOK, resp)
		}
	}
}

// GetHelmRelease
// @Summary get HelmRelease CR details
// @Description Retrieves the details of a specific HelmRelease custom resource
// @Tags helmrelease
// @Accept json
// @Produce json
// @Param name path string true "HelmRelease name"
// @Success 200 {object} message.Result{data=message.GetHelmReleaseResp}
// @Failure 404 {object} message.Result
// @Failure 500 {object} message.Result
// @Router /helmreleases/{name} [get]
func GetHelmRelease(c *gin.Context) {
	req := &message.GetHelmReleaseReq{
		Name: c.Param("name"),
	}

	if ok := apiinterceptor.HandleJsonRequestFromQuery(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().GetHelmRelease(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusOK, resp)
		}
	}
}

// UpdateHelmRelease
// @Summary update HelmRelease CR
// @Description Updates the configuration of an existing HelmRelease custom resource
// @Tags helmrelease
// @Accept json
// @Produce json
// @Param name path string true "HelmRelease name"
// @Param request body message.UpdateHelmReleaseReq true "update HelmRelease request"
// @Success 202 {object} message.Result{data=message.UpdateHelmReleaseResp}
// @Failure 400 {object} message.Result
// @Failure 404 {object} message.Result
// @Failure 500 {object} message.Result
// @Router /helmreleases/{name} [put]
func UpdateHelmRelease(c *gin.Context) {
	req := &message.UpdateHelmReleaseReq{
		Name: c.Param("name"),
	}

	if ok := apiinterceptor.HandleJsonRequestFromBody(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().UpdateHelmRelease(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusAccepted, resp)
		}
	}
}

// DeleteHelmRelease
// @Summary delete HelmRelease CR
// @Description Deletes a HelmRelease custom resource and triggers the associated Helm uninstall
// @Tags helmrelease
// @Accept json
// @Produce json
// @Param namespace path string true "HelmRelease namespace"
// @Param name path string true "HelmRelease name"
// @Success 202 {object} message.Result{data=message.DeleteHelmReleaseResp}
// @Failure 404 {object} message.Result
// @Failure 500 {object} message.Result
// @Router /helmreleases/{name} [delete]
func DeleteHelmRelease(c *gin.Context) {
	req := &message.DeleteHelmReleaseReq{
		Name: c.Param("name"),
	}

	if ok := apiinterceptor.HandleJsonRequestFromQuery(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().DeleteHelmRelease(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusAccepted, resp)
		}
	}
}

// UpdateBasicAuth
// @Summary update basic auth credentials for alertmanager and kube-prometheus-stack
// @Description Updates basic auth credentials for both alertmanager and kube-prometheus-stack HelmReleases using fail-fast approach
// @Tags ops
// @Accept json
// @Produce json
// @Param request body message.UpdateBasicAuthReq true "update basic auth request"
// @Success 200 {object} message.Result{data=message.UpdateBasicAuthResp} "Basic auth credentials updated successfully"
// @Failure 500 {object} message.Result "Basic auth update failed (30004)"
// @Router /alert-auth [put]
func UpdateBasicAuth(c *gin.Context) {
	req := &message.UpdateBasicAuthReq{}
	if ok := apiinterceptor.HandleJsonRequestFromBody(c, req); ok {
		resp, err := opsservice.GetHelmReleaseService().UpdateBasicAuth(c, *req)
		if err != nil {
			apiinterceptor.Fail(c, err)
		} else {
			apiinterceptor.Succeed(c, http.StatusOK, resp)
		}
	}
}
