package controller

import (
	_const "chonho/const"
	"chonho/internal/api-v1/entity"
	"chonho/internal/api-v1/usecase/order_usecase"
	_error "chonho/pkg/c_error"
	"github.com/gin-gonic/gin"
)

type OrderController struct {
	Controller
	orderUseCase order_usecase.UseCase
}

func NewOrderController(orderUseCase order_usecase.UseCase) *OrderController {
	return &OrderController{
		orderUseCase: orderUseCase,
	}
}

// CreateOrder godoc
// @Summary Create order
// @Tags Order
// @ID order-create
// @Accept json
// @Produce json
// @Param json body entity.CreateOrderReq true "Order info"
// @Success 200 {object} entity.CreateOrderResponse
// @Failure 400 {object} entity.Response
// @Router /order [post]
// @Security BearerAuth
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (c *OrderController) CreateOrder(ctx *gin.Context) {
	var req entity.CreateOrderReq
	if valid := c.WrapBindAndValidate(ctx, &req); valid {
		res, err := c.orderUseCase.CreateOrder(c.GetLoggedUser(ctx).Id, req)
		c.WrapResponse(ctx, res, err)
	}
}

// RequestCancelOrder godoc
// @Summary Buyer request cancel an order
// @Tags Order
// @ID order-cancel
// @Accept json
// @Produce json
// @param id path int true "order id"
// @Success 200 {object} entity.Response
// @Failure 400 {object} entity.Response
// @Router /order/{id}/cancel [post]
// @Security BearerAuth
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (c *OrderController) RequestCancelOrder(ctx *gin.Context) {
	if orderID := c.WrapReadIDFromPath(ctx); orderID != 0 {
		err := c.orderUseCase.CancelOrder(c.GetLoggedUser(ctx).Id, orderID)
		c.WrapResponse(ctx, nil, err)
	}

}

// ProvePayment godoc
// @Summary Buyer send the payment proof
// @Tags Order
// @ID order-payment-proof
// @Accept json
// @Produce json
// @param id path int true "order id"
// @Param json body entity.ProvePaymentRequest true "Payment proof image url"
// @Success 200 {object} entity.Response
// @Failure 400 {object} entity.Response
// @Router /order/{id}/payment-proof [post]
// @Security BearerAuth
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (c *OrderController) ProvePayment(ctx *gin.Context) {
	if orderID := c.WrapReadIDFromPath(ctx); orderID != 0 {
		var req entity.ProvePaymentRequest
		if c.WrapBindAndValidate(ctx, &req) {
			err := c.orderUseCase.ProvePayment(c.GetLoggedUser(ctx).Id, orderID, req)
			c.WrapResponse(ctx, nil, err)
		}
	}

}

// GetOrder godoc
// @Summary Get order detail
// @Tags Order
// @ID order
// @Accept json
// @Produce json
// @Param id path int true "Order ID"
// @Success 200 {object} entity.GetBuyerOrderResponse
// @Failure 400 {object} entity.Response
// @Router /order/{id} [get]
// @Security BearerAuth
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (c *OrderController) GetOrder(ctx *gin.Context) {
	res, err := c.orderUseCase.GetBuyerOrder(c.GetLoggedUser(ctx).Id, c.GetParamIdInt64(ctx))
	c.WrapResponse(ctx, res, err)
}

// GetOrders godoc
// @Summary Get order list
// @Tags Order
// @ID order-list
// @Accept json
// @Produce json
// @Param status query int false "Order Status"
// @Param group_status query int true "Group order Status"
// @Success 200 {object} entity.GetBuyerOrdersResponse
// @Failure 400 {object} entity.Response
// @Router /order [get]
// @Security BearerAuth
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (c *OrderController) GetOrders(ctx *gin.Context) {
	groupStatus := c.GetQueryInt(ctx, "group_status")
	if groupStatus > 0 && groupStatus < 4 {
		res, err := c.orderUseCase.GetBuyerOrders(c.GetLoggedUser(ctx).Id, groupStatus)
		c.WrapResponse(ctx, res, err)
	} else {
		c.Failure(ctx, _error.New(_const.StatusBadRequest, "Invalid param"))
	}
}

// ConfirmReceived godoc
// @Summary buyer confirm the package received
// @Tags Order
// @ID order-confirm-received
// @Accept json
// @Produce json
// @Param id path int true "order id"
// @Success 200 {object} entity.Response
// @Failure 400 {object} entity.Response
// @Router /order/{id}/confirm-received [post]
// @Security BearerAuth
// @Security ApiVersion
// @Security AppVersion
// @Security AppPlatform
func (c *OrderController) ConfirmReceived(ctx *gin.Context) {
	// ConfirmOrderReceivedRequest used for trace purpose
	if orderId := c.WrapReadIDFromPath(ctx); orderId != 0 {
		err := c.orderUseCase.ConfirmReceived(c.GetLoggedUser(ctx).Id, orderId)
		c.WrapResponse(ctx, nil, err)
	}

}
