// tslint:disable:no-console
import * as moment from 'moment-timezone';
import * as mongoose from 'mongoose';
import * as redis from 'redis';
import { ILockKey } from '../../../../lib/chevre/repo/stockHolderAbstract';
import { chevre } from '../../../../lib/index';

const client = redis.createClient<redis.RedisDefaultModules, Record<string, never>, Record<string, never>>({
    socket: {
        port: Number(<string>process.env.REDIS_PORT),
        host: <string>process.env.REDIS_HOST
    },
    password: <string>process.env.REDIS_KEY
})
    .on('error', (err) => {
        // eslint-disable-next-line no-console
        console.error('createDefaultRedisClient: client onError:', err);
        // reject(err);
    });
client.connect();
mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });

const EVENT_ID = 'cm8dwc74c';

async function main() {
    // 万が一に備えて、保留予約をredis->mongo移行するスクリプト
    const assetTransactionRepo = await chevre.repository.AssetTransaction.createInstance(mongoose.connection);
    const eventRepo = await chevre.repository.Event.createInstance(mongoose.connection);
    // const pendingReservationRepo = await chevre.repository.PendingReservation.createInstance(mongoose.connection);
    const stockHolderRepo = await chevre.repository.StockHolder.createInstance(client, mongoose.connection);

    const event = await eventRepo.projectEventFieldsById(
        { id: EVENT_ID },
        ['startDate', 'organizer', 'project', 'offers']
    );
    const hasTicketedSeat = event.offers.itemOffered.serviceOutput?.reservedTicket?.ticketedSeat?.typeOf === chevre.factory.placeType.Seat;
    const { expireTime, hash } = await stockHolderRepo.migrate2mongoJustInCase({
        eventId: EVENT_ID,
        startDate: event.startDate
        // project: { id: event.project.id },
        // provider: { id: event.organizer.id }
    });
    console.log(expireTime, hash);

    const lockKeys: ILockKey[] = [];
    const reservationNumbers: string[] = [...new Set(Object.values(hash))];
    const expires: Date = moment.unix(expireTime)
        .toDate();
    console.log('reservationNumbers:', reservationNumbers);
    console.log('expires:', expires);

    // 予約番号ごとにlockKeyを作成する
    for (const reservationNumber of reservationNumbers) {
        const reserveTransaction = (await assetTransactionRepo.search<chevre.factory.assetTransactionType.Reserve>(
            {
                limit: 1,
                page: 1,
                transactionNumber: { $eq: reservationNumber },
                typeOf: chevre.factory.assetTransactionType.Reserve,
                status: { $in: [chevre.factory.transactionStatusType.Confirmed] }
            },
            ['object', 'startDate']
        )).shift();
        if (reserveTransaction === undefined) {
            throw new Error(`reserveTransaction not found ${reservationNumber}`);
        }

        const fields: string[] = Object.keys(hash)
            .filter((field) => hash[field] === reservationNumber);
        const lockKey: ILockKey = {
            project: { id: event.project.id },
            provider: { id: event.organizer.id },
            eventId: EVENT_ID,
            startDate: event.startDate,
            hasTicketedSeat,
            offers: fields.map((field) => {
                const splitedField = field.split(':');

                return {
                    seatSection: splitedField[0],
                    seatNumber: splitedField[1]
                };
            }),
            expires,
            holder: reservationNumber,
            bookingTime: reserveTransaction.startDate
        };
        console.log('lockKey:', lockKey);
        lockKeys.push(lockKey);
        // await pendingReservationRepo.lock(lockKey);
    }
}

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