package appapi

import (
	"context"
	"io"
	"net/http"

	"hyapp/services/gateway-service/internal/appconfig"
	"hyapp/services/gateway-service/internal/client"
)

// ConfigReader 是 gateway 对后台 App 配置的只读依赖。
type ConfigReader interface {
	ListH5Links(ctx context.Context, query appconfig.H5LinkQuery) ([]appconfig.H5Link, error)
	ListExploreTabs(ctx context.Context, appCode string) ([]appconfig.ExploreTab, error)
	ListBanners(ctx context.Context, query appconfig.BannerQuery) ([]appconfig.Banner, error)
	ListSplashScreens(ctx context.Context, query appconfig.SplashScreenQuery) ([]appconfig.SplashScreen, error)
	ListPopups(ctx context.Context, query appconfig.PopupQuery) ([]appconfig.Popup, error)
	LatestVersion(ctx context.Context, query appconfig.VersionQuery) (appconfig.Version, error)
	RoomRegionWhitelistAllows(ctx context.Context, appCode string, userID int64) (bool, error)
}

// ObjectUploader 是 gateway 上传接口依赖的对象存储最小能力。
type ObjectUploader interface {
	PutObject(ctx context.Context, key string, reader io.Reader, sizeBytes int64, contentType string) (string, error)
}

// ObjectURLVerifier 验证上传返回 URL 确实属于当前 COS access_url 和指定对象键。
type ObjectURLVerifier interface {
	OwnsObjectURL(objectURL string, objectKey string) bool
}

// Handler owns app platform endpoints such as bootstrap, config, upload and device token binding.
// It does not own user identity or resource semantics; those remain in their owner services/packages.
type Handler struct {
	appConfigReader        ConfigReader
	userAuthClient         client.UserAuthClient
	userProfileClient      client.UserProfileClient
	userAvatarUploadClient client.UserAvatarUploadClient
	userDeviceClient       client.UserDeviceClient
	statisticsClient       client.StatisticsClient
	objectUploader         ObjectUploader
	objectURLVerifier      ObjectURLVerifier
}

type Config struct {
	AppConfigReader        ConfigReader
	UserAuthClient         client.UserAuthClient
	UserProfileClient      client.UserProfileClient
	UserAvatarUploadClient client.UserAvatarUploadClient
	UserDeviceClient       client.UserDeviceClient
	StatisticsClient       client.StatisticsClient
	ObjectUploader         ObjectUploader
}

func New(config Config) *Handler {
	objectURLVerifier, _ := config.ObjectUploader.(ObjectURLVerifier)
	return &Handler{
		appConfigReader:        config.AppConfigReader,
		userAuthClient:         config.UserAuthClient,
		userProfileClient:      config.UserProfileClient,
		userAvatarUploadClient: config.UserAvatarUploadClient,
		userDeviceClient:       config.UserDeviceClient,
		statisticsClient:       config.StatisticsClient,
		objectUploader:         config.ObjectUploader,
		objectURLVerifier:      objectURLVerifier,
	}
}

func (h *Handler) GetAppBootstrap(writer http.ResponseWriter, request *http.Request) {
	h.getAppBootstrap(writer, request)
}

func (h *Handler) ListH5Links(writer http.ResponseWriter, request *http.Request) {
	h.listH5Links(writer, request)
}

func (h *Handler) ListExploreTabs(writer http.ResponseWriter, request *http.Request) {
	h.listExploreTabs(writer, request)
}

func (h *Handler) ListAppBanners(writer http.ResponseWriter, request *http.Request) {
	h.listAppBanners(writer, request)
}

func (h *Handler) ListSplashScreens(writer http.ResponseWriter, request *http.Request) {
	h.listSplashScreens(writer, request)
}

func (h *Handler) ListPopups(writer http.ResponseWriter, request *http.Request) {
	h.listPopups(writer, request)
}

func (h *Handler) GetAppVersion(writer http.ResponseWriter, request *http.Request) {
	h.getAppVersion(writer, request)
}

func (h *Handler) UploadFile(writer http.ResponseWriter, request *http.Request) {
	h.uploadFile(writer, request)
}

func (h *Handler) UploadAvatar(writer http.ResponseWriter, request *http.Request) {
	h.uploadAvatar(writer, request)
}

func (h *Handler) UploadRegistrationAvatar(writer http.ResponseWriter, request *http.Request) {
	h.uploadRegistrationAvatar(writer, request)
}

func (h *Handler) UploadUserAvatar(writer http.ResponseWriter, request *http.Request) {
	h.uploadUserAvatar(writer, request)
}

func (h *Handler) ProxyEffectMedia(writer http.ResponseWriter, request *http.Request) {
	h.proxyEffectMedia(writer, request)
}

func (h *Handler) HandlePushToken(writer http.ResponseWriter, request *http.Request) {
	h.handlePushToken(writer, request)
}

func (h *Handler) AppHeartbeat(writer http.ResponseWriter, request *http.Request) {
	h.appHeartbeat(writer, request)
}

func (h *Handler) ReportAppEvents(writer http.ResponseWriter, request *http.Request) {
	h.reportAppEvents(writer, request)
}
