// Package service 业务逻辑层
package service

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"time"

	"server/common"
	"server/config"
	"server/modules/system/entity"
	"server/modules/system/mapper"

	"github.com/google/uuid"
)

type SysUserService struct {
	mapper *mapper.SysUserMapper
}

func NewSysUserService() *SysUserService {
	return &SysUserService{mapper: mapper.NewSysUserMapper()}
}

// Login 用户登录
// 密码验证方式与 Java JeecgBoot 兼容: PBEWithMD5AndDES(username, password, salt)
func (s *SysUserService) Login(username, password string) (*entity.LoginUser, string, error) {
	// 查询用户
	user, err := s.mapper.FindByPhone(username)
	if err != nil {
		return nil, "", errors.New("用户不存在")
	}

	// 验证状态
	if user.Status == 2 {
		return nil, "", errors.New("账号已被冻结")
	}

	// 验证密码 (与Java兼容: encrypt(username, password, salt))
	encrypted, err := common.Encrypt(user.Username, password, user.Salt)
	if (user.Password != encrypted) || (err != nil) {
		return nil, "", errors.New("用户名或密码错误")
	}

	// 生成Token
	token := s.generateToken()

	// 构建登录用户信息
	loginUser := &entity.LoginUser{
		ID:       user.ID,
		Username: user.Username,
		Realname: user.Realname,
		Avatar:   user.Avatar,
		Phone:    user.Phone,
		Email:    user.Email,
		Token:    token,
	}

	// 存储到Redis
	if err := s.saveLoginUser(token, loginUser); err != nil {
		return nil, "", errors.New("登录失败，请重试")
	}

	return loginUser, token, nil
}

// SysLogin 用户登录
// 密码验证方式与 Java JeecgBoot 兼容: PBEWithMD5AndDES(username, password, salt)
func (s *SysUserService) SysLogin(username, password string) (*entity.LoginUser, string, error) {
	// 查询用户
	user, err := s.mapper.FindByUsername(username)
	if err != nil {
		return nil, "", errors.New("用户不存在")
	}

	// 验证状态
	if user.Status == 2 {
		return nil, "", errors.New("账号已被冻结")
	}

	// 验证密码 (与Java兼容: encrypt(username, password, salt))
	encrypted, err := common.Encrypt(username, password, user.Salt)
	if (user.Password != encrypted) || (err != nil) {
		return nil, "", errors.New("用户名或密码错误")
	}

	// 生成Token
	token := s.generateToken()

	// 构建登录用户信息
	loginUser := &entity.LoginUser{
		ID:       user.ID,
		Username: user.Username,
		Realname: user.Realname,
		Avatar:   user.Avatar,
		Phone:    user.Phone,
		Email:    user.Email,
		Token:    token,
	}

	// 存储到Redis
	if err := s.saveLoginUser(token, loginUser); err != nil {
		return nil, "", errors.New("登录失败，请重试")
	}

	return loginUser, token, nil
}

// Logout 用户登出
func (s *SysUserService) Logout(token string) error {
	ctx := context.Background()
	return config.RDB.Del(ctx, common.RedisTokenPrefix+token).Err()
}

// GetLoginUser 根据Token获取登录用户信息
func (s *SysUserService) GetLoginUser(token string) (*entity.LoginUser, error) {
	ctx := context.Background()
	data, err := config.RDB.Get(ctx, common.RedisTokenPrefix+token).Result()
	if err != nil {
		return nil, errors.New("未登录或登录已过期")
	}

	var loginUser entity.LoginUser
	if err := json.Unmarshal([]byte(data), &loginUser); err != nil {
		return nil, errors.New("登录信息异常")
	}

	// 刷新过期时间
	config.RDB.Expire(ctx, common.RedisTokenPrefix+token, common.RedisTokenExpire)

	return &loginUser, nil
}

// RefreshToken 刷新Token过期时间
func (s *SysUserService) RefreshToken(token string) error {
	ctx := context.Background()
	return config.RDB.Expire(ctx, common.RedisTokenPrefix+token, common.RedisTokenExpire).Err()
}

// 保存登录用户到Redis
func (s *SysUserService) saveLoginUser(token string, user *entity.LoginUser) error {
	ctx := context.Background()
	data, err := json.Marshal(user)
	if err != nil {
		return err
	}
	return config.RDB.Set(ctx, common.RedisTokenPrefix+token, data, common.RedisTokenExpire).Err()
}

// 生成Token
func (s *SysUserService) generateToken() string {
	return uuid.New().String()
}

// ========== 用户管理 ==========

func (s *SysUserService) List(page, size int) ([]entity.SysUser, int64, error) {
	return s.mapper.FindAll(page, size)
}

func (s *SysUserService) GetByID(id string) (*entity.SysUser, error) {
	return s.mapper.FindByID(id)
}

func (s *SysUserService) Create(item *entity.SysUser) error {
	item.ID = uuid.New().String()
	// 生成盐值 (8字节)
	item.Salt = uuid.New().String()[:8]
	// 加密密码 (与Java兼容)
	encrypted, err := common.Encrypt(item.Username, item.Password, item.Salt)
	if err != nil {
		log.Printf("密码加密失败: %v", err)
		return fmt.Errorf("密码加密失败: %w,请联系管理员", err) // 仍然返回错误
	}
	item.Password = encrypted
	item.DelFlag = 0
	item.Status = 1
	now := time.Now()
	item.CreateTime = &now
	return s.mapper.Create(item)
}

func (s *SysUserService) Update(item *entity.SysUser) error {
	now := time.Now()
	item.UpdateTime = &now
	return s.mapper.Update(item)
}

func (s *SysUserService) UpdateFields(id string, fields map[string]interface{}) error {
	return s.mapper.UpdateFields(id, fields)
}

func (s *SysUserService) Delete(id string) error {
	return s.mapper.Delete(id)
}

// UpdatePassword 修改密码
func (s *SysUserService) UpdatePassword(id, oldPwd, newPwd string) error {
	user, err := s.mapper.FindByID(id)
	if err != nil {
		return errors.New("用户不存在")
	}

	// 验证旧密码
	encrypted, err := common.Encrypt(user.Username, oldPwd, user.Salt)
	if err != nil {
		log.Printf("密码加密失败: %v", err)
		return fmt.Errorf("密码加密失败: %w,请联系管理员", err) // 仍然返回错误
	}
	if encrypted != user.Password {
		return errors.New("原密码错误")
	}

	// 生成新密码
	newEncrypted, err := common.Encrypt(user.Username, newPwd, user.Salt)
	if err != nil {
		log.Printf("密码加密失败: %v", err)
		return fmt.Errorf("密码加密失败: %w,请联系管理员", err) // 仍然返回错误
	}
	return s.mapper.UpdateFields(id, map[string]interface{}{
		"password": newEncrypted,
	})
}
