package appconfig

import (
	"fmt"
	"strconv"
	"strings"

	"hyapp-admin-server/internal/appctx"
	"hyapp-admin-server/internal/modules/shared"
	"hyapp-admin-server/internal/repository"
	"hyapp-admin-server/internal/response"

	"github.com/gin-gonic/gin"
)

type Handler struct {
	service *AppConfigService
	audit   shared.OperationLogger
}

func New(store *repository.Store, audit shared.OperationLogger) *Handler {
	return &Handler{service: NewService(store), audit: audit}
}

func (h *Handler) ListH5Links(c *gin.Context) {
	items, err := h.service.ListH5Links()
	if err != nil {
		response.ServerError(c, "获取 H5 配置失败")
		return
	}
	response.OK(c, gin.H{"items": items, "total": len(items)})
}

func (h *Handler) UpdateH5Links(c *gin.Context) {
	var request updateH5LinksRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		response.BadRequest(c, "参数不正确")
		return
	}

	items, err := h.service.UpdateH5Links(request)
	if err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "update-app-h5-links", "admin_app_configs", "success", fmt.Sprintf("%d h5 links", len(request.Items)))
	response.OK(c, gin.H{"items": items, "total": len(items)})
}

func (h *Handler) ListBanners(c *gin.Context) {
	options := shared.ListOptions(c)
	items, err := h.service.ListBanners(appctx.FromContext(c.Request.Context()), repository.AppBannerListOptions{
		Keyword:  options.Keyword,
		Status:   options.Status,
		Platform: strings.TrimSpace(c.Query("platform")),
		RegionID: parseOptionalInt64(c.Query("regionId"), c.Query("region_id")),
		Country:  firstQuery(c, "countryCode", "country_code", "country"),
	})
	if err != nil {
		response.ServerError(c, "获取 BANNER 配置失败")
		return
	}
	response.OK(c, gin.H{"items": items, "total": len(items)})
}

func (h *Handler) CreateBanner(c *gin.Context) {
	var request bannerRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		response.BadRequest(c, "参数不正确")
		return
	}
	item, err := h.service.CreateBanner(appctx.FromContext(c.Request.Context()), request)
	if err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "create-app-banner", "admin_app_banners", "success", fmt.Sprintf("banner_id=%d", item.ID))
	response.Created(c, item)
}

func (h *Handler) UpdateBanner(c *gin.Context) {
	id, ok := bannerID(c)
	if !ok {
		return
	}
	var request bannerRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		response.BadRequest(c, "参数不正确")
		return
	}
	item, err := h.service.UpdateBanner(appctx.FromContext(c.Request.Context()), id, request)
	if err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "update-app-banner", "admin_app_banners", "success", fmt.Sprintf("banner_id=%d", item.ID))
	response.OK(c, item)
}

func (h *Handler) DeleteBanner(c *gin.Context) {
	id, ok := bannerID(c)
	if !ok {
		return
	}
	if err := h.service.DeleteBanner(appctx.FromContext(c.Request.Context()), id); err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "delete-app-banner", "admin_app_banners", "success", fmt.Sprintf("banner_id=%d", id))
	response.OK(c, gin.H{"deleted": true})
}

func (h *Handler) ListAppVersions(c *gin.Context) {
	items, err := h.service.ListAppVersions(appctx.FromContext(c.Request.Context()), repository.AppVersionListOptions{
		Keyword:  strings.TrimSpace(c.Query("keyword")),
		Platform: strings.TrimSpace(c.Query("platform")),
	})
	if err != nil {
		response.ServerError(c, "获取版本配置失败")
		return
	}
	response.OK(c, gin.H{"items": items, "total": len(items)})
}

func (h *Handler) CreateAppVersion(c *gin.Context) {
	var request appVersionRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		response.BadRequest(c, "参数不正确")
		return
	}
	item, err := h.service.CreateAppVersion(appctx.FromContext(c.Request.Context()), request)
	if err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "create-app-version", "admin_app_versions", "success", fmt.Sprintf("version_id=%d", item.ID))
	response.Created(c, item)
}

func (h *Handler) UpdateAppVersion(c *gin.Context) {
	id, ok := appVersionID(c)
	if !ok {
		return
	}
	var request appVersionRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		response.BadRequest(c, "参数不正确")
		return
	}
	item, err := h.service.UpdateAppVersion(appctx.FromContext(c.Request.Context()), id, request)
	if err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "update-app-version", "admin_app_versions", "success", fmt.Sprintf("version_id=%d", item.ID))
	response.OK(c, item)
}

func (h *Handler) DeleteAppVersion(c *gin.Context) {
	id, ok := appVersionID(c)
	if !ok {
		return
	}
	if err := h.service.DeleteAppVersion(appctx.FromContext(c.Request.Context()), id); err != nil {
		response.BadRequest(c, err.Error())
		return
	}
	shared.OperationLog(c, h.audit, "delete-app-version", "admin_app_versions", "success", fmt.Sprintf("version_id=%d", id))
	response.OK(c, gin.H{"deleted": true})
}

func bannerID(c *gin.Context) (uint, bool) {
	value, err := strconv.ParseUint(c.Param("banner_id"), 10, 64)
	if err != nil || value == 0 {
		response.BadRequest(c, "banner id is invalid")
		return 0, false
	}
	return uint(value), true
}

func appVersionID(c *gin.Context) (uint, bool) {
	value, err := strconv.ParseUint(c.Param("version_id"), 10, 64)
	if err != nil || value == 0 {
		response.BadRequest(c, "version id is invalid")
		return 0, false
	}
	return uint(value), true
}

func parseOptionalInt64(values ...string) int64 {
	for _, value := range values {
		value = strings.TrimSpace(value)
		if value == "" {
			continue
		}
		parsed, err := strconv.ParseInt(value, 10, 64)
		if err == nil && parsed > 0 {
			return parsed
		}
	}
	return 0
}

func firstQuery(c *gin.Context, keys ...string) string {
	for _, key := range keys {
		if value := c.Query(key); value != "" {
			return value
		}
	}
	return ""
}
