import { createSubcommand } from '../../types';
import { getAppBaseURL, UpgradeRequiredError } from '@agentuity/server';
import { saveAuth } from '../../config';
import { generateSignupOTP, pollForSignupCompletion } from './api';
import * as tui from '../../tui';
import { getCommand } from '../../command-prefix';
import { ErrorCode } from '../../errors';

export const signupCommand = createSubcommand({
	name: 'signup',
	description: 'Create a new Agentuity Cloud Platform account',
	tags: ['mutating', 'creates-resource', 'slow', 'api-intensive'],
	toplevel: true,
	skipSkill: true,
	idempotent: false,
	requires: { apiClient: true },
	examples: [
		{ command: getCommand('auth signup'), description: 'Sign up for account' },
		{ command: getCommand('signup'), description: 'Sign up for account' },
	],

	async handler(ctx) {
		const { logger, config, apiClient } = ctx;
		const appUrl = getAppBaseURL(config?.name, config?.overrides);

		try {
			const otp = generateSignupOTP();

			const signupURL = `${appUrl}/sign-up?code=${otp}`;

			const bannerBody = `Please open the URL in your browser:\n\n${tui.link(signupURL)}\n\n${tui.muted('Once you have completed the signup process, you will be given a one-time password to complete the signup process.')}`;

			tui.banner('Signup for Agentuity', bannerBody);
			tui.newline();

			await tui.spinner({
				message: 'Waiting for signup to complete...',
				clearOnSuccess: true,
				callback: async () => {
					const result = await pollForSignupCompletion(apiClient, otp);

					await saveAuth({
						apiKey: result.apiKey,
						userId: result.userId,
						expires: result.expires,
					});
				},
			});

			tui.newline();
			tui.success('Welcome to Agentuity! You are now logged in');
		} catch (error) {
			if (error instanceof UpgradeRequiredError) {
				const bannerBody = `${error.message}\n\nVisit: ${tui.link('https://agentuity.dev/Get-Started/installation')}`;
				tui.banner('CLI Upgrade Required', bannerBody);
				process.exit(1);
			} else if (error instanceof Error) {
				logger.fatal(`Signup failed: ${error.message}`, ErrorCode.AUTH_FAILED);
			} else {
				logger.fatal('Signup failed', ErrorCode.AUTH_FAILED);
			}
		}
	},
});
