package dbAccess

import (
	"context"
	"time"

	"git.fjla.uk/owlboard/go-types/pkg/database"
	"git.fjla.uk/owlboard/timetable-mgr/helpers"
	"git.fjla.uk/owlboard/timetable-mgr/log"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
)

const timetableCollection string = "timetable"

func DropCollection(collectionName string) error {
	database := MongoClient.Database(databaseName)
	collection := database.Collection(collectionName)

	err := collection.Drop(context.Background())
	if err != nil {
		log.Msg.Error("Error dropping collection", zap.String("Collection Name", collectionName), zap.Error(err))
		return err
	}

	return nil
}

func CheckUpdateTime(collectionName string) (int64, error) {
	database := MongoClient.Database(databaseName)
	collection := database.Collection(metaCollection)
	filter := bson.D{
		{Key: "target", Value: collectionName},
		{Key: "type", Value: "collection"},
	}
	var result struct {
		Updated int64 `bson:"updated"`
	}
	err := collection.FindOne(context.Background(), filter).Decode(&result)
	if err != nil {
		return 0, err
	}
	return result.Updated, nil
}

func SetUpdateTime(collectionName string) error {
	log.Msg.Info("Setting update time", zap.String("collection", collectionName))
	database := MongoClient.Database(databaseName)
	collection := database.Collection("meta")
	options := options.Update().SetUpsert(true)
	updateTime := time.Now().Unix()
	filter := bson.M{
		"target": collectionName,
		"type":   "collection",
	}
	update := bson.M{
		"$set": bson.M{
			"updated": updateTime,
			"target":  collectionName,
			"type":    "collection",
		},
	}
	_, err := collection.UpdateOne(context.Background(), filter, update, options)

	if err != nil {
		log.Msg.Error("Error setting update time", zap.String("collection", collectionName), zap.Error(err))
		return err
	}
	return nil
}

func PushVersionToDb() {
	version := database.Version{
		Target:    "mq-client",
		Component: "mq-client",
		Version:   helpers.Version,
	}
	versionSelector := database.VersionSelector{
		Target:    "mq-client",
		Component: "mq-client",
	}
	opts := options.Update().SetUpsert(true)
	coll := MongoClient.Database("owlboard").Collection("versions")
	_, err := coll.UpdateOne(context.TODO(), versionSelector, bson.M{"$set": version}, opts)
	if err != nil {
		log.Msg.Warn("Unable to push version to database: " + err.Error())
	} else {
		log.Msg.Debug("Version up to date in Database")
	}
}

func PutOneService(data database.Service) bool {
	coll := MongoClient.Database(databaseName).Collection(timetableCollection)
	_, err := coll.InsertOne(context.TODO(), data)
	if err != nil {
		log.Msg.Error("Unable to insert to database: " + err.Error())
		return false
	}
	return true
}

func DeleteOneService(data database.DeleteQuery) bool {
	coll := MongoClient.Database(databaseName).Collection(timetableCollection)
	var filter = bson.D{
		{Key: "trainUid", Value: data.TrainUid},
		{Key: "stpIndicator", Value: data.StpIndicator},
		{Key: "scheduleStartDate", Value: data.ScheduleStartDate},
	}
	_, err := coll.DeleteOne(context.TODO(), filter)
	if err != nil {
		log.Msg.Error("Unable to delete service: " + err.Error())
		return false
	}
	return true
}
