package web

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

	"git.iioio.com/freefire/jiang13-forum/models"
	"git.iioio.com/freefire/jiang13-forum/modules/webctx"
	"git.iioio.com/freefire/jiang13-forum/services"
	"github.com/gin-gonic/gin"
)

type adminFriendLinkBrandRow struct {
	Name string
	URL  string
	Logo string
}

type adminFriendLinkApplyRow struct {
	ID          uint
	UserID      uint
	Username    string
	Name        string
	URL         string
	Logo        string
	Status      string
	StatusLabel string
	OnHome      bool
	Reciprocal  string
	RecipOK     bool
	RecipNote   string
	CreatedAt   string
	CanReview   bool
}

type adminFriendLinksData struct {
	AdminChrome
	BrandLinks      []adminFriendLinkBrandRow
	Applies         []adminFriendLinkApplyRow
	PendingCount    int64
	NavShow         bool
	FooterShow      bool
	AsideShow       bool
	ReciprocalCheck bool
	BrandName       string
	BrandURL        string
	BrandLogo       string
}

// AdminFriendLinksGet 友链管理
func (d Deps) AdminFriendLinksGet(c *gin.Context) {
	ctx := d.ctx(c)
	d.renderAdminFriendLinks(ctx, "")
}

func (d Deps) renderAdminFriendLinks(ctx *webctx.Context, errMsg string) {
	chrome := d.adminChrome(ctx, "友链", "friend-links")
	chrome.Error = errMsg
	data := adminFriendLinksData{
		AdminChrome:     chrome,
		NavShow:         d.Settings.NavShowFriendLinks(),
		FooterShow:      d.Settings.FooterShowFriendLinks(),
		AsideShow:       d.Settings.AsideShowFriendLinks(),
		ReciprocalCheck: d.Settings.FriendLinkReciprocalCheckEnabled(),
	}
	brand := d.Settings.SiteBranding()
	for _, l := range brand.FriendLinks {
		data.BrandLinks = append(data.BrandLinks, adminFriendLinkBrandRow{Name: l.Name, URL: l.URL, Logo: l.Logo})
	}
	if d.FriendLink != nil {
		data.PendingCount, _ = d.FriendLink.PendingCount()
		rows, _, _ := d.FriendLink.ListAdmin(services.FriendLinkApplyListQuery{Page: 1, Size: 50, Status: "all"})
		data.Applies = make([]adminFriendLinkApplyRow, 0, len(rows))
		for _, a := range rows {
			uname := ""
			if a.User.ID > 0 {
				uname = a.User.Username
			}
			data.Applies = append(data.Applies, adminFriendLinkApplyRow{
				ID:          a.ID,
				UserID:      a.UserID,
				Username:    uname,
				Name:        a.Name,
				URL:         a.URL,
				Logo:        a.Logo,
				Status:      a.Status,
				StatusLabel: friendLinkApplyStatusLabel(a.Status),
				OnHome:      a.LinkOnHomepage,
				Reciprocal:  a.ReciprocalPageURL,
				RecipOK:     a.ReciprocalVerified,
				RecipNote:   a.ReciprocalCheckNote,
				CreatedAt:   a.CreatedAt.Format("2006-01-02 15:04"),
				CanReview:   a.Status == models.FriendLinkApplyStatusPending,
			})
		}
	}
	ctx.HTML(http.StatusOK, "admin/friend_links", data)
}

// AdminFriendLinksSettingsPost nav/footer/回链开关
func (d Deps) AdminFriendLinksSettingsPost(c *gin.Context) {
	ctx := d.ctx(c)
	if !ctx.CheckCSRF() {
		d.renderAdminFriendLinks(ctx, "无效请求，请重试")
		return
	}
	_ = d.Settings.SetNavShowFriendLinks(c.PostForm("nav_show") == "1" || c.PostForm("nav_show") == "on")
	_ = d.Settings.SetFooterShowFriendLinks(c.PostForm("footer_show") == "1" || c.PostForm("footer_show") == "on")
	_ = d.Settings.SetAsideFriendLinksEnabled(c.PostForm("aside_show") == "1" || c.PostForm("aside_show") == "on")
	_ = d.Settings.SetFriendLinkReciprocalCheckEnabled(c.PostForm("reciprocal_check") == "1" || c.PostForm("reciprocal_check") == "on")
	ctx.SetFlash("友链入口设置已保存")
	ctx.Redirect("/admin/friend-links")
}

// AdminFriendLinksBrandAddPost 添加品牌友链
func (d Deps) AdminFriendLinksBrandAddPost(c *gin.Context) {
	ctx := d.ctx(c)
	name := strings.TrimSpace(c.PostForm("name"))
	url := strings.TrimSpace(c.PostForm("url"))
	logo := strings.TrimSpace(c.PostForm("logo"))
	if !ctx.CheckCSRF() {
		d.renderAdminFriendLinks(ctx, "无效请求，请重试")
		return
	}
	brand := d.Settings.SiteBranding()
	next := append([]services.FriendLink{}, brand.FriendLinks...)
	next = append(next, services.FriendLink{Name: name, URL: url, Logo: logo})
	if err := d.Settings.UpdateSiteBranding(services.SiteBranding{
		Name: brand.Name, Slogan: brand.Slogan, Description: brand.Description,
		Keywords: brand.Keywords, LogoMark: brand.LogoMark, Logo: brand.Logo,
		Favicon: brand.Favicon, OGImage: brand.OGImage,
		ICPBeian: brand.ICPBeian, ICPBeianURL: brand.ICPBeianURL,
		FriendLinks: next,
	}); err != nil {
		d.renderAdminFriendLinks(ctx, err.Error())
		return
	}
	ctx.SetFlash("已添加品牌友链")
	ctx.Redirect("/admin/friend-links")
}

// AdminFriendLinksBrandDeletePost 删除品牌友链（按 URL）
func (d Deps) AdminFriendLinksBrandDeletePost(c *gin.Context) {
	ctx := d.ctx(c)
	if !ctx.CheckCSRF() {
		d.renderAdminFriendLinks(ctx, "无效请求，请重试")
		return
	}
	target := strings.TrimSpace(c.PostForm("url"))
	brand := d.Settings.SiteBranding()
	next := make([]services.FriendLink, 0, len(brand.FriendLinks))
	for _, l := range brand.FriendLinks {
		if l.URL == target {
			continue
		}
		next = append(next, l)
	}
	if err := d.Settings.UpdateSiteBranding(services.SiteBranding{
		Name: brand.Name, Slogan: brand.Slogan, Description: brand.Description,
		Keywords: brand.Keywords, LogoMark: brand.LogoMark, Logo: brand.Logo,
		Favicon: brand.Favicon, OGImage: brand.OGImage,
		ICPBeian: brand.ICPBeian, ICPBeianURL: brand.ICPBeianURL,
		FriendLinks: next,
	}); err != nil {
		d.renderAdminFriendLinks(ctx, err.Error())
		return
	}
	ctx.SetFlash("已删除品牌友链")
	ctx.Redirect("/admin/friend-links")
}

// AdminFriendLinkApprovePost 通过申请
func (d Deps) AdminFriendLinkApprovePost(c *gin.Context) {
	ctx := d.ctx(c)
	if !ctx.CheckCSRF() {
		d.renderAdminFriendLinks(ctx, "无效请求，请重试")
		return
	}
	if d.FriendLink == nil {
		d.renderAdminFriendLinks(ctx, "友链服务未就绪")
		return
	}
	id64, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	if _, err := d.FriendLink.Approve(uint(id64)); err != nil {
		d.renderAdminFriendLinks(ctx, err.Error())
		return
	}
	ctx.SetFlash("已通过友链申请")
	ctx.Redirect("/admin/friend-links")
}

// AdminFriendLinkRejectPost 拒绝申请
func (d Deps) AdminFriendLinkRejectPost(c *gin.Context) {
	ctx := d.ctx(c)
	if !ctx.CheckCSRF() {
		d.renderAdminFriendLinks(ctx, "无效请求，请重试")
		return
	}
	if d.FriendLink == nil {
		d.renderAdminFriendLinks(ctx, "友链服务未就绪")
		return
	}
	id64, _ := strconv.ParseUint(c.Param("id"), 10, 64)
	note := strings.TrimSpace(c.PostForm("note"))
	if _, err := d.FriendLink.Reject(uint(id64), note); err != nil {
		d.renderAdminFriendLinks(ctx, err.Error())
		return
	}
	ctx.SetFlash("已拒绝友链申请")
	ctx.Redirect("/admin/friend-links")
}
