'use server';

import { getDbClient } from '../dbClient';
import { ObjectId } from 'mongodb';
import { Bill, BillingLocation, YearMonth } from '../db-types';
import { AuthenticatedUser } from '../types/next-auth';
import { withUser } from '../auth';
import { unstable_noStore as noStore } from 'next/cache';

/**
 * Server-side action which adds a new month to the database
 * @param locationId location of the bill
 * @param billId ID of the bill
 * @param prevState previous state of the form
 * @param formData form data
 * @returns 
 */
export const addMonth = withUser(async (user:AuthenticatedUser, { year, month }: YearMonth) => {
    noStore();
    
    const { id: userId } = user;

    // update the bill in the mongodb
    const dbClient = await getDbClient();

    const prevYear = month === 1 ? year - 1 : year;
    const prevMonth = month === 1 ? 12 : month - 1;

    // find all locations for the previous month
    const prevMonthLocations = await dbClient.collection<BillingLocation>("lokacije").find({
        userId, // make sure that the locations belongs to the user
        yearMonth: {
            year: prevYear,
            month: prevMonth,
        }
    });

    const newMonthLocationsCursor = prevMonthLocations.map((prevLocation) => {
        return({
            // copy all the properties from the previous location
            ...prevLocation,
            // assign a new ID
            _id: (new ObjectId()).toHexString(),
            yearMonth: {
                year: year,
                month: month,
            },
            // copy bill array, but set all bills to unpaid and remove attachments and notes
            bills: prevLocation.bills.map((bill) => {
                return {
                    ...bill,
                    paid: false,
                    attachment: null,
                    notes: null,
                    payedAmount: null,
                    barcodeImage: undefined,
                } as Bill
            })
        } as BillingLocation);
    });

    const newMonthLocations = await newMonthLocationsCursor.toArray()
    await dbClient.collection<BillingLocation>("lokacije").insertMany(newMonthLocations);
});

export const fetchAvailableYears = withUser(async (user:AuthenticatedUser) => {
    noStore();

    const { id: userId } = user;

    const dbClient = await getDbClient();

    // query mnogodb for all `yearMonth` values
    const years:number[] = await dbClient.collection<BillingLocation>("lokacije")
        .distinct("yearMonth.year", { userId })

    // sort the years in descending order
    const sortedYears = years.sort((a, b) => b - a);

    return(sortedYears);
})
