// tslint:disable:no-console
import * as moment from 'moment';
import * as mongoose from 'mongoose';

import { chevre } from '../../../lib/index';

// const project = { id: String(process.env.PROJECT_ID) };
const excludedProject = { id: String(process.env.EXCLUDED_PROJECT_ID) };

// tslint:disable-next-line:max-func-body-length
async function main() {
    await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });

    const eventRepo = await chevre.repository.Event.createInstance(mongoose.connection);

    const cursor = eventRepo.getCursor(
        {
            'project.id': { $ne: excludedProject.id },
            startDate: {
                $gte: moment()
                    .add(-1, 'days')
                    .toDate()
            },
            typeOf: { $eq: chevre.factory.eventType.ScreeningEvent }
            // _id: { $eq: 'blyk9q24f' }
        },
        {
            _id: 1,
            offers: 1,
            startDate: 1,
            project: 1,
            typeOf: 1
        }
    );
    console.log('events found');

    let i = 0;
    let updateCount = 0;
    await cursor.eachAsync(async (doc) => {
        i += 1;
        const event: Pick<
            chevre.factory.event.screeningEvent.IEvent,
            'id' | 'offers' | 'startDate' | 'project' | 'typeOf'
        > = doc.toObject();

        console.log(
            'alreadyMigrated?', event.project.id, event.typeOf, event.id, event.startDate, i);
        const originMakesOffer = event.offers.seller.makesOffer;
        const alreadyMigrated = !Array.isArray(originMakesOffer)
            || (Array.isArray(originMakesOffer)
                && originMakesOffer.every(
                    ({ availableAtOrFrom }) => !Array.isArray(availableAtOrFrom) && typeof availableAtOrFrom?.id === 'string'
                ));

        if (alreadyMigrated) {
            console.log(
                'already migrated.', event.project.id, event.typeOf, event.id, event.startDate, i);
        } else {
            if (Array.isArray(originMakesOffer)) {
                const newMakesOffer: chevre.factory.event.screeningEvent.ISellerMakesOffer[] = originMakesOffer.map((offer) => {
                    let newAvailableAtOrFrom: { id: string } | undefined;
                    if (Array.isArray(offer.availableAtOrFrom)) {
                        newAvailableAtOrFrom = offer.availableAtOrFrom.at(0);
                    }
                    if (newAvailableAtOrFrom === undefined) {
                        throw new Error('newAvailableAtOrFrom undefined');
                    }

                    return {
                        ...offer,
                        availableAtOrFrom: newAvailableAtOrFrom
                    };
                });
                console.log(
                    'updating project...',
                    event.project.id, event.typeOf, event.id, event.startDate, i);
                await eventRepo.updatePartiallyById({
                    project: { id: event.project.id },
                    id: event.id,
                    attributes: {
                        typeOf: event.typeOf,
                        ...{
                            'offers.seller.makesOffer': newMakesOffer
                        }
                    }
                });
                updateCount += 1;
                console.log(
                    'updated.',
                    event.project.id, event.typeOf, event.id, event.startDate, i);
            }
        }
    });

    console.log(i, 'events checked');
    console.log(updateCount, 'events updated');
}

main()
    .then()
    .catch(console.error);
