package service

import (
	"encoding/json"
	"fmt"

	"be.ems/src/framework/utils/generate"
	"be.ems/src/modules/system/model"
	"be.ems/src/modules/system/model/vo"
	"be.ems/src/modules/system/repository"
)

// NewSysLoginSource 实例化服务层
var NewSysLoginSource = &SysLoginSource{
	sysLoginSourceRepository: repository.NewSysLoginSource,
}

// SysLoginSource 认证源 服务层处理
type SysLoginSource struct {
	sysLoginSourceRepository *repository.SysLoginSource // 认证源表
}

// FindByPage 分页查询
func (s SysLoginSource) FindByPage(query map[string]string) ([]model.SysLoginSource, int64) {
	return s.sysLoginSourceRepository.SelectByPage(query)
}

// FindById 查询ID
func (s SysLoginSource) FindById(id int64) model.SysLoginSource {
	rows := s.sysLoginSourceRepository.SelectByIds([]int64{id})
	if len(rows) > 0 {
		return rows[0]
	}
	return model.SysLoginSource{}
}

// Insert 新增
func (s SysLoginSource) Insert(param model.SysLoginSource) int64 {
	param.UID = generate.Code(8)
	return s.sysLoginSourceRepository.Insert(param)
}

// Update 更新
func (s SysLoginSource) Update(param model.SysLoginSource) int64 {
	return s.sysLoginSourceRepository.Update(param)
}

// DeleteByIds 批量删除
func (s SysLoginSource) DeleteByIds(ids []int64) (int64, error) {
	// 检查是否存在
	arr := s.sysLoginSourceRepository.SelectByIds(ids)
	if len(arr) <= 0 {
		// return 0, fmt.Errorf("没有权限访问认证源数据！")
		return 0, fmt.Errorf("no permission to access authentication source data")
	}
	if len(arr) == len(ids) {
		for _, v := range arr {
			s.sysLoginSourceRepository.DeleteByUserSource(v.UID)
		}
		return s.sysLoginSourceRepository.DeleteByIds(ids), nil
	}
	// return 0, fmt.Errorf("删除认证源信息失败！")
	return 0, fmt.Errorf("failed to delete authentication source information")
}

// FindByActive 查询激活
func (s SysLoginSource) FindByActive(uid string) []model.SysLoginSource {
	param := model.SysLoginSource{
		ActiveFlag: "1",
	}
	if uid != "" {
		param.UID = uid
	}
	return s.sysLoginSourceRepository.Select(param)
}

// CheckConfigJSON 检查配置JSON
func (s SysLoginSource) CheckConfigJSON(sType, sConfig string) (string, error) {
	var source any
	switch sType {
	case "LDAP":
		source = new(vo.SysLoginSourceLDAP)
	case "SMTP":
		source = new(vo.SysLoginSourceSMTP)
	case "OAuth2":
		source = new(vo.SysLoginSourceOAuth2)
	default:
		return "", fmt.Errorf("unsupported login source type: %s", sType)
	}
	if err := json.Unmarshal([]byte(sConfig), &source); err != nil {
		return "", fmt.Errorf("config json format error for %s type: %s", sType, err.Error())
	}
	configByte, err := json.Marshal(source)
	if err != nil {
		return "", fmt.Errorf("config json format error")
	}
	return string(configByte), nil
}
