/**
 * Qwen Code Account Management Handlers
 *
 * Auth model: paste-token, per-account. Each `engine_accounts.credential`
 * stores a JSON blob of `{ apiKey, preset }`. The chosen preset (DashScope
 * CN/INTL, OpenRouter, Fireworks) decides the base URL — we no longer offer
 * a custom-endpoint escape hatch since every account stands alone.
 *
 * Switching/deleting active accounts disposes the project-scoped Qwen engine
 * instances so the next stream picks up the new credential.
 */

import { t } from 'elysia';
import { createRouter } from '$shared/utils/ws-server';
import { engineQueries } from '../../../database/queries';
import { disposeAllProjectEnginesByType } from '../../../engine';
import {
	parseQwenCredential,
	serializeQwenCredential,
} from '../../../engine/adapters/qwen/credential';
import type { QwenProviderPresetId } from '../../../engine/adapters/qwen/presets';

const PRESET_LITERALS = t.Union([
	t.Literal('dashscope-cn'),
	t.Literal('dashscope-intl'),
	t.Literal('openrouter'),
	t.Literal('fireworks'),
]);

async function disposeQwenEngines(): Promise<void> {
	try {
		await disposeAllProjectEnginesByType('qwen');
	} catch {
		/* engine may not be initialised — ignore */
	}
}

export const qwenAccountsHandler = createRouter()

	.http('engine:qwen-accounts-list', {
		data: t.Object({}),
		response: t.Object({
			accounts: t.Array(t.Object({
				id: t.Number(),
				name: t.String(),
				isActive: t.Boolean(),
				createdAt: t.String(),
				preset: PRESET_LITERALS,
			})),
		})
	}, async () => {
		const provider = engineQueries.getProviderBySlug('qwen', 'qwen');
		if (!provider) return { accounts: [] };
		const accounts = engineQueries.getAccountsByProvider(provider.id);
		return {
			accounts: accounts.map(a => {
				const credential = parseQwenCredential(a.credential);
				return {
					id: a.id,
					name: a.name,
					isActive: a.is_active === 1,
					createdAt: a.created_at,
					preset: credential.preset as QwenProviderPresetId,
				};
			}),
		};
	})

	.http('engine:qwen-accounts-add', {
		data: t.Object({
			name: t.String({ minLength: 1 }),
			apiKey: t.String({ minLength: 1 }),
			preset: PRESET_LITERALS,
		}),
		response: t.Object({
			account: t.Object({
				id: t.Number(),
				name: t.String(),
				isActive: t.Boolean(),
				createdAt: t.String(),
				preset: PRESET_LITERALS,
			})
		})
	}, async ({ data }) => {
		const provider = engineQueries.getProviderBySlug('qwen', 'qwen');
		if (!provider) {
			throw new Error('Qwen Code provider not found in database');
		}

		const credential = serializeQwenCredential({
			apiKey: data.apiKey.trim(),
			preset: data.preset,
		});

		const account = engineQueries.createAccount(provider.id, data.name.trim(), credential);

		if (account.is_active === 1) {
			await disposeQwenEngines();
		}

		return {
			account: {
				id: account.id,
				name: account.name,
				isActive: account.is_active === 1,
				createdAt: account.created_at,
				preset: data.preset,
			}
		};
	})

	.http('engine:qwen-accounts-switch', {
		data: t.Object({ id: t.Number() }),
		response: t.Object({ success: t.Boolean() })
	}, async ({ data }) => {
		engineQueries.switchAccount(data.id);
		await disposeQwenEngines();
		return { success: true };
	})

	.http('engine:qwen-accounts-delete', {
		data: t.Object({ id: t.Number() }),
		response: t.Object({ success: t.Boolean() })
	}, async ({ data }) => {
		const active = engineQueries.getActiveAccountForEngine('qwen');
		engineQueries.deleteAccount(data.id);
		if (active?.id === data.id) await disposeQwenEngines();
		return { success: true };
	})

	.http('engine:qwen-accounts-rename', {
		data: t.Object({ id: t.Number(), name: t.String({ minLength: 1 }) }),
		response: t.Object({ success: t.Boolean() })
	}, async ({ data }) => {
		engineQueries.renameAccount(data.id, data.name.trim());
		return { success: true };
	});
