package controller

import (
	"io"
	"net/http"

	"metazone.cc/metalab/internal/common"
	"metazone.cc/metalab/internal/model"
	"metazone.cc/metalab/internal/session"

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

// profileProvider SettingsController 对 Service 层的最小依赖（ISP：4 个方法）
type profileProvider interface {
	GetProfile(userID uint) (*model.User, error)
	UpdateProfile(userID uint, username, bio string) error
	ChangePassword(userID uint, currentPassword, newPassword string) error
	DeleteAccount(userID uint, password, reason string) error
}

// avatarProvider 头像上传对 Service 层的最小依赖（ISP：2 个方法）
type avatarProvider interface {
	ProcessAvatar(userID uint, file io.Reader, contentType string, cropX, cropY, cropSize int) (string, error)
	ProcessImage(userID uint, file io.Reader, contentType string, cropX, cropY, cropSize int) (string, error)
}

// auditSubmittable 个人设置对审核服务的依赖（ISP：4 个方法）
type auditSubmittable interface {
	ShouldAudit(userID uint) (bool, error)
	SubmitProfileChanges(userID uint, currentUser *model.User, newUsername, newBio string) error
	Submit(userID uint, auditType, newValue string) error
	GetPendingTypes(userID uint) ([]string, error)
}

// SettingsController 个人设置控制器
type SettingsController struct {
	authService   profileProvider
	avatarService avatarProvider
	auditService  auditSubmittable
	sessionMgr    sessionManager
}

// NewSettingsController 构造函数
func NewSettingsController(authService profileProvider, avatarService avatarProvider, auditService auditSubmittable, sessionMgr sessionManager) *SettingsController {
	return &SettingsController{authService: authService, avatarService: avatarService, auditService: auditService, sessionMgr: sessionMgr}
}

// SettingsPage 个人设置页面（需登录）
func (sc *SettingsController) SettingsPage(c *gin.Context) {
	uidVal, exists := c.Get("uid")
	if !exists {
		c.Redirect(http.StatusFound, "/auth/login")
		c.Abort()
		return
	}
	uid := uidVal.(uint)

	tab := c.Param("tab")
	if tab != "profile" && tab != "account" && tab != "sessions" {
		c.String(http.StatusNotFound, "页面不存在")
		return
	}

	user, err := sc.authService.GetProfile(uid)
	if err != nil || user == nil {
		c.String(http.StatusNotFound, "用户不存在")
		return
	}

	// 查询待审核类型（用于前端显示审核提示）
	pendingTypes, _ := sc.auditService.GetPendingTypes(uid)

	data := gin.H{
		"Title":        "个人设置",
		"ExtraCSS":     "/static/css/settings.css",
		"ActiveTab":    tab,
		"User":         user,
		"RoleName":     model.RoleDisplayNames[user.Role],
		"StatusName":   model.StatusDisplayNames[user.Status],
		"PendingTypes": pendingTypes,
		"AuditTypes":   model.AuditTypeNames,
	}

	// 登录管理 tab 需要额外数据
	if tab == "sessions" {
		sessions, _ := sc.sessionMgr.ListByUID(uid)
		if sessions == nil {
			sessions = []*session.Session{}
		}
		currentSID, _ := c.Cookie(common.SessionCookieName)
		// 解析每个 session 的设备信息
		type sessionView struct {
			*session.Session
			DeviceInfo session.DeviceInfo
			IsCurrent  bool
		}
		var views []sessionView
		for _, s := range sessions {
			views = append(views, sessionView{
				Session:    s,
				DeviceInfo: session.ParseUA(s.UserAgent),
				IsCurrent:  s.ID == currentSID,
			})
		}
		data["Sessions"] = views
		data["CurrentSID"] = currentSID
	}

	c.HTML(http.StatusOK, "settings/index.html", common.BuildPageData(c, data))
}

// AuditStatus 查询当前用户的待审核类型（需登录）
func (sc *SettingsController) AuditStatus(c *gin.Context) {
	uid, exists := c.Get("uid")
	if !exists {
		common.Error(c, http.StatusUnauthorized, "请先登录")
		return
	}

	types, err := sc.auditService.GetPendingTypes(uid.(uint))
	if err != nil {
		common.Ok(c, gin.H{"pending_types": []string{}})
		return
	}
	if types == nil {
		types = []string{}
	}
	common.Ok(c, gin.H{"pending_types": types})
}
