package dao

import (
	"cds/models"
	"context"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
)

func GetGroupById(id string) (group *models.Group, err error) {
	db, _ := get()
	objectId, err := primitive.ObjectIDFromHex(id)
	defer disconnect(db.Client())
	coll := db.Collection("groups")

	var result models.Group
	err = coll.FindOne(context.TODO(), bson.D{{"_id", objectId}}).Decode(&result)
	if err != nil {
		return nil, err
	} else {
		return &result, nil
	}
}

func GetGroupByMember(id string) (group []models.Group, err error) {
	db, _ := get()
	objectId, err := primitive.ObjectIDFromHex(id)
	defer disconnect(db.Client())
	coll := db.Collection("groups")

	cursor, err := coll.Find(context.TODO(), bson.D{{"members", objectId}})
	defer cursor.Close(context.TODO())
	if err != nil {
		return nil, err
	}

	err = cursor.All(context.TODO(), &group)

	if err != nil {
		return nil, err
	} else {
		return group, nil
	}
}

func GetGroupNotByMember(id string) (group []models.Group, err error) {
	db, _ := get()
	objectId, err := primitive.ObjectIDFromHex(id)
	defer disconnect(db.Client())
	coll := db.Collection("groups")

	cursor, err := coll.Find(context.TODO(), bson.D{{"members", bson.D{{"$ne", objectId}}}})
	defer cursor.Close(context.TODO())
	if err != nil {
		return nil, err
	}

	err = cursor.All(context.TODO(), &group)

	if err != nil {
		return nil, err
	} else {
		return group, nil
	}
}

func CheckMemberInGroup(idUser string, idGroup string) (ret bool, err error) {
	db, _ := get()
	userObject, err := primitive.ObjectIDFromHex(idUser)
	groupObject, err := primitive.ObjectIDFromHex(idGroup)
	defer disconnect(db.Client())
	coll := db.Collection("groups")

	err = coll.FindOne(context.TODO(), bson.D{
		{"_id", groupObject},
		{"members", userObject},
	}).Err()

	if err == mongo.ErrNoDocuments {
		return false, nil
	} else if err != nil {
		return false, err
	} else {
		return true, nil
	}
}

func AddMemberInGroup(idUser string, idGroup string) error {
	db, _ := get()
	user, err := primitive.ObjectIDFromHex(idUser)
	group, err := primitive.ObjectIDFromHex(idGroup)
	defer disconnect(db.Client())
	coll := db.Collection("groups")

	update := bson.D{{"$push", bson.D{{"members", user}}}}

	err = coll.FindOneAndUpdate(
		context.TODO(),
		bson.D{{"_id", group}},
		update,
	).Err()

	return err
}

func RemoveMemberFromGroup(idUser string, idGroup string) error {
	db, _ := get()
	user, err := primitive.ObjectIDFromHex(idUser)
	group, err := primitive.ObjectIDFromHex(idGroup)
	defer disconnect(db.Client())
	coll := db.Collection("groups")

	update := bson.D{{"$pull", bson.D{{"members", user}}}}

	err = coll.FindOneAndUpdate(
		context.TODO(),
		bson.D{{"_id", group}},
		update,
	).Err()

	return err
}