import type { UserConfigPersisted } from './config.js'
import type { MtcuteFeature } from './features/types.js'
import type { PackageManager } from './package-manager.js'

import * as colors from 'colorette'
import inquirer from 'inquirer'
import { open } from 'openurl'

import { readConfig, writeConfig } from './config.js'
import { TELEGRAM_APPS_PAGE } from './constants.js'
import { getFeatureChoices } from './features/cli.js'

interface UserConfigAnswers {
    reuse?: boolean
    apiId?: string
    apiHash?: string
    botToken?: string
    features: MtcuteFeature[]
}

export interface UserConfig extends UserConfigPersisted {
    name: string
    botToken?: string
    features: MtcuteFeature[]
    packageManager: PackageManager
}

export async function askForConfigPersisted(): Promise<UserConfigPersisted> {
    const existing = await readConfig()

    if (existing) {
        const { reuse } = await inquirer.prompt<UserConfigAnswers>([
            {
                type: 'confirm',
                name: 'reuse',
                message: 'Found existing config, do you want to reuse it?',
                default: true,
            },
        ])

        if (reuse) return existing
    }

    const answers = await inquirer.prompt<UserConfigAnswers>([
        {
            type: 'input',
            name: 'apiId',
            message: 'API ID (press Enter to obtain one):',
            validate: (v: string) => {
                if (!v) {
                    // eslint-disable-next-line no-restricted-globals
                    setTimeout(() => {
                        try {
                            open(TELEGRAM_APPS_PAGE)
                        } catch {}
                    }, 1000)

                    return [
                        colors.italic(`Opening ${colors.blue(TELEGRAM_APPS_PAGE)}...`),
                        `🔒 Log in with your ${colors.blueBright('Telegram')} account`,
                        '📝 Fill out the form:',
                        `   - ${colors.bold('App title, short name')}: anything you want, can be changed later`,
                        `   - ${colors.bold('Platform')}: doesn't matter`,
                        `   - ${colors.bold('URL')}: can be left blank`,
                        `🚀 Click ${colors.bold('Create application')}`,
                        `${colors.bold(
                            colors.red('❗ DO NOT'),
                        )} share your API hash with anyone, as it can't be revoked`,
                    ].join('\n')
                }
                if (!/^\d+$/.test(v)) return 'API ID must be a number'

                return true
            },
        },
        {
            type: 'input',
            name: 'apiHash',
            message: 'API hash:',
            validate: (v: string) => {
                if (!v) return 'API hash is required'
                if (!v.match(/^[a-f0-9]{32}$/i)) return 'API hash must be 32 hex characters'

                return true
            },
        },
        {
            type: 'confirm',
            name: 'reuse',
            message: 'Do you want to save these credentials for later use?',
            default: true,
        },
    ])

    const config: UserConfigPersisted = {
        apiId: Number(answers.apiId),
        apiHash: answers.apiHash!,
    }

    if (answers.reuse) {
        await writeConfig(config)
    }

    return config
}

export async function askForConfig(packageManager: PackageManager): Promise<UserConfig> {
    const persisted = await askForConfigPersisted()

    let allowEmptyBotToken = false
    const { botToken, features } = await inquirer.prompt<UserConfigAnswers>([
        {
            type: 'input',
            name: 'botToken',
            message: 'Bot token (optional):',
            validate: (v: string) => {
                if (!v) {
                    if (allowEmptyBotToken) return true

                    allowEmptyBotToken = true

                    return [
                        `You most likely need a bot token. You can obtain one from ${colors.blue('@BotFather')}`,
                        `   Press ${colors.bold('Enter')} again if you want to create a ${colors.magenta('userbot')}`,
                    ].join('\n')
                }
                if (!v.match(/^\d+:[\w-]{16,50}$/)) return 'Invalid bot token'

                return true
            },
        },
        {
            type: 'checkbox',
            choices: getFeatureChoices(packageManager),
            name: 'features',
            message: 'Select features:',
        },
    ])

    return {
        ...persisted,
        name: '', // will be filled later
        packageManager,
        botToken: botToken || undefined,
        features,
    }
}
