package models

import (
	database "WorldEpcho/src/datasource"
	"errors"
	"fmt"
	"github.com/go-xorm/xorm"
	"reflect"
)

// UserRelationShip 用户关系结构体
type UserRelationShip struct {
	Id            int64  `json:"id" xorm:"pk autoincr 'id'"`
	MajorUId      int64  `json:"major_uid"  xorm:"major_uid"`
	SubUid        int64  `json:"sub_uid"  xorm:"sub_uid"`
	RelationLabel string `json:"relation_label" xorm:"relation_label"`
}

// CreateUserRelationShip 创建用户关系
func CreateUserRelationShip(session *xorm.Session, urs *UserRelationShip) error {
	_, err := session.Insert(urs)
	return err
}

// GetUserRelationShipByID 通过ID获取用户关系
func GetUserRelationShipByID(id int64) (*UserRelationShip, error) {
	urs := &UserRelationShip{}
	has, err := database.Engine.Id(id).Get(urs)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, fmt.Errorf("UserRelationShip not found")
	}
	return urs, nil
}

// UpdateUserRelationShip 更新用户关系
func UpdateUserRelationShip(session *xorm.Session, urs *UserRelationShip) error {
	_, err := database.Engine.Id(urs.Id).Update(urs)
	return err
}

// DeleteUserRelationShipByID 通过ID删除用户关系
func DeleteUserRelationShipByID(id int64) error {
	urs := &UserRelationShip{Id: id}
	_, err := database.Engine.Delete(urs)
	return err
}

// GetUserRelationshipByIDs 根据主 ID 和子 ID 查询用户关系信息
func GetUserRelationshipByIDs(session *xorm.Session, majorID, subID int64) (*UserRelationShip, error) {
	var userRelationship UserRelationShip
	exists, err := session.Where("major_uid = ?", majorID).And("sub_uid = ?", subID).Get(&userRelationship)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, errors.New("用户关系信息不存在")
	}
	return &userRelationship, nil
}

// GetUserRelationshipByMajorIDAndLabel 根据主 ID 和关系标签查询用户关系信息
func GetUserRelationshipByMajorIDAndLabel(session *xorm.Session, majorID int64, label string) (*UserRelationShip, error) {
	var userRelationship UserRelationShip
	exists, err := session.Where("major_uid = ?", majorID).And("relation_label = ?", label).Get(&userRelationship)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	return &userRelationship, nil
}

// GetUserRelationshipByMajorIDAndLabel 根据主 ID 和关系标签查询用户关系信息
func GetUserRelationshipBySubUIDAndLabel(SubID int64, label string) (*UserRelationShip, error) {
	var userRelationship UserRelationShip
	exists, err := database.Engine.Where("sub_uid = ?", SubID).And("relation_label = ?", label).Get(&userRelationship)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	return &userRelationship, nil
}

// GetUserRelationshipByMajorIDAndLabel 根据主 ID 和关系标签查询或更新用户关系信息
func FindUserRelationshipByMajorIDAndLabelOrUpdate(session *xorm.Session, majorID int64, label string, newData map[string]interface{}) (*UserRelationShip, error) {
	var userRelationship UserRelationShip
	// 首先检查记录是否存在
	exists, err := session.Where("major_uid = ?", majorID).And("relation_label = ?", label).Get(&userRelationship)
	if err != nil {
		return nil, err
	}

	if exists {
		// 如果存在，根据提供的数据更新记录
		_, err := session.Table(new(UserRelationShip)).Where("major_uid = ? AND relation_label = ?", majorID, label).Update(newData)
		if err != nil {
			return nil, err
		}
	} else {
		// 如果不存在，创建新的记录
		userRelationship.MajorUId = majorID
		userRelationship.RelationLabel = label
		// 假设 newData 是一个 map，其中包含了需要设置的字段和值
		// 这里需要将 newData 中的字段赋值给 userRelationship 对象
		for key, value := range newData {
			// 这里使用反射来动态设置字段值，需要确保 newData 的键与 UserRelationShip 的字段匹配
			// 这是一个简化示例，实际使用时应更严格地处理类型断言和错误检查
			reflect.ValueOf(&userRelationship).Elem().FieldByName(key).Set(reflect.ValueOf(value))
		}
		_, err = session.Insert(&userRelationship)
		if err != nil {
			return nil, err
		}
	}
	return &userRelationship, nil
}

// QueryRelationByMajorUidAndLabel 根据关系标签和主id获取获取关系信息
func QueryRelationByMajorUidAndLabel(engine *xorm.Engine, majorUid int64, label string) (*UserRelationShip, bool, error) {
	var userRelation UserRelationShip
	has, err := engine.Where("major_uid = ? AND relation_label = ?", majorUid, label).Get(&userRelation)
	if err != nil {
		return nil, false, err
	}
	if has {
		return &userRelation, true, nil
	}
	return nil, false, nil
}
