package tenant

import (
	"time"

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

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

// contentAdmin provides tenant-admin content management endpoints.
//
//	@provider
type contentAdmin struct{}

func requireTenantAdmin(tenantUser *models.TenantUser) error {
	if tenantUser == nil {
		return errorx.ErrPermissionDenied
	}
	if !tenantUser.Role.Contains(consts.TenantUserRoleTenantAdmin) {
		return errorx.ErrPermissionDenied
	}
	return nil
}

// create
//
//	@Summary	创建内容（草稿）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string					true	"Tenant Code"
//	@Param		form		body		dto.ContentCreateForm	true	"Form"
//	@Success	200			{object}	models.Content
//
//	@Router		/t/:tenantCode/v1/admin/contents [post]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		form body
func (*contentAdmin) create(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, form *dto.ContentCreateForm) (*models.Content, 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.contents.create")

	return services.Content.Create(ctx, tenant.ID, tenantUser.UserID, form)
}

// update
//
//	@Summary	更新内容（标题/描述/状态等）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string					true	"Tenant Code"
//	@Param		contentID	path		int64					true	"ContentID"
//	@Param		form		body		dto.ContentUpdateForm	true	"Form"
//	@Success	200			{object}	models.Content
//
//	@Router		/t/:tenantCode/v1/admin/contents/:contentID [patch]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		contentID path
//	@Bind		form body
func (*contentAdmin) update(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, contentID int64, form *dto.ContentUpdateForm) (*models.Content, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}

	log.WithFields(log.Fields{
		"tenant_id":  tenant.ID,
		"user_id":    tenantUser.UserID,
		"content_id": contentID,
	}).Info("tenant.admin.contents.update")

	return services.Content.Update(ctx, tenant.ID, tenantUser.UserID, contentID, form)
}

// upsertPrice
//
//	@Summary	设置内容价格与折扣
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string						true	"Tenant Code"
//	@Param		contentID	path		int64						true	"ContentID"
//	@Param		form		body		dto.ContentPriceUpsertForm	true	"Form"
//	@Success	200			{object}	models.ContentPrice
//
//	@Router		/t/:tenantCode/v1/admin/contents/:contentID/price [put]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		contentID path
//	@Bind		form body
func (*contentAdmin) upsertPrice(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, contentID int64, form *dto.ContentPriceUpsertForm) (*models.ContentPrice, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}

	log.WithFields(log.Fields{
		"tenant_id":  tenant.ID,
		"user_id":    tenantUser.UserID,
		"content_id": contentID,
	}).Info("tenant.admin.contents.upsert_price")

	return services.Content.UpsertPrice(ctx, tenant.ID, tenantUser.UserID, contentID, form)
}

// attachAsset
//
//	@Summary	绑定媒体资源到内容（main/cover/preview）
//	@Tags		Tenant
//	@Accept		json
//	@Produce	json
//	@Param		tenantCode	path		string						true	"Tenant Code"
//	@Param		contentID	path		int64						true	"ContentID"
//	@Param		form		body		dto.ContentAssetAttachForm	true	"Form"
//	@Success	200			{object}	models.ContentAsset
//
//	@Router		/t/:tenantCode/v1/admin/contents/:contentID/assets [post]
//	@Bind		tenant local key(tenant)
//	@Bind		tenantUser local key(tenant_user)
//	@Bind		contentID path
//	@Bind		form body
func (*contentAdmin) attachAsset(ctx fiber.Ctx, tenant *models.Tenant, tenantUser *models.TenantUser, contentID int64, form *dto.ContentAssetAttachForm) (*models.ContentAsset, error) {
	if err := requireTenantAdmin(tenantUser); err != nil {
		return nil, err
	}

	log.WithFields(log.Fields{
		"tenant_id":  tenant.ID,
		"user_id":    tenantUser.UserID,
		"content_id": contentID,
		"asset_id":   form.AssetID,
		"role":       form.Role,
	}).Info("tenant.admin.contents.attach_asset")

	role := form.Role
	if role == "" {
		role = consts.ContentAssetRoleMain
	}

	sort := int32(0)
	if form.Sort > 0 {
		sort = form.Sort
	}

	return services.Content.AttachAsset(ctx, tenant.ID, tenantUser.UserID, contentID, form.AssetID, role, sort, time.Now())
}
