// tslint:disable:no-console
import { CognitoIdentityProvider, ListUsersInGroupCommandOutput, UserType } from '@aws-sdk/client-cognito-identity-provider';
import { fromEnv } from '@aws-sdk/credential-providers';
import * as moment from 'moment';
import * as mongoose from 'mongoose';

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

const USERPOOL_PROVIDER_NAME = (typeof process.env.DISCONTINUE_PEOPLE_USERPOOL_PROVIDER_NAME === 'string')
    ? process.env.DISCONTINUE_PEOPLE_USERPOOL_PROVIDER_NAME
    : 'SSKTS';

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

    const orderRepo = await chevre.repository.Order.createInstance(mongoose.connection);
    const settingRepo = await chevre.repository.Setting.createInstance(mongoose.connection);
    const setting = await settingRepo.findOne({ project: { id: { $eq: '*' } } }, ['userPoolIdNew']);
    if (typeof setting?.userPoolIdNew !== 'string') {
        throw new chevre.factory.errors.NotFound('setting.userPoolIdNew');
    }
    const userPoolId: string = setting.userPoolIdNew;
    const USER_GROUP_NAME = `${userPoolId}_${USERPOOL_PROVIDER_NAME}`; // 'ap-northeast-1_XXXXXXXXX_SSKTS',

    const awsCredentials = fromEnv();
    const cognitoIdentityServiceProvider = new CognitoIdentityProvider({
        apiVersion: 'latest',
        region: 'ap-northeast-1',
        credentials: awsCredentials
    });

    // create user
    const newPersonRepo = await chevre.repository.Person.createInstance({
        userPoolId: userPoolId,
        cognitoIdentityServiceProvider
    });

    const users: UserType[] = [];
    let nextToken: string | undefined = '';
    let page: number = 0;
    while (typeof nextToken === 'string') {
        // tslint:disable-next-line:no-magic-numbers
        // if (page > 1000) {
        //     break;
        // }

        page += 1;
        console.log('listUsersInGroup processing...', nextToken, page);
        const listUsersInGroupResult = <ListUsersInGroupCommandOutput>await newPersonRepo.cognitoIdentityServiceProvider.listUsersInGroup(
            {
                Limit: 50,
                UserPoolId: userPoolId,
                GroupName: USER_GROUP_NAME,
                ...(typeof nextToken === 'string' && nextToken !== '') ? { NextToken: nextToken } : undefined
            }
        );
        // tslint:disable-next-line:no-null-keyword
        console.dir(listUsersInGroupResult.Users?.at(0), { depth: null });
        nextToken = listUsersInGroupResult.NextToken;
        if (Array.isArray(listUsersInGroupResult.Users)) {
            users.push(...listUsersInGroupResult.Users);
        }
    }
    console.log('listUsersInGroup processed', nextToken, page);
    console.log(users.length, 'users found');

    const someMonthsAgo = moment()
        // tslint:disable-next-line:no-magic-numbers
        .add(-3, 'months');
    let i = 0;
    for (const user of users) {
        i += 1;
        const isSSKTSMember = user.Username?.startsWith(USERPOOL_PROVIDER_NAME, 0);
        if (!isSSKTSMember) {
            console.error(user);
            throw new Error('not ssktsMember');
        }

        const sub = user.Attributes?.find(({ Name }) => Name === 'sub')?.Value;

        // 注文が存在しなければ削除
        console.log('searching orders...', user.Username, sub, i);
        const existingOrders = await orderRepo.projectFields(
            {
                limit: 1,
                page: 1,
                customer: { ids: [String(sub)] }
            },
            { inclusion: ['orderNumber'] }
        );
        console.log(existingOrders.length, 'existingOrders found', user.Username, sub, i);

        if (existingOrders.length > 0) {
            continue;
        } else {
            if (user.UserLastModifiedDate instanceof Date) {
                if (moment(user.UserLastModifiedDate)
                    .isBefore(someMonthsAgo)) {
                    console.log('adminDeleteUser prossing...', user.Username, sub);
                    const adminDeleteUserResult = await newPersonRepo.cognitoIdentityServiceProvider.adminDeleteUser({
                        UserPoolId: userPoolId,
                        Username: user.Username
                    });
                    console.log('adminDeleteUser processed.', user.Username, sub, adminDeleteUserResult);
                }
            }

            // if (user.Enabled === true) {
            //     console.log('disabling...', user.Username, sub);
            //     // disable link provider
            //     const adminDisableUserResult = await newPersonRepo.cognitoIdentityServiceProvider.adminDisableUser({
            //         UserPoolId: userPoolId,
            //         Username: user.Username
            //     });
            //     console.log('disabled.', user.Username, sub, adminDisableUserResult);
            // } else {
            //     if (user.UserLastModifiedDate instanceof Date) {
            //         if (moment(user.UserLastModifiedDate)
            //             .isBefore(oneMonthAgo)) {
            //             console.log('adminDeleteUser prossing...', user.Username, sub);
            //             const adminDeleteUserResult = await newPersonRepo.cognitoIdentityServiceProvider.adminDeleteUser({
            //                 UserPoolId: userPoolId,
            //                 Username: user.Username
            //             });
            //             console.log('adminDeleteUser processed.', user.Username, sub, adminDeleteUserResult);
            //         }
            //     }
            // }
        }
    }

    console.log(users.length, 'users processed');
}

main()
    .then(() => {
        console.log('success!');
    })
    .catch(console.error);
