package models

import (
	"errors"
	"spaceofcheng/services/models/model"
	"spaceofcheng/services/utils"

	"github.com/yl10/kit/guid"

	"github.com/go-xorm/xorm"
)

// SysDAO 系统
type SysDAO struct {
	ctx *utils.Context
	db  *xorm.Session
}

// NewSysDAO New Inst
func NewSysDAO(ctx *utils.Context) *SysDAO {
	return &SysDAO{
		ctx: ctx,
		db:  ctx.DB,
	}
}

// GetPureUserInfo 获取用户基本信息
func (m *SysDAO) GetPureUserInfo(id string) (*model.SysUser, error) {
	user := model.SysUser{}

	has, err := m.db.Where("user_id=?", id).Get(&user)
	if err != nil {
		return nil, err
	}

	if !has {
		return nil, errors.New("没有查询到 ID (" + id + ") 对应的用户")
	}

	if user.Status != STATUS_NORMAL {
		return nil, errors.New("用户状态不正确")
	}

	return &user, nil
}

// GetUserMenu 获取用户菜单
func (m *SysDAO) GetUserMenu(userID string) ([]model.SysMenu, error) {
	query := `
		SELECT t.*
		FROM sys_menu t
			JOIN sys_user_menu s ON t.menu_id = s.menu_id
		WHERE s.user_id = ?
			AND t.status = ?
		ORDER BY t.order_no ASC
	`

	var menus []model.SysMenu
	if err := m.db.SQL(query, userID, STATUS_NORMAL).Find(&menus); err != nil {
		return nil, err
	}

	return menus, nil
}

// GetUserCase 获取用户案场
func (m *SysDAO) GetUserCase(userID string) ([]model.SysUserCase, error) {
	query := `
		SELECT t.*
		FROM sys_user_case t
		WHERE t.user_id = ?
			AND t.status = ?
	`

	var cases []model.SysUserCase
	if err := m.db.SQL(query, userID, STATUS_NORMAL).Find(&cases); err != nil {
		return nil, err
	}

	return cases, nil
}

// GetOrg 获取机构信息
func (m *SysDAO) GetOrg(orgID string) (*model.SysOrg, error) {
	var org model.SysOrg
	has, err := m.db.Where("org_id=?", orgID).And("status=?", STATUS_NORMAL).Get(&org)
	if err != nil {
		return nil, err
	}

	if !has {
		return nil, errors.New("没有查询到机构信息")
	}

	return &org, nil
}

// GetCustomer 获取用户信息
// 暂时无法解决 一个用户 多组织架构的问题
func (m *SysDAO) GetCustomer(custID string) (*model.TaCustomer, error) {
	var cust model.TaCustomer

	has, err := m.db.Where("customer_id=?", custID).And("status=?", STATUS_NORMAL).Get(&cust)
	if err != nil {
		return nil, err
	}

	if !has {
		return nil, errors.New("没有查询到客户 (id: " + custID + ") 信息")
	}

	return &cust, nil
}

// GetUserMappingByOpenID 获取用户映射信息
func (m *SysDAO) GetUserMappingByOpenID(openID string) ([]model.TaUserMapping, error) {
	var users []model.TaUserMapping

	err := m.db.Where("openid=?", openID).Find(&users)
	return users, err
}

// UpdateUserMapping 保存用户映射信息
func (m *SysDAO) UpdateUserMapping(user *model.TaUserMapping) error {
	// 如果没有映射ID, 则新增记录
	if user.MappingId == "" {
		user.MappingId = guid.NewGUIDString()
		_, err := m.db.Insert(user)
		return err
	}

	// 否则更新记录
	cols := []string{
		"account_info",
	}
	_, err := m.db.Cols(cols...).
		Where("account_type=?", user.AccountType).
		And("openid=?", user.Openid).
		Update(user)
	return err
}

// GetCaseByContext 获取案场
func GetCaseByContext(ctx *utils.Context) (string, error) {
	csRaw := ctx.Get("currentCase")
	if csRaw == nil {
		return "", errors.New("当前人员无案场权限")
	}

	cs := csRaw.(model.SysUserCase)
	if cs.CaseId == "" || cs.Status == STATUS_DEL {
		return "", errors.New("当前人员无案场权限")
	}

	return cs.CaseId, nil
}

// GetWeChatConfig 获取微信配置
func (m *SysDAO) GetWeChatConfig(org string) (*model.SysWechatConf, error) {
	conf := new(model.SysWechatConf)

	if _, err := m.db.Where("org_id=?", org).And("type=?", WECHAT_WX).Get(conf); err != nil {
		return nil, err
	}

	return conf, nil
}
