package handler

import (
	"fmt"
	"net/http"
	"strconv"
	"strings"

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

// APIApplyFriendLink 提交友情链接申请
func (h *Handlers) APIApplyFriendLink(c *gin.Context) {
	uid := h.currentUserID(c)
	if uid == 0 {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
		return
	}
	var req struct {
		Name              string `json:"name"`
		URL               string `json:"url"`
		Logo              string `json:"logo"`
		LinkOnHomepage    bool   `json:"link_on_homepage"`
		ReciprocalPageURL string `json:"reciprocal_page_url"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	result, err := h.FriendLinkApply.Create(service.FriendLinkApplyInput{
		UserID:            uid,
		Name:              req.Name,
		URL:               req.URL,
		Logo:              req.Logo,
		LinkOnHomepage:    req.LinkOnHomepage,
		ReciprocalPageURL: req.ReciprocalPageURL,
		OurSiteURL:        h.publicBaseURL(c),
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	resp := gin.H{
		"message": friendLinkApplySubmittedMessage(h.Settings.FriendLinkReciprocalCheckEnabled(), false),
		"apply":   result.Apply,
	}
	c.JSON(http.StatusOK, resp)
}

// APIUploadFriendLinkLogo 上传友链申请 LOGO
func (h *Handlers) APIUploadFriendLinkLogo(c *gin.Context) {
	uid := h.currentUserID(c)
	if uid == 0 {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
		return
	}
	file, err := c.FormFile("logo")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请选择 LOGO 图片"})
		return
	}
	maxBytes := int64(h.Settings.AvatarMaxMB()) * 1024 * 1024
	if file.Size > maxBytes {
		c.JSON(http.StatusBadRequest, gin.H{"error": "图片文件过大"})
		return
	}
	url, err := service.SaveUploadedImage(
		h.Store,
		file,
		service.UploadCategorySite,
		fmt.Sprintf("fl_%d", uid),
	)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "LOGO 已上传", "url": url})
}

// APIAdminFriendLinkApplies 管理员友链申请列表
func (h *Handlers) APIAdminFriendLinkApplies(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
	status := strings.TrimSpace(c.DefaultQuery("status", "pending"))
	list, total, err := h.FriendLinkApply.ListAdmin(service.FriendLinkApplyListQuery{
		Page: page, Size: size, Status: status,
	})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	pending, _ := h.FriendLinkApply.PendingCount()
	c.JSON(http.StatusOK, gin.H{
		"applies":                  list,
		"total":                    total,
		"page":                     page,
		"pending_count":            pending,
		"reciprocal_check_enabled": h.Settings.FriendLinkReciprocalCheckEnabled(),
	})
}

// APIAdminUpdateFriendLinkSettings 更新友链相关开关（回链检测 / 入口展示）
func (h *Handlers) APIAdminUpdateFriendLinkSettings(c *gin.Context) {
	var req struct {
		ReciprocalCheckEnabled *bool `json:"reciprocal_check_enabled"`
		NavShowFriendLinks     *bool `json:"nav_show_friend_links"`
		FooterShowFriendLinks  *bool `json:"footer_show_friend_links"`
		AsideShowFriendLinks   *bool `json:"aside_show_friend_links"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	if req.ReciprocalCheckEnabled == nil && req.NavShowFriendLinks == nil &&
		req.FooterShowFriendLinks == nil && req.AsideShowFriendLinks == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	if req.ReciprocalCheckEnabled != nil {
		if err := h.Settings.SetFriendLinkReciprocalCheckEnabled(*req.ReciprocalCheckEnabled); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	if req.NavShowFriendLinks != nil {
		if err := h.Settings.SetNavShowFriendLinks(*req.NavShowFriendLinks); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	if req.FooterShowFriendLinks != nil {
		if err := h.Settings.SetFooterShowFriendLinks(*req.FooterShowFriendLinks); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}
	if req.AsideShowFriendLinks != nil {
		if err := h.Settings.SetAsideFriendLinksEnabled(*req.AsideShowFriendLinks); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
	}

	msg := "设置已保存"
	if req.ReciprocalCheckEnabled != nil && req.NavShowFriendLinks == nil &&
		req.FooterShowFriendLinks == nil && req.AsideShowFriendLinks == nil {
		if *req.ReciprocalCheckEnabled {
			msg = "已开启回链检测"
		} else {
			msg = "已关闭回链检测"
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"message":                   msg,
		"reciprocal_check_enabled":  h.Settings.FriendLinkReciprocalCheckEnabled(),
		"nav_show_friend_links":     h.Settings.NavShowFriendLinks(),
		"footer_show_friend_links":  h.Settings.FooterShowFriendLinks(),
		"aside_show_friend_links":   h.Settings.AsideShowFriendLinks(),
	})
}

// APIAdminApproveFriendLinkApply 通过友链申请
func (h *Handlers) APIAdminApproveFriendLinkApply(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	apply, err := h.FriendLinkApply.Approve(uint(id))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "已通过并加入友情链接", "apply": apply})
}

// APIAdminRejectFriendLinkApply 拒绝友链申请
func (h *Handlers) APIAdminRejectFriendLinkApply(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	var req struct {
		Note string `json:"note"`
	}
	_ = c.ShouldBindJSON(&req)
	apply, err := h.FriendLinkApply.Reject(uint(id), req.Note)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "已拒绝申请", "apply": apply})
}

// APIMyFriendLinkApplies 当前用户的友链申请列表
func (h *Handlers) APIMyFriendLinkApplies(c *gin.Context) {
	uid := h.currentUserID(c)
	if uid == 0 {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
		return
	}
	list, err := h.FriendLinkApply.ListMine(uid)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"applies": list})
}

// APICancelFriendLinkApply 撤销待审友链申请
func (h *Handlers) APICancelFriendLinkApply(c *gin.Context) {
	uid := h.currentUserID(c)
	if uid == 0 {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
		return
	}
	id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	if err := h.FriendLinkApply.Cancel(uid, uint(id)); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "已撤销申请"})
}

// APIUpdateFriendLinkApply 修改并重新提交友链申请
func (h *Handlers) APIUpdateFriendLinkApply(c *gin.Context) {
	uid := h.currentUserID(c)
	if uid == 0 {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
		return
	}
	id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	var req struct {
		Name              string `json:"name"`
		URL               string `json:"url"`
		Logo              string `json:"logo"`
		LinkOnHomepage    bool   `json:"link_on_homepage"`
		ReciprocalPageURL string `json:"reciprocal_page_url"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}
	result, err := h.FriendLinkApply.Update(uid, uint(id), service.FriendLinkApplyInput{
		UserID:            uid,
		Name:              req.Name,
		URL:               req.URL,
		Logo:              req.Logo,
		LinkOnHomepage:    req.LinkOnHomepage,
		ReciprocalPageURL: req.ReciprocalPageURL,
		OurSiteURL:        h.publicBaseURL(c),
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	resp := gin.H{
		"message": friendLinkApplySubmittedMessage(h.Settings.FriendLinkReciprocalCheckEnabled(), true),
		"apply":   result.Apply,
	}
	c.JSON(http.StatusOK, resp)
}

// APIAdminRecheckFriendLinkApply 管理员重新检测回链
func (h *Handlers) APIAdminRecheckFriendLinkApply(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	apply, err := h.FriendLinkApply.RecheckReciprocal(uint(id), h.publicBaseURL(c))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "已开始重新检测回链", "apply": apply})
}

func friendLinkApplySubmittedMessage(checkEnabled, isUpdate bool) string {
	if isUpdate {
		if checkEnabled {
			return "申请已更新，回链检测将在后台进行"
		}
		return "申请已更新"
	}
	if checkEnabled {
		return "申请已提交，回链检测将在后台进行"
	}
	return "申请已提交"
}
