package main

import (
	"context"
	"fmt"
	"gitea.pena/PenaSide/heruvym/internal/model"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

const (
	bucketName      = "videodata"
	minioEndpoint   = "localhost:9000"
	accessKeyID     = "admin"
	secretAccessKey = "admin123"
	mongoURI        = "mongodb://test:test@localhost:27024/?authSource=admin"
	mongoDBName     = "admin"
	collectionName  = "verification"
)

func main() {
	ctx := context.Background()
	clientOptions := options.Client().ApplyURI(mongoURI)
	client, err := mongo.Connect(ctx, clientOptions)
	if err != nil {
		fmt.Println("Ошибка подключения к монго:", err)
		return
	}
	defer func(client *mongo.Client, ctx context.Context) {
		err := client.Disconnect(ctx)
		if err != nil {
			return
		}
	}(client, ctx)

	collection := client.Database(mongoDBName).Collection(collectionName)

	minioClient, err := minio.New(minioEndpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
		Secure: false,
	})
	if err != nil {
		fmt.Println("Ошибка подключения к минио:", err)
		return
	}

	allFiles, err := getAllFilesInBucket(ctx, minioClient)
	if err != nil {
		fmt.Println("Ошибка при получении списка файлов в бакете:", err)
		return
	}

	messages, err := getMessagesRecords(ctx, collection)
	if err != nil {
		fmt.Println("Ошибка при получении записей из монго:", err)
		return
	}

	for _, file := range allFiles {
		if !checkContains(messages, file.Key) {
			fmt.Println("Удаление файла:", file.Key)
			err := deleteFileFromBucket(ctx, minioClient, file.Key)
			if err != nil {
				fmt.Println("Ошибка при удалении файла:", err)
			}
		}
	}
}

// получение всех файлов из минио по бакету
func getAllFilesInBucket(ctx context.Context, client *minio.Client) ([]minio.ObjectInfo, error) {
	var files []minio.ObjectInfo
	objectCh := client.ListObjects(ctx, bucketName, minio.ListObjectsOptions{})
	for object := range objectCh {
		if object.Err != nil {
			return nil, object.Err
		}
		files = append(files, object)
	}
	return files, nil
}

// удаление файла из минио
func deleteFileFromBucket(ctx context.Context, client *minio.Client, fileName string) error {
	err := client.RemoveObject(ctx, bucketName, fileName, minio.RemoveObjectOptions{})
	return err
}

// получение списка сообщений из монго
func getMessagesRecords(ctx context.Context, collection *mongo.Collection) ([]model.Message, error) {
	var records []model.Message
	cursor, err := collection.Find(ctx, bson.M{})
	if err != nil {
		return nil, err
	}
	defer cursor.Close(ctx)
	for cursor.Next(ctx) {
		var record model.Message
		if err := cursor.Decode(&record); err != nil {
			return nil, err
		}
		records = append(records, record)
	}
	if err := cursor.Err(); err != nil {
		return nil, err
	}
	return records, nil
}

// проверка на существования файла минио в монге по имени
func checkContains(messages []model.Message, fileKey string) bool {
	for _, message := range messages {
		for _, file := range message.Files {
			if file == fileKey {
				return true
			}
		}
	}
	return false
}
