package handler

import (
	"errors"
	"net/http"
	"net/url"
	"strings"

	"github.com/gin-gonic/gin"

	"git.iioio.com/freefire/jiang13-forum/service"
)

// APICommunityHeartbeat 公开心跳入口（仅枢纽开启时写入）
func (h *Handlers) APICommunityHeartbeat(c *gin.Context) {
	if h.Community == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "未启用"})
		return
	}
	var req service.CommunityHeartbeatPayload
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	if err := h.Community.ReceiveHeartbeat(req, c.ClientIP(), requestOrigin(c)); err != nil {
		if errors.Is(err, service.ErrCommunityHubDisabled) {
			c.JSON(http.StatusForbidden, gin.H{"error": "本站未开启社区枢纽"})
			return
		}
		if errors.Is(err, service.ErrCommunityBadPayload) {
			c.JSON(http.StatusBadRequest, gin.H{"error": "心跳参数无效"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"ok": true})
}

// APICommunityShowcase 公开展柜（仅精选）
func (h *Handlers) APICommunityShowcase(c *gin.Context) {
	if h.Community == nil {
		c.JSON(http.StatusOK, gin.H{"items": []any{}})
		return
	}
	list, err := h.Community.ListShowcase(requestOrigin(c))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "加载失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{"items": list})
}

// APIAdminCommunityInstances 公网实例列表
func (h *Handlers) APIAdminCommunityInstances(c *gin.Context) {
	if h.Community == nil {
		c.JSON(http.StatusOK, gin.H{"instances": []any{}, "hub_enabled": false})
		return
	}
	cfg := h.Settings.CommunityConfigForRequest(communityRequestOrigin(c))
	list, err := h.Community.ListInstances()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "加载失败"})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"hub_enabled": cfg.HubEnabled,
		"instances":   list,
	})
}

// APIAdminFeatureCommunityInstance 精选 / 取消精选
func (h *Handlers) APIAdminFeatureCommunityInstance(c *gin.Context) {
	if h.Community == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "未启用"})
		return
	}
	var req service.CommunityFeatureInput
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	view, err := h.Community.SetInstanceFeatured(c.Param("id"), req)
	if err != nil {
		if errors.Is(err, service.ErrCommunityBadPayload) {
			c.JSON(http.StatusBadRequest, gin.H{"error": "实例无效"})
			return
		}
		c.JSON(http.StatusNotFound, gin.H{"error": "实例不存在"})
		return
	}
	msg := "已取消精选"
	if view.Featured {
		msg = "已设为精选，将出现在公开展柜"
	}
	c.JSON(http.StatusOK, gin.H{"message": msg, "instance": view})
}

// APIAdminUpdateCommunitySettings 更新社区上报设置
func (h *Handlers) APIAdminUpdateCommunitySettings(c *gin.Context) {
	var req service.CommunityConfig
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	_, err := h.Settings.UpdateCommunityConfig(req)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	origin := communityRequestOrigin(c)
	cfg := h.Settings.CommunityConfigForRequest(origin)
	out := gin.H{
		"message":   "社区设置已保存",
		"community": cfg,
	}
	if cfg.ReportEnabled && !cfg.HubEnabled && h.Community != nil {
		if err := h.Community.SendHeartbeatOnce(origin); err != nil {
			out["message"] = "社区设置已保存，但心跳未成功"
			out["heartbeat_error"] = err.Error()
			// 刷新 site_url（可能已由 Origin 持久化）
			out["community"] = h.Settings.CommunityConfigForRequest(origin)
		}
	}
	c.JSON(http.StatusOK, out)
}

// APIAdminUpdateShowcaseEntry 更新开源展柜入口展示位置（左栏 / 右栏 / 页脚）
func (h *Handlers) APIAdminUpdateShowcaseEntry(c *gin.Context) {
	var req struct {
		NavShowShowcase    *bool `json:"nav_show_showcase"`
		FooterShowShowcase *bool `json:"footer_show_showcase"`
		AsideShowShowcase  *bool `json:"aside_show_showcase"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	if req.NavShowShowcase == nil && req.FooterShowShowcase == nil && req.AsideShowShowcase == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	if req.NavShowShowcase != nil {
		if err := h.Settings.SetNavShowShowcase(*req.NavShowShowcase); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	if req.FooterShowShowcase != nil {
		if err := h.Settings.SetFooterShowShowcase(*req.FooterShowShowcase); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	if req.AsideShowShowcase != nil {
		if err := h.Settings.SetAsideShowcaseEnabled(*req.AsideShowShowcase); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"message":              "展柜入口已保存",
		"nav_show_showcase":    h.Settings.NavShowShowcase(),
		"footer_show_showcase": h.Settings.FooterShowShowcase(),
		"aside_show_showcase":  h.Settings.AsideShowShowcase(),
	})
}

// communityRequestOrigin 优先用浏览器 Origin（Vite 代理时 Host 可能是后端端口）
func communityRequestOrigin(c *gin.Context) string {
	if o := strings.TrimSpace(c.GetHeader("Origin")); o != "" {
		return o
	}
	if ref := strings.TrimSpace(c.GetHeader("Referer")); ref != "" {
		if u, err := url.Parse(ref); err == nil && u.Scheme != "" && u.Host != "" {
			return u.Scheme + "://" + u.Host
		}
	}
	return requestOrigin(c)
}
