package api

import (
	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/billing2/billing_errors"
	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/handler/novuhandler"
	"github.com/pingcap/dbaas/billing2/utils/ginutils"
	"github.com/pingcap/dbaas/billing2/utils/log"
	"github.com/pingcap/dbaas/billing2/utils/user"
	"go.uber.org/zap"
)

type NotificationRequest struct {
	TenantID  uint   `uri:"tenant_id" binding:"required"`
	QueryType string `uri:"query_type" binding:"required"`
	Page      int    `uri:"page" binding:"required"`
	PageSize  int    `uri:"page_size" binding:"required"`
}

// @Summary Get  Notifications
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param query_type path string true "query_type"
// @Param page path int true "page"
// @Param page_size path int true "page_size"
// @Success 200 {object} forms.Notifications
// @Router /tenants/{tenant_id}/notifications/{query_type}/page/{page}/page_size/{page_size} [GET]
func (s *API) GetNotificationsByUserID(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	httpRequest := &NotificationRequest{}
	err := c.ShouldBindUri(httpRequest)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	request := forms.NotificationRequest{}
	request.TenantID = httpRequest.TenantID
	request.UserID = user.GetCurrentUserID()
	request.Page = httpRequest.Page - 1
	request.PageSize = httpRequest.PageSize
	request.QueryType = httpRequest.QueryType

	log.Info("GetNotificationsByUserID", zap.Any("request", request), zap.Any("httpRequest", httpRequest))

	return novuhandler.Get().GetSubscriberInAppNotifications(request)

}

type NotificationMarkRequest struct {
	TenantID       uint   `uri:"tenant_id" binding:"required"`
	Type           string `uri:"type" binding:"required"`
	NotificationID string `uri:"notification_id" binding:"required"`
}

// @Summary Mark User Notifications As Seen
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param type path string true "type"
// @Param notification_id path string  true "notification_id"
// @Success 200 {object} forms.Notifications
// @Router /tenants/{tenant_id}/notifications/{type}/notification_id/{notification_id} [POST]
func (s *API) MarkUserNotificationsAsSeen(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	httpRequest := &NotificationMarkRequest{}

	err := c.ShouldBindUri(httpRequest)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	request := forms.NotificationMarkRequest{}
	request.UserID = user.GetCurrentUserID()
	request.TenantID = httpRequest.TenantID
	request.Type = httpRequest.Type
	request.NotificationID = httpRequest.NotificationID
	log.Info("MarkUserNotificationsAsSeen", zap.Any("request", request), zap.Any("httpRequest", httpRequest))
	return novuhandler.Get().MarkMessagesAsSeen(request)

}

type NotificationID struct {
	TenantID       uint   `uri:"tenant_id" binding:"required"`
	NotificationID string `uri:"notification_id" binding:"required"`
}

// @Summary Get Notifications by Notification_id
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param notification_id path string  true "notification_id"
// @Success 200 {object} forms.Notification
// @Router /tenants/{tenant_id}/notifications/notification_id/{notification_id} [GET]
func (s *API) GetNotificationByID(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	httpRequest := &NotificationID{}

	err := c.ShouldBindUri(httpRequest)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	request := forms.NotificationRequest{}
	request.TenantID = httpRequest.TenantID
	request.NotificationID = httpRequest.NotificationID
	request.UserID = user.GetCurrentUserID()

	log.Info("GetNotificationByID", zap.Any("request", request), zap.Any("httpRequest", httpRequest))
	return novuhandler.Get().GetSubscriberInAppNotificationByID(request)

}

// @Summary Mark User Notifications As Read
// @Schemes
// @Accept json
// @Produce json
// @Param tenant_id path string true "tenant_id"
// @Param notification_id path string  true "notification_id"
// @Success 200 {object} forms.Notifications
// @Router /tenants/{tenant_id}/notifications/notification_id/{notification_id} [POST]
func (s *API) MarkUserNotificationsAsRead(c *gin.Context) (ginutils.HandlerFuncResult, error) {
	request := &forms.NotificationRequest{}
	err := c.ShouldBindUri(request)
	if err != nil {
		return nil, billing_errors.NewInvalidInputError(err)
	}
	log.Info("MarkUserNotificationsAsRead", zap.Any("request", request))

	return forms.OK, nil

}

func InitializeNotificationsRouter(router ginutils.MyRoute) {
	api := &API{}
	router.HandleWithError("GET", "/tenants/:tenant_id/notifications/:query_type/page/:page/page_size/:page_size", api.GetNotificationsByUserID)
	router.HandleWithError("POST", "/tenants/:tenant_id/notifications/:type/notification_id/:notification_id", api.MarkUserNotificationsAsSeen)
	router.HandleWithError("POST", "/tenants/:tenant_id/notifications/notification_id/:notification_id", api.MarkUserNotificationsAsRead)
	router.HandleWithError("GET", "/tenants/:tenant_id/notifications/notification_id/:notification_id", api.GetNotificationByID)

}
