package tenant

import (
	"time"

	"quyun/v2/app/errorx"
	"quyun/v2/app/http/tenant/dto"
	"quyun/v2/app/requests"
	"quyun/v2/app/services"
	"quyun/v2/database/models"

	"github.com/gofiber/fiber/v3"
	log "github.com/sirupsen/logrus"
)

// orderAdmin provides tenant-admin order management endpoints.
//
//	@provider
type orderAdmin struct{}

// adminOrderList
//
//	@Summary	订单列表（租户管理）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string					true	"Tenant Code"
//	@Param		filter		query		dto.AdminOrderListFilter	true	"Filter"
//	@Success	200			{object}	requests.Pager{items=models.Order}
//
//	@Router		/t/:tenantCode/v1/admin/orders [get]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		filter query
func (*orderAdmin) adminOrderList(
	ctx fiber.Ctx,
	tenant *models.Tenant,
	tenantUser *models.TenantUser,
	filter *dto.AdminOrderListFilter,
) (*requests.Pager, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}

	log.WithFields(log.Fields{
		"tenant_id": tenant.ID,
		"user_id":   tenantUser.UserID,
	}).Info("tenant.admin.orders.list")

	return services.Order.AdminOrderPage(ctx, tenant.ID, filter)
}

// adminOrderDetail
//
//	@Summary	订单详情（租户管理）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string	true	"Tenant Code"
//	@Param		orderID		path		int64	true	"OrderID"
//	@Success	200			{object}	dto.AdminOrderDetail
//
//	@Router		/t/:tenantCode/v1/admin/orders/:orderID [get]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		orderID path
func (*orderAdmin) adminOrderDetail(
	ctx fiber.Ctx,
	tenant *models.Tenant,
	tenantUser *models.TenantUser,
	orderID int64,
) (*dto.AdminOrderDetail, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}

	log.WithFields(log.Fields{
		"tenant_id": tenant.ID,
		"user_id":   tenantUser.UserID,
		"order_id":  orderID,
	}).Info("tenant.admin.orders.detail")

	m, err := services.Order.AdminOrderDetail(ctx, tenant.ID, orderID)
	if err != nil {
		return nil, err
	}
	return &dto.AdminOrderDetail{Order: m}, nil
}

// adminRefund
//
//	@Summary	订单退款（租户管理）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string					true	"Tenant Code"
//	@Param		orderID		path		int64					true	"OrderID"
//	@Param		form		body		dto.AdminOrderRefundForm	true	"Form"
//	@Success	200			{object}	models.Order
//
//	@Router		/t/:tenantCode/v1/admin/orders/:orderID/refund [post]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		orderID path
//	@Bind		form body
func (*orderAdmin) adminRefund(
	ctx fiber.Ctx,
	tenant *models.Tenant,
	tenantUser *models.TenantUser,
	orderID int64,
	form *dto.AdminOrderRefundForm,
) (*models.Order, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}
	if form == nil {
		return nil, errorx.ErrInvalidParameter
	}

	log.WithFields(log.Fields{
		"tenant_id":       tenant.ID,
		"user_id":         tenantUser.UserID,
		"order_id":        orderID,
		"force":           form.Force,
		"idempotency_key": form.IdempotencyKey,
	}).Info("tenant.admin.orders.refund")

	return services.Order.AdminRefundOrder(
		ctx,
		tenant.ID,
		tenantUser.UserID,
		orderID,
		form.Force,
		form.Reason,
		form.IdempotencyKey,
		time.Now(),
	)
}

// adminTopupUser
//
//	@Summary	为租户成员充值（租户管理）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string				true	"Tenant Code"
//	@Param		userID		path		int64				true	"UserID"
//	@Param		form		body		dto.AdminTopupForm	true	"Form"
//	@Success	200			{object}	models.Order
//
//	@Router		/t/:tenantCode/v1/admin/users/:userID/topup [post]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		userID path
//	@Bind		form body
func (*orderAdmin) adminTopupUser(
	ctx fiber.Ctx,
	tenant *models.Tenant,
	tenantUser *models.TenantUser,
	userID int64,
	form *dto.AdminTopupForm,
) (*models.Order, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}
	if form == nil {
		return nil, errorx.ErrInvalidParameter
	}

	log.WithFields(log.Fields{
		"tenant_id":       tenant.ID,
		"operator_user":   tenantUser.UserID,
		"target_user":     userID,
		"amount":          form.Amount,
		"idempotency_key": form.IdempotencyKey,
	}).Info("tenant.admin.users.topup")

	return services.Order.AdminTopupUser(
		ctx,
		tenant.ID,
		tenantUser.UserID,
		userID,
		form.Amount,
		form.IdempotencyKey,
		form.Reason,
		time.Now(),
	)
}
