package service

import (
	"errors"

	"git.zkcoi.com/zkcoi/meshray/internal/model"
	"git.zkcoi.com/zkcoi/meshray/internal/store/sqlite"
	"go.uber.org/zap"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

// SystemConfigService 系统配置服务
type SystemConfigService struct {
	store  *sqlite.Store
	logger *zap.Logger
}

// NewSystemConfigService 创建系统配置服务
func NewSystemConfigService(store *sqlite.Store, logger *zap.Logger) *SystemConfigService {
	return &SystemConfigService{
		store:  store,
		logger: logger,
	}
}

// GetWGMode 获取当前 WG 运行模式
func (s *SystemConfigService) GetWGMode() (string, error) {
	config, err := s.getConfig("wg_mode")
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			// 如果不存在，返回默认值 "auto"
			return "auto", nil
		}
		return "", err
	}
	return config.Value, nil
}

// SetWGMode 设置 WG 运行模式（需要重启 MeshRay 才能生效）
func (s *SystemConfigService) SetWGMode(mode string) error {
	// 验证模式值
	validModes := map[string]bool{
		"auto":      true,
		"kernel":    true,
		"userspace": true,
	}
	if !validModes[mode] {
		return errors.New("无效的 WG 模式，仅支持：auto, kernel, userspace")
	}

	return s.setConfig("wg_mode", mode)
}

// GetConfig 获取任意配置项
func (s *SystemConfigService) GetConfig(key string) (string, error) {
	config, err := s.getConfig(key)
	if err != nil {
		return "", err
	}
	return config.Value, nil
}

// SetConfig 设置任意配置项
func (s *SystemConfigService) SetConfig(key, value string) error {
	return s.setConfig(key, value)
}

// getConfig 内部方法：获取配置
func (s *SystemConfigService) getConfig(key string) (*model.SystemConfig, error) {
	var config model.SystemConfig
	err := s.store.DB().Where("key = ?", key).First(&config).Error
	if err != nil {
		return nil, err
	}
	return &config, nil
}

// setConfig 内部方法：设置配置
func (s *SystemConfigService) setConfig(key, value string) error {
	var config model.SystemConfig
	err := s.store.DB().Where("key = ?", key).First(&config).Error

	if errors.Is(err, gorm.ErrRecordNotFound) {
		// 创建新配置
		config = model.SystemConfig{
			Key:   key,
			Value: value,
		}
		return s.store.DB().Create(&config).Error
	}

	// 更新现有配置
	config.Value = value
	return s.store.DB().Save(&config).Error
}

// ChangePassword 修改密码（P1）
func (s *SystemConfigService) ChangePassword(userID uint, oldPassword, newPassword string) error {
	// 获取用户
	var user model.User
	if err := s.store.DB().First(&user, userID).Error; err != nil {
		return errors.New("用户不存在")
	}

	// 验证旧密码
	if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(oldPassword)); err != nil {
		return errors.New("原密码错误")
	}

	// 加密新密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
	if err != nil {
		s.logger.Error("加密新密码失败", zap.Error(err))
		return errors.New("密码加密失败")
	}

	// 更新密码
	return s.store.DB().Model(&user).Update("password_hash", string(hashedPassword)).Error
}
