package v1

import (
	"quyun/v2/app/errorx"
	"quyun/v2/app/http/v1/dto"
	"quyun/v2/app/requests"
	"quyun/v2/app/services"
	"quyun/v2/database/models"

	"github.com/gofiber/fiber/v3"
)

// @provider
type Tenant struct{}

// List creator contents
//
// @Router /t/:tenantCode/v1/creators/:id<int>/contents [get]
// @Summary List creator contents
// @Description List contents of a specific creator
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Creator User ID"
// @Param page query int false "Page"
// @Param limit query int false "Limit"
// @Success 200 {object} requests.Pager
// @Bind id path
// @Bind filter query
func (t *Tenant) ListContents(ctx fiber.Ctx, id int64, filter *dto.ContentListFilter) (*requests.Pager, error) {
	tenantID := getTenantID(ctx)
	if filter == nil {
		filter = &dto.ContentListFilter{}
	}
	if tenantID > 0 {
		filter.TenantID = &tenantID
	}
	filter.AuthorID = &id
	return services.Content.List(ctx, tenantID, filter)
}

// List tenants (search)
//
// @Router /t/:tenantCode/v1/tenants [get]
// @Summary List tenants
// @Description Search tenants
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param keyword query string false "Keyword"
// @Param page query int false "Page"
// @Param limit query int false "Limit"
// @Success 200 {object} requests.Pager
// @Bind filter query
func (t *Tenant) List(ctx fiber.Ctx, filter *dto.TenantListFilter) (*requests.Pager, error) {
	tenantID := getTenantID(ctx)
	return services.Tenant.List(ctx, tenantID, filter)
}

// Get tenant public profile
//
// @Router /t/:tenantCode/v1/tenants/:id<int> [get]
// @Summary Get tenant profile
// @Description Get tenant public profile
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Tenant ID"
// @Success 200 {object} dto.TenantProfile
// @Bind user local key(__ctx_user)
// @Bind id path
func (t *Tenant) Get(ctx fiber.Ctx, user *models.User, id int64) (*dto.TenantProfile, error) {
	uid := int64(0)
	if user != nil {
		uid = user.ID
	}
	tenantID := getTenantID(ctx)
	if tenantID > 0 && id != tenantID {
		return nil, errorx.ErrForbidden.WithMsg("租户不匹配")
	}
	return services.Tenant.GetPublicProfile(ctx, tenantID, uid)
}

// Follow a tenant
//
// @Router /t/:tenantCode/v1/tenants/:id<int>/follow [post]
// @Summary Follow tenant
// @Description Follow a tenant
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Tenant ID"
// @Success 200 {string} string "Followed"
// @Bind user local key(__ctx_user)
// @Bind id path
func (t *Tenant) Follow(ctx fiber.Ctx, user *models.User, id int64) error {
	tenantID := getTenantID(ctx)
	if tenantID > 0 && id != tenantID {
		return errorx.ErrForbidden.WithMsg("租户不匹配")
	}
	return services.Tenant.Follow(ctx, tenantID, user.ID)
}

// Unfollow a tenant
//
// @Router /t/:tenantCode/v1/tenants/:id<int>/follow [delete]
// @Summary Unfollow tenant
// @Description Unfollow a tenant
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Tenant ID"
// @Success 200 {string} string "Unfollowed"
// @Bind user local key(__ctx_user)
// @Bind id path
func (t *Tenant) Unfollow(ctx fiber.Ctx, user *models.User, id int64) error {
	tenantID := getTenantID(ctx)
	if tenantID > 0 && id != tenantID {
		return errorx.ErrForbidden.WithMsg("租户不匹配")
	}
	return services.Tenant.Unfollow(ctx, tenantID, user.ID)
}

// Apply to join a tenant
//
// @Router /t/:tenantCode/v1/tenants/:id<int>/join [post]
// @Summary Apply to join tenant
// @Description Submit join request for a tenant
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Tenant ID"
// @Param form body dto.TenantJoinApplyForm true "Join form"
// @Success 200 {string} string "Applied"
// @Bind id path
// @Bind form body
func (t *Tenant) ApplyJoin(ctx fiber.Ctx, id int64, form *dto.TenantJoinApplyForm) error {
	tenantID := getTenantID(ctx)
	if tenantID > 0 && id != tenantID {
		return errorx.ErrForbidden.WithMsg("租户不匹配")
	}
	userID := getUserID(ctx)
	return services.Tenant.ApplyJoin(ctx, id, userID, form)
}

// Cancel join request
//
// @Router /t/:tenantCode/v1/tenants/:id<int>/join [delete]
// @Summary Cancel join request
// @Description Cancel join request for a tenant
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Tenant ID"
// @Success 200 {string} string "Canceled"
// @Bind id path
func (t *Tenant) CancelJoin(ctx fiber.Ctx, id int64) error {
	tenantID := getTenantID(ctx)
	if tenantID > 0 && id != tenantID {
		return errorx.ErrForbidden.WithMsg("租户不匹配")
	}
	userID := getUserID(ctx)
	return services.Tenant.CancelJoin(ctx, id, userID)
}

// Accept tenant invite
//
// @Router /t/:tenantCode/v1/tenants/:id<int>/invites/accept [post]
// @Summary Accept tenant invite
// @Description Accept a tenant invite by code
// @Tags TenantPublic
// @Accept json
// @Produce json
// @Param id path int64 true "Tenant ID"
// @Param form body dto.TenantInviteAcceptForm true "Invite form"
// @Success 200 {string} string "Accepted"
// @Bind id path
// @Bind form body
func (t *Tenant) AcceptInvite(ctx fiber.Ctx, id int64, form *dto.TenantInviteAcceptForm) error {
	tenantID := getTenantID(ctx)
	if tenantID > 0 && id != tenantID {
		return errorx.ErrForbidden.WithMsg("租户不匹配")
	}
	userID := getUserID(ctx)
	return services.Tenant.AcceptInvite(ctx, id, userID, form)
}
