package cbd;
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.IndexOptions;
import org.bson.Document;
import java.util.concurrent.TimeUnit;
import java.time.Duration;
import java.time.Instant;
import java.util.*;

public class atendimentoB {

    private MongoDatabase db;
    private MongoCollection<Document> col;
    private String username;
    private static int limit = 10; //products limit
    private static long timeslot = 2 * 60 ; //time limit (s)

    
    public atendimentoB(String username) {

        this.username = username;

        String uri = "mongodb://127.0.0.1:27017";

        MongoClient mongoClient = MongoClients.create(uri);
        MongoDatabase db = mongoClient.getDatabase("cbd");
        this.db = db;

    }	


    public void insertProducts(String prod, int quant) {

        if (db.listCollections().filter(Filters.eq("name", "atendimentoB" + this.username)).first() == null) {

            MongoCollection<Document> col = db.getCollection("atendimentoB" + this.username);
            this.col = col;
            col.insertOne(new Document("product", prod)
                        .append("quantity", quant)
                        .append("createdAt", new Date()));
                      
            col.createIndex(new Document("createdAt", 1), 
                            new IndexOptions().expireAfter(timeslot, TimeUnit.SECONDS));

            col.createIndex(new Document("product", 1));
            col.createIndex(new Document("quantity", 1));

            System.out.println("Product " + prod + " is now registered with " + quant + " units");
        }

 

        else {
            Integer count = 0;
            AggregateIterable<Document> result = col.aggregate(Arrays.asList(
                new Document("$group", new Document("_id", null)
                .append("totalQuantity", new Document("$sum", "$quantity")))
            ));
            if (result.first() != null) {
                count = result.first().getInteger("totalQuantity");
            }
          


            if (col.find(Filters.eq("product", prod)).first() != null) {
                System.out.println("Product " + prod + " is now registered with update amount ( +" + quant + " units)");
                return;
            }  

            if (count == limit || count + quant > limit){

                if (count + quant > limit){
                    if (limit - count > 0){
                        System.out.println("Product amount limit reached for the time interval, only registered " + (limit - count) + " units");
                        col.insertOne(new Document("product", prod)
                        .append("quantity", limit - count));
                    }
                    else{
                        System.out.println("Product limit reached for the time interval");
                    }
                }
            

                Document firstProduct = col.find(Filters.exists("createdAt")).first();

                if (firstProduct != null && firstProduct.containsKey("createdAt")) {
                    Date createdAtDate = firstProduct.getDate("createdAt");
                    Instant createdAt = createdAtDate.toInstant();
                    Instant now = Instant.now();

                    long elapsedTime = Duration.between(createdAt, now).getSeconds();

            
                    long remainingTTL = timeslot - elapsedTime;

                    if (remainingTTL > 0) {
                        System.out.println("Please wait " + remainingTTL + " seconds to add different products, or press 'Enter' to quit");
                    } else {
                        //TTL expired, drop the collection and insert the new product
                        col.drop();
                        col = db.getCollection("atendimentoA" + this.username);
                        col.insertOne(new Document("product", prod)
                                    .append("createdAt", new Date())
                                    .append("quantity", quant));
                        System.out.println("Product " + prod + " is now registered");
                        return;
                    }
                }




            }

         


            else if (col.find(Filters.eq("product", prod)).first() != null){
                Document doc = col.find(Filters.eq("product", prod)).first();
                int amount = doc.getInteger("quantity");
                System.out.println("Product " + prod + " already registered. Amount updated (total amount: " + (amount + quant) + ")");
                col.updateOne(doc, new Document("quantity", amount + quant));
                return;
            }
            
            else {
                col.insertOne(new Document("product", prod)
                            .append("quantity", quant));
                System.out.println("Product " + prod + " is now registered with " + quant + " units");
                return;
            }
        }
        return;
    }   


    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        System.out.print("Please write your username in order to register products: ");
        String username = scanner.nextLine();
        atendimentoB atendimento = new atendimentoB(username);

        System.out.print("Please write (product, quantity) you would like to register (press 'Enter' to quit): ");
        String line = scanner.nextLine();
       

        while (!line.isEmpty()) {
            String[] parts = line.split(",");

            if (parts.length != 2){
                System.err.println("Invalid input, please write (product, amount). Exiting...");
                System.exit(1);
            }

            String prod = parts[0];
            int quant = Integer.parseInt(parts[1]);
    

            atendimento.insertProducts(prod, quant);
            line = scanner.nextLine();
            parts = line.split(",");

            if (parts.length != 2 && !line.isEmpty()){
                System.err.println("Invalid input, please write (product,amount). Exiting");
                System.exit(1);

            }        
        }

    
        System.out.println("Exiting...");

        scanner.close();   
        
    }
}
