import { json } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import type { RequestHandler } from './$types';

type ChatRole = 'user' | 'assistant';

type ChatMessage = {
	role?: ChatRole;
	content?: string;
};

type UnifiedState = {
	activeDomain?: 'fitness' | 'brain';
	fitnessState?: Record<string, unknown>;
	brainState?: Record<string, unknown>;
};

function recentMessages(messages: unknown): Array<{ role: ChatRole; content: string }> {
	if (!Array.isArray(messages)) return [];
	return messages
		.filter((message) => !!message && typeof message === 'object')
		.map((message) => {
			const item = message as ChatMessage;
			return {
				role: item.role === 'assistant' ? 'assistant' : 'user',
				content: typeof item.content === 'string' ? item.content : ''
			};
		})
		.filter((message) => message.content.trim())
		.slice(-16);
}

function lastUserMessage(messages: Array<{ role: ChatRole; content: string }>): string {
	return [...messages].reverse().find((message) => message.role === 'user')?.content?.trim() || '';
}

function isFitnessIntent(text: string): boolean {
	return /\b(calories?|protein|carbs?|fat|sugar|fiber|breakfast|lunch|dinner|snack|meal|food|ate|eaten|log|track|entries|macros?)\b/i.test(text)
		|| /\bfor (breakfast|lunch|dinner|snack)\b/i.test(text)
		|| /\bhow many calories do i have left\b/i.test(text);
}

function isBrainIntent(text: string): boolean {
	return /\b(note|notes|brain|remember|save this|save that|what do i have|what have i saved|find my|delete (?:that|this|note|item)|update (?:that|this|note)|from my notes)\b/i.test(text);
}

function detectDomain(
	messages: Array<{ role: ChatRole; content: string }>,
	state: UnifiedState,
	imageDataUrl?: string | null
): 'fitness' | 'brain' {
	const text = lastUserMessage(messages);
	if (imageDataUrl) return 'fitness';
	if (!text) return state.activeDomain || 'brain';

	const fitness = isFitnessIntent(text);
	const brain = isBrainIntent(text);

	if (fitness && !brain) return 'fitness';
	if (brain && !fitness) return 'brain';

	if (state.activeDomain === 'fitness' && !brain) return 'fitness';
	if (state.activeDomain === 'brain' && !fitness) return 'brain';

	return fitness ? 'fitness' : 'brain';
}

export const POST: RequestHandler = async ({ request, fetch, cookies }) => {
	if (!cookies.get('platform_session')) {
		return json({ error: 'Unauthorized' }, { status: 401 });
	}

	const { messages = [], state = {}, imageDataUrl = null, entryDate = null, action = 'chat', allowBrain = true } = await request
		.json()
		.catch(() => ({}));

	let brainEnabled = !!allowBrain;
	try {
		const gatewayUrl = env.GATEWAY_URL || 'http://localhost:8100';
		const session = cookies.get('platform_session');
		if (session) {
			const auth = await fetch(`${gatewayUrl}/api/auth/me`, {
				headers: { Cookie: `platform_session=${session}` }
			});
			if (auth.ok) {
				const data = await auth.json().catch(() => null);
				if (data?.authenticated && data?.user?.username === 'madiha') {
					brainEnabled = false;
				}
			}
		}
	} catch {
		// keep requested allowBrain fallback
	}

	const chat = recentMessages(messages);
	const unifiedState: UnifiedState = state && typeof state === 'object' ? state : {};
	const domain = brainEnabled ? detectDomain(chat, unifiedState, imageDataUrl) : 'fitness';

	const response = await fetch(domain === 'fitness' ? '/assistant/fitness' : '/assistant/brain', {
		method: 'POST',
		headers: { 'content-type': 'application/json' },
		body: JSON.stringify(
			domain === 'fitness'
				? {
						action,
						messages,
						draft: unifiedState.fitnessState && 'draft' in unifiedState.fitnessState ? unifiedState.fitnessState.draft : null,
						drafts: unifiedState.fitnessState && 'drafts' in unifiedState.fitnessState ? unifiedState.fitnessState.drafts : [],
						entryDate,
						imageDataUrl
					}
				: {
						messages,
						state: unifiedState.brainState || {}
					}
		)
	});

	const body = await response.json().catch(() => ({}));
	if (!response.ok) {
		return json(body, { status: response.status });
	}

	return json({
		...body,
		domain,
		state: {
			activeDomain: domain,
			fitnessState:
				domain === 'fitness'
					? {
							draft: body?.draft ?? null,
							drafts: Array.isArray(body?.drafts) ? body.drafts : []
						}
					: unifiedState.fitnessState || {},
			brainState: domain === 'brain' ? body?.state || {} : unifiedState.brainState || {}
		}
	});
};
