package system

import (
	"encoding/json"

	"kra/internal/biz/system"
	"kra/internal/server/middleware"
	types "kra/internal/service/types/system"
	"kra/pkg/jwt"

	"github.com/go-kratos/kratos/v2/errors"
	khttp "github.com/go-kratos/kratos/v2/transport/http"
)

// RouterGroup 路由组接口
type RouterGroup struct {
	Public            *khttp.Router // 公开路由（无需认证）
	Private           *khttp.Router // 私有路由（需要JWT认证）
	PrivateWithRecord *khttp.Router // 私有路由 + 操作记录
}

// UserService 用户服务
type UserService struct {
	uc     *system.UserUsecase
	jwtPkg *jwt.JWT
}

// NewUserService 创建用户服务
func NewUserService(uc *system.UserUsecase, jwtPkg *jwt.JWT) *UserService {
	return &UserService{uc: uc, jwtPkg: jwtPkg}
}

// Login 用户登录
func (s *UserService) Login(ctx khttp.Context) error {
	var req types.LoginRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	user, err := s.uc.Login(ctx, req.Username, req.Password)
	if err != nil {
		return errors.Unauthorized("LOGIN_FAILED", err.Error())
	}
	if user.Enable != 1 {
		return errors.Forbidden("USER_DISABLED", "用户被禁止登录")
	}
	claims := s.jwtPkg.CreateClaims(jwt.BaseClaims{
		UUID:        user.UUID.String(),
		ID:          user.ID,
		Username:    user.Username,
		NickName:    user.NickName,
		AuthorityID: user.AuthorityId,
	})
	token, err := s.jwtPkg.CreateToken(claims.BaseClaims)
	if err != nil {
		return errors.InternalServer("TOKEN_ERROR", "生成token失败")
	}
	return ctx.Result(200, &types.LoginReply{
		User:      toTypesUserInfo(user),
		Token:     token,
		ExpiresAt: claims.ExpiresAt.UnixMilli(),
	})
}

// Register 用户注册
func (s *UserService) Register(ctx khttp.Context) error {
	var req types.RegisterRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	user := &system.User{
		Username:    req.Username,
		Password:    req.Password,
		NickName:    req.NickName,
		HeaderImg:   req.HeaderImg,
		AuthorityId: req.AuthorityId,
		Phone:       req.Phone,
		Email:       req.Email,
		Enable:      req.Enable,
	}
	created, err := s.uc.Register(ctx, user)
	if err != nil {
		return errors.BadRequest("REGISTER_FAILED", err.Error())
	}
	return ctx.Result(200, &types.UserInfoReply{User: toTypesUserInfo(created)})
}

// ChangePassword 修改密码
func (s *UserService) ChangePassword(ctx khttp.Context) error {
	var req types.ChangePasswordRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	userID := middleware.GetUserID(ctx)
	if userID == 0 {
		return errors.Unauthorized("UNAUTHORIZED", "请先登录")
	}
	if err := s.uc.ChangePassword(ctx, userID, req.Password, req.NewPassword); err != nil {
		return errors.BadRequest("CHANGE_PASSWORD_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// ResetPassword 重置密码
func (s *UserService) ResetPassword(ctx khttp.Context) error {
	var req types.ResetPasswordRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	if err := s.uc.ResetPassword(ctx, req.ID, req.Password); err != nil {
		return errors.BadRequest("RESET_PASSWORD_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// GetUserInfo 获取用户信息
func (s *UserService) GetUserInfo(ctx khttp.Context) error {
	claims, ok := middleware.GetClaims(ctx)
	if !ok {
		return errors.Unauthorized("UNAUTHORIZED", "请先登录")
	}
	user, err := s.uc.GetUserInfo(ctx, claims.UUID)
	if err != nil {
		return errors.NotFound("USER_NOT_FOUND", err.Error())
	}
	return ctx.Result(200, &types.GetUserInfoReply{UserInfo: toTypesUserInfo(user)})
}

// GetUserList 获取用户列表
func (s *UserService) GetUserList(ctx khttp.Context) error {
	var req types.GetUserListRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	filters := make(map[string]string)
	if req.Username != "" {
		filters["username"] = req.Username
	}
	if req.NickName != "" {
		filters["nick_name"] = req.NickName
	}
	if req.Phone != "" {
		filters["phone"] = req.Phone
	}
	if req.Email != "" {
		filters["email"] = req.Email
	}
	users, total, err := s.uc.GetUserList(ctx, req.Page, req.PageSize, filters)
	if err != nil {
		return errors.InternalServer("LIST_ERROR", err.Error())
	}
	list := make([]types.UserInfo, len(users))
	for i, u := range users {
		list[i] = toTypesUserInfo(u)
	}
	return ctx.Result(200, &types.GetUserListReply{List: list, Total: total, Page: req.Page, PageSize: req.PageSize})
}

// SetUserInfo 设置用户信息
func (s *UserService) SetUserInfo(ctx khttp.Context) error {
	var req types.SetUserInfoRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	user := &system.User{
		ID:        req.ID,
		NickName:  req.NickName,
		HeaderImg: req.HeaderImg,
		Phone:     req.Phone,
		Email:     req.Email,
		Enable:    req.Enable,
	}
	if err := s.uc.SetUserInfo(ctx, user); err != nil {
		return errors.BadRequest("SET_USER_INFO_FAILED", err.Error())
	}
	if len(req.AuthorityIds) > 0 {
		adminAuthorityID := middleware.GetAuthorityID(ctx)
		if err := s.uc.SetUserAuthorities(ctx, adminAuthorityID, req.ID, req.AuthorityIds); err != nil {
			return errors.BadRequest("SET_USER_AUTHORITIES_FAILED", err.Error())
		}
	}
	return ctx.Result(200, nil)
}

// SetSelfInfo 设置自己信息
func (s *UserService) SetSelfInfo(ctx khttp.Context) error {
	var req types.SetSelfInfoRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	userID := middleware.GetUserID(ctx)
	if userID == 0 {
		return errors.Unauthorized("UNAUTHORIZED", "请先登录")
	}
	user := &system.User{
		ID:        userID,
		NickName:  req.NickName,
		HeaderImg: req.HeaderImg,
		Phone:     req.Phone,
		Email:     req.Email,
	}
	if err := s.uc.SetSelfInfo(ctx, user); err != nil {
		return errors.BadRequest("SET_SELF_INFO_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// SetSelfSetting 设置自己配置
func (s *UserService) SetSelfSetting(ctx khttp.Context) error {
	var req types.SetSelfSettingRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	userID := middleware.GetUserID(ctx)
	if userID == 0 {
		return errors.Unauthorized("UNAUTHORIZED", "请先登录")
	}
	setting := json.RawMessage(req.Setting)
	if err := s.uc.SetSelfSetting(ctx, userID, setting); err != nil {
		return errors.BadRequest("SET_SELF_SETTING_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// DeleteUser 删除用户
func (s *UserService) DeleteUser(ctx khttp.Context) error {
	var req types.DeleteUserRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	currentUserID := middleware.GetUserID(ctx)
	if currentUserID == req.ID {
		return errors.BadRequest("DELETE_FAILED", "无法删除自己")
	}
	if err := s.uc.DeleteUser(ctx, req.ID); err != nil {
		return errors.BadRequest("DELETE_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// SetUserAuthority 设置用户角色
func (s *UserService) SetUserAuthority(ctx khttp.Context) error {
	var req types.SetUserAuthorityRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	userID := middleware.GetUserID(ctx)
	if userID == 0 {
		return errors.Unauthorized("UNAUTHORIZED", "请先登录")
	}
	if err := s.uc.SetUserAuthority(ctx, userID, req.AuthorityId); err != nil {
		return errors.BadRequest("SET_AUTHORITY_FAILED", err.Error())
	}
	// 重新生成token
	claims, ok := middleware.GetClaims(ctx)
	if !ok {
		return errors.Unauthorized("UNAUTHORIZED", "请先登录")
	}
	claims.AuthorityID = req.AuthorityId
	token, err := s.jwtPkg.CreateToken(claims.BaseClaims)
	if err != nil {
		return errors.InternalServer("TOKEN_ERROR", "生成token失败")
	}
	return ctx.Result(200, &types.SetUserAuthorityReply{Token: token, ExpiresAt: claims.ExpiresAt.UnixMilli()})
}

// SetUserAuthorities 设置用户多角色
func (s *UserService) SetUserAuthorities(ctx khttp.Context) error {
	var req types.SetUserAuthoritiesRequest
	if err := ctx.Bind(&req); err != nil {
		return err
	}
	adminAuthorityID := middleware.GetAuthorityID(ctx)
	if err := s.uc.SetUserAuthorities(ctx, adminAuthorityID, req.ID, req.AuthorityIds); err != nil {
		return errors.BadRequest("SET_AUTHORITIES_FAILED", err.Error())
	}
	return ctx.Result(200, nil)
}

// toTypesUserInfo 转换用户信息为types格式
func toTypesUserInfo(user *system.User) types.UserInfo {
	if user == nil {
		return types.UserInfo{}
	}
	info := types.UserInfo{
		ID:          user.ID,
		UUID:        user.UUID.String(),
		Username:    user.Username,
		NickName:    user.NickName,
		SideMode:    user.SideMode,
		HeaderImg:   user.HeaderImg,
		BaseColor:   user.BaseColor,
		AuthorityId: user.AuthorityId,
		Phone:       user.Phone,
		Email:       user.Email,
		Enable:      user.Enable,
	}
	if user.OriginSetting != nil {
		info.OriginSetting = string(user.OriginSetting)
	}
	if user.Authority != nil {
		auth := toTypesAuthorityInfo(user.Authority)
		info.Authority = &auth
	}
	if len(user.Authorities) > 0 {
		info.Authorities = make([]types.AuthorityInfo, len(user.Authorities))
		for i, a := range user.Authorities {
			info.Authorities[i] = toTypesAuthorityInfo(a)
		}
	}
	return info
}

// toTypesAuthorityInfo 转换角色信息为types格式
func toTypesAuthorityInfo(auth *system.Authority) types.AuthorityInfo {
	if auth == nil {
		return types.AuthorityInfo{}
	}
	return types.AuthorityInfo{
		AuthorityId:   auth.AuthorityId,
		AuthorityName: auth.AuthorityName,
		ParentId:      auth.ParentId,
		DefaultRouter: auth.DefaultRouter,
	}
}

// RegisterRoutes 注册用户路由
func (s *UserService) RegisterRoutes(rg *RouterGroup) {
	// 公开路由（无需认证）
	rg.Public.POST("/base/login", s.Login)

	// 私有路由 + 操作记录（写操作）
	rg.PrivateWithRecord.POST("/user/admin_register", s.Register)
	rg.PrivateWithRecord.POST("/user/changePassword", s.ChangePassword)
	rg.PrivateWithRecord.POST("/user/setUserAuthority", s.SetUserAuthority)
	rg.PrivateWithRecord.DELETE("/user/deleteUser", s.DeleteUser)
	rg.PrivateWithRecord.PUT("/user/setUserInfo", s.SetUserInfo)
	rg.PrivateWithRecord.PUT("/user/setSelfInfo", s.SetSelfInfo)
	rg.PrivateWithRecord.POST("/user/setUserAuthorities", s.SetUserAuthorities)
	rg.PrivateWithRecord.POST("/user/resetPassword", s.ResetPassword)
	rg.PrivateWithRecord.PUT("/user/setSelfSetting", s.SetSelfSetting)

	// 私有路由（读操作，不记录）
	rg.Private.POST("/user/getUserList", s.GetUserList)
	rg.Private.GET("/user/getUserInfo", s.GetUserInfo)
}
