import type { Handle } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';

const gatewayUrl = env.GATEWAY_URL || 'http://localhost:8100';
const devAutoLogin = ['1', 'true', 'yes', 'on'].includes((env.DEV_AUTO_LOGIN || '').toLowerCase());
const immichUrl = env.IMMICH_URL || '';
const immichApiKey = env.IMMICH_API_KEY || '';
const karakeepUrl = env.KARAKEEP_URL || '';
const karakeepApiKey = env.KARAKEEP_API_KEY || '';

export const handle: Handle = async ({ event, resolve }) => {
	function shouldUseDevAutoLogin(): boolean {
		if (!devAutoLogin) return false;
		const host = event.url.host.toLowerCase();
		return host.includes(':4174') || host.startsWith('test.');
	}

	function normalizeSetCookieForHttp(value: string): string {
		// The gateway issues Secure cookies by default. On local HTTP dev hosts
		// like 192.168.x.x or localhost, browsers drop those cookies entirely.
		// Relax only at the frontend proxy boundary when the current app URL is HTTP.
		if (event.url.protocol !== 'http:') return value;
		return value.replace(/;\s*Secure/gi, '');
	}

	async function isAuthenticated(request: Request): Promise<boolean> {
		const cookie = request.headers.get('cookie') || '';
		if (!cookie.includes('platform_session=') && !shouldUseDevAutoLogin()) return false;
		try {
			const headers: Record<string, string> = {};
			if (cookie) headers.cookie = cookie;
			if (shouldUseDevAutoLogin()) headers['X-Dev-Auto-Login'] = '1';
			const res = await fetch(`${gatewayUrl}/api/auth/me`, { headers });
			if (!res.ok) return false;
			const data = await res.json();
			return data.authenticated === true;
		} catch {
			return false;
		}
	}

	// ── Immich API proxy (shared across all pages) ──
	if (event.url.pathname.startsWith('/api/immich/') && immichUrl && immichApiKey) {
		if (!await isAuthenticated(event.request)) {
			return new Response(JSON.stringify({ error: 'Unauthorized' }), {
				status: 401, headers: { 'Content-Type': 'application/json' }
			});
		}
		const immichPath = event.url.pathname.replace('/api/immich', '/api');

		// Thumbnail/original image proxy — cache-friendly binary response
		if (immichPath.includes('/thumbnail') || immichPath.includes('/original')) {
			const assetId = event.url.pathname.split('/')[4]; // /api/immich/assets/{id}/thumbnail
			const type = immichPath.includes('/original') ? 'original' : 'thumbnail';
			try {
				const response = await fetch(`${immichUrl}/api/assets/${assetId}/${type}`, {
					headers: { 'x-api-key': immichApiKey }
				});
				return new Response(response.body, {
					status: response.status,
					headers: {
						'Content-Type': response.headers.get('Content-Type') || 'image/webp',
						'Cache-Control': 'public, max-age=86400'
					}
				});
			} catch {
				return new Response('', { status: 502 });
			}
		}

		// JSON API proxy (search, timeline, etc.)
		try {
			const targetUrl = `${immichUrl}${immichPath}${event.url.search}`;
			const reqHeaders: Record<string, string> = { 'x-api-key': immichApiKey };
			const ct = event.request.headers.get('content-type');
			if (ct) reqHeaders['content-type'] = ct;

			const response = await fetch(targetUrl, {
				method: event.request.method,
				headers: reqHeaders,
				body: event.request.method !== 'GET' && event.request.method !== 'HEAD'
					? await event.request.arrayBuffer()
					: undefined
			});

			// For search results, strip down to minimal fields to avoid huge payloads
			if (immichPath.includes('/search/') && response.ok) {
				const data = await response.json();
				if (data.assets?.items) {
					data.assets.items = data.assets.items.map((a: Record<string, unknown>) => ({
						id: a.id,
						type: a.type,
						fileCreatedAt: a.fileCreatedAt,
						originalFileName: a.originalFileName
					}));
				}
				return new Response(JSON.stringify(data), {
					status: 200,
					headers: { 'Content-Type': 'application/json' }
				});
			}

			const responseHeaders = new Headers();
			for (const [key, value] of response.headers.entries()) {
				responseHeaders.append(key, value);
			}
			return new Response(response.body, { status: response.status, headers: responseHeaders });
		} catch {
			return new Response(JSON.stringify({ error: 'Immich unavailable' }), {
				status: 502, headers: { 'Content-Type': 'application/json' }
			});
		}
	}

	// ── Karakeep API proxy (server-to-server) ──
	if (event.url.pathname.startsWith('/api/karakeep/') && karakeepUrl && karakeepApiKey) {
		if (!await isAuthenticated(event.request)) {
			return new Response(JSON.stringify({ error: 'Unauthorized' }), {
				status: 401, headers: { 'Content-Type': 'application/json' }
			});
		}
		const action = event.url.pathname.split('/').pop(); // 'save' or 'delete'
		try {
			const body = await event.request.json();

			if (action === 'save' && body.url) {
				const response = await fetch(`${karakeepUrl}/api/v1/bookmarks`, {
					method: 'POST',
					headers: {
						'Authorization': `Bearer ${karakeepApiKey}`,
						'Content-Type': 'application/json'
					},
					body: JSON.stringify({ type: 'link', url: body.url })
				});
				const data = await response.json();
				if (response.ok) {
					return new Response(JSON.stringify({ ok: true, id: data.id || '' }), {
						status: 200, headers: { 'Content-Type': 'application/json' }
					});
				}
				return new Response(JSON.stringify({ error: 'Save failed', status: response.status }), {
					status: response.status, headers: { 'Content-Type': 'application/json' }
				});
			}

			if (action === 'delete' && body.id) {
				const response = await fetch(`${karakeepUrl}/api/v1/bookmarks/${body.id}`, {
					method: 'DELETE',
					headers: { 'Authorization': `Bearer ${karakeepApiKey}` }
				});
				return new Response(JSON.stringify({ ok: response.ok }), {
					status: 200, headers: { 'Content-Type': 'application/json' }
				});
			}

			return new Response(JSON.stringify({ error: 'Invalid request' }), {
				status: 400, headers: { 'Content-Type': 'application/json' }
			});
		} catch (err) {
			console.error('Karakeep proxy error:', err);
			return new Response(JSON.stringify({ error: 'Karakeep unavailable', detail: String(err) }), {
				status: 502, headers: { 'Content-Type': 'application/json' }
			});
		}
	}

	// Legacy trips-specific Immich thumbnail (keep for backward compat)
	if (event.url.pathname.startsWith('/api/trips/immich/thumb/') && immichUrl && immichApiKey) {
		if (!await isAuthenticated(event.request)) {
			return new Response('', { status: 401 });
		}
		const assetId = event.url.pathname.split('/').pop();
		try {
			const response = await fetch(`${immichUrl}/api/assets/${assetId}/thumbnail`, {
				headers: { 'x-api-key': immichApiKey }
			});
			return new Response(response.body, {
				status: response.status,
				headers: {
					'Content-Type': response.headers.get('Content-Type') || 'image/webp',
					'Cache-Control': 'public, max-age=86400'
				}
			});
		} catch {
			return new Response('', { status: 502 });
		}
	}

	// Proxy all /api/* requests to the gateway
	if (event.url.pathname.startsWith('/api/') || event.url.pathname.startsWith('/images/')) {
		// Rewrite /images/trips/* to /api/trips/images/* for gateway routing
		let targetPath = event.url.pathname;
		if (targetPath.startsWith('/images/trips/')) {
			targetPath = '/api/trips' + targetPath.replace('/images/trips', '/images');
		} else if (targetPath.startsWith('/images/fitness/')) {
			targetPath = '/api/fitness' + targetPath.replace('/images/fitness', '/images');
		}

		const targetUrl = `${gatewayUrl}${targetPath}${event.url.search}`;
		const headers = new Headers();

		// Forward all relevant headers
		for (const [key, value] of event.request.headers.entries()) {
			if (['authorization', 'content-type', 'cookie', 'x-api-key', 'x-telegram-user-id'].includes(key.toLowerCase())) {
				headers.set(key, value);
			}
		}
		if (shouldUseDevAutoLogin()) {
			headers.set('X-Dev-Auto-Login', '1');
		}

		try {
			const response = await fetch(targetUrl, {
				method: event.request.method,
				headers,
				body: event.request.method !== 'GET' && event.request.method !== 'HEAD'
					? await event.request.arrayBuffer()
					: undefined
			});

			// Forward set-cookie headers from gateway
			const responseHeaders = new Headers();
			for (const [key, value] of response.headers.entries()) {
				if (key.toLowerCase() === 'set-cookie') {
					responseHeaders.append(key, normalizeSetCookieForHttp(value));
				} else {
					responseHeaders.append(key, value);
				}
			}

			return new Response(response.body, {
				status: response.status,
				headers: responseHeaders
			});
		} catch (error) {
			console.error('Gateway proxy error:', error);
			return new Response(JSON.stringify({ error: 'Gateway unavailable' }), {
				status: 502,
				headers: { 'Content-Type': 'application/json' }
			});
		}
	}

	return resolve(event);
};
