/*
 * SPDX-License-Identifier: MPL-2.0
 *   Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

import { IgApiClient, IgLoginTwoFactorRequiredError } from 'instagram-private-api';
import Bluebird = require("bluebird");
import inquirer = require ("inquirer");
import date = require("date-and-time");
import fs = require("fs");
import path = require("path");
import https = require("https");

export class MediaItem {
    id: string = "";
    taken_at: Date = new Date();
    date_str: string = "";
    url: string = "";
    filename: string = "";

    constructor(id: string, taken_at: number, url: string) {
        this.id = id;
        this.taken_at = new Date(taken_at * 1000);
        this.date_str = date.format(this.taken_at, "YYYYMMDD");
        this.url = url;
        const filename = url.split('#').shift()?.split('?').shift()?.split('/').pop();
        if (filename)
            this.filename = filename;
        else
            this.filename = "";
    }

    public async fetch(dest_dir: string): Promise<void> {
        const dest_path = path.join(dest_dir, this.filename);
        console.log(`Downloading ${this.url} => ${dest_path}`);
        const file = fs.createWriteStream(dest_path);
        await new Promise((resolve) => {
            https.get(this.url, (response) => {
                response.pipe(file);
                file.on("finish", () => {
                    file.close();
                    resolve(response);
                });
            })
        });
        console.log(`Completed downloading ${this.url} => ${dest_path}`);
    }
}

export class UserStory extends MediaItem {
    constructor(id: string, taken_at: number, url: string) {
        super(id, taken_at, url);
    }
}

export class StoryCollection {
    users: Map<string, UserStory[]> = new Map<string, UserStory[]>();

    public length(): number {
        let cntr = 0;
        this.users.forEach(() => cntr++);
        return cntr;
    }

    public async download(base_dir: string): Promise<void> {
        await Bluebird.map(this.users.entries(), async (entry) => {
            const user = entry[0];
            const story_list = entry[1];

            const user_dir = path.join(base_dir, user);
            await this.mkdir(user_dir);

            await Bluebird.map(story_list, async (story) => {
                const story_dir = path.join(user_dir, story.date_str);
                await this.mkdir(story_dir);
                await story.fetch(story_dir);
            });

            await this.dump_story_json(user_dir, story_list);
        });
    }

    private async mkdir(dir: string): Promise<void> {
        await new Promise((resolve) => {
            fs.mkdir(dir, {recursive: true}, (err) => {
                if (err)
                    console.error(err)
                else
                    console.log(`Created directory ${dir}`)
                resolve(null);
            });
        });
    }

    private async dump_story_json(dest_dir: string, stories: UserStory[]): Promise<void> {
        const d = date.format(new Date, "YYYY-MM-DDTHHmmssZ", true);
        const dest_path = path.join(dest_dir, `info_${d}.json`);
        await new Promise((resolve) => {
            fs.writeFile(dest_path, JSON.stringify(stories), (err) => {
                if (err)
                    console.error(err)
                else
                    console.log(`Written info to ${dest_path}`)
                resolve(null);
            });
        });
    }
}

export class Client
{
    ig = new IgApiClient();

    constructor(seed?: string) {
        if (seed === undefined)
            seed = `ig-story-dl-${date.format(new Date(), "YYYYMMDDHH")}`
        this.ig.state.generateDevice(seed);
    }

    public async login(username: string) {
        await this.ig.simulate.preLoginFlow();

        const { passwd } = await inquirer.prompt([
            {
                type: 'password',
                name: 'passwd',
                message: `Enter password for ${username}`,
            },
        ]);

        await Bluebird.try(() => this.ig.account.login(username, passwd)).catch(
            IgLoginTwoFactorRequiredError,
            async err => {
                const {username, totp_two_factor_on, two_factor_identifier} = err.response.body.two_factor_info;
                const verificationMethod: string = totp_two_factor_on ? '0' : '0';
                const { code } = await inquirer.prompt([
                    {
                        type: 'input',
                        name: 'code',
                        message: `Enter code received via ${verificationMethod === '1' ? 'SMS' : 'TOTP'}`,
                    },
                ]);
                return this.ig.account.twoFactorLogin({
                    username,
                    verificationCode: code,
                    twoFactorIdentifier: two_factor_identifier,
                    verificationMethod, // '1' = SMS (default), '0' = TOTP (google auth for example)
                    trustThisDevice: '0',
                });
            },
        ).catch(e => console.error('An error occurred while processing two factor auth', e, e.stack));

        console.log(`Logged in as ${username}`);
    }

    public async logout() {
        await this.ig.account.logout();
        console.log(`Logged out`);
    }

    public async get_stories(users: string[]): Promise<StoryCollection> {
        let stories = new StoryCollection();

        await Bluebird.map(users, async (user) => {
            let user_stories: UserStory[] = [];

            const target_user = await this.ig.user.searchExact(user);
            const reels_feed = this.ig.feed.reelsMedia({
                userIds: [target_user.pk]
            });
            console.info(`Fetch stories for ${target_user.pk} (${target_user.username})`)
            const story_items = await reels_feed.items();
            story_items.forEach((item) => {
                console.info(`${target_user.pk} (${target_user.username}) story item: ${item.id}`)
                if (item.image_versions2) {
                    item.image_versions2.candidates.forEach((pic) => {
                        user_stories.push(
                            new UserStory(
                                item.id,
                                item.taken_at,
                                pic.url
                            )
                        );
                        console.info(`${target_user.pk} (${target_user.username})->${item.id}: ${pic.url}`)
                    });
                }
                if (item.video_versions) {
                    item.video_versions.forEach((vid) => {
                        user_stories.push(
                            new UserStory(
                                item.id,
                                item.taken_at,
                                vid.url
                            )
                        );
                        console.info(`${target_user.pk} (${target_user.username})->${item.id}: ${vid.url}`)
                    });
                }
            });

            stories.users.set(user, user_stories);
        });

        return stories;
    }
}

export function json_replacer(key: any, value: any) {
    if (value instanceof Map) {
        return Array.from(value.entries());
    } else {
        return value;
    }
}

export class Sleeper {
    running: boolean = false;

    poll_interval: number = 1000;

    constructor(poll_interval: number = 1000) {
        this.poll_interval = poll_interval;
    }

    public async sleep_ms(ms: number): Promise<void> {
        this.running = true;
        for (let remaining_ms = ms; (remaining_ms > 0) && this.running; remaining_ms -= this.poll_interval) {
            await new Promise((resolve) => {
                setTimeout(resolve, (remaining_ms > this.poll_interval) ? this.poll_interval : remaining_ms)
            });
        }
    }

    public cancel() {
        this.running = false;
    }
}
