import type { PageServerLoad, Actions } from './$types';
import { getDb } from '$lib/server/db';
import { redirect, fail } from '@sveltejs/kit';
import { normalizeTime, ymdInTZ } from '$lib/server/datetime';
import { resolveReminderTime, upsertPreference } from '$lib/server/preferences-helpers';

function hmInTZ(d: Date, tz: string): string {
	const parts = new Intl.DateTimeFormat('en-GB', {
		timeZone: tz,
		hour: '2-digit',
		minute: '2-digit',
		hour12: false
	}).formatToParts(d);
	const get = (t: string) => parts.find((p) => p.type === t)?.value || '';
	return `${get('hour')}:${get('minute')}`;
}

function weekdayShortInTZ(d: Date, tz: string): string {
	return new Intl.DateTimeFormat('en-GB', { timeZone: tz, weekday: 'short' }).format(d);
}


function computeNextReminder(
	freq: 'off' | 'daily' | 'weekly' | 'weekdays',
	time: string | null,
	now: Date,
	tz: string
): string | null {
	if (freq === 'off' || !time) return null;

	const nowHM = hmInTZ(now, tz);
	const [nowH, nowM] = String(nowHM).split(':');
	const [cfgH, cfgM] = String(time).split(':');
	const nowMin = (parseInt(nowH || '0', 10) || 0) * 60 + (parseInt(nowM || '0', 10) || 0);
	const cfgMin = (parseInt(cfgH || '0', 10) || 0) * 60 + (parseInt(cfgM || '0', 10) || 0);

	const allowDay = (w: string) => {
		if (freq === 'daily') return true;
		if (freq === 'weekly') return w === 'Mon';
		// weekdays
		return w !== 'Sat' && w !== 'Sun';
	};

	for (let offset = 0; offset < 14; offset++) {
		const cand = new Date(now.getTime() + offset * 24 * 60 * 60 * 1000);
		const wd = weekdayShortInTZ(cand, tz);
		if (!allowDay(wd)) continue;

		if (offset === 0 && nowMin >= cfgMin) {
			// hoy ya pasó la hora → buscar siguiente día permitido
			continue;
		}
		const ymd = ymdInTZ(cand, tz);
		return `${ymd} ${normalizeTime(time)}`;
	}
	return null;
}

export const load: PageServerLoad = async ({ locals }) => {
	const userId = locals.userId ?? null;
	if (!userId) {
		throw redirect(302, '/login');
	}

	const db = await getDb();
	const row = db
		.prepare(
			`SELECT reminder_freq AS freq, reminder_time AS time
       FROM user_preferences
       WHERE user_id = ?
       LIMIT 1`
		)
		.get(userId) as any;

	const pref =
		row && row.freq
			? { freq: String(row.freq) as 'off' | 'daily' | 'weekly' | 'weekdays', time: row.time ? String(row.time) : null }
			: { freq: 'off' as const, time: '08:30' as string };

	const tz = (process.env.TZ && process.env.TZ.trim()) || 'Europe/Madrid';
	const next = computeNextReminder(pref.freq, pref.time, new Date(), tz);

	return {
		pref,
		tz,
		next
	};
};

export const actions: Actions = {
	default: async ({ locals, request }) => {
		const userId = locals.userId ?? null;
		if (!userId) {
			throw redirect(302, '/login');
		}

		const form = await request.formData();
		const freqRaw = String(form.get('freq') || '').trim().toLowerCase();
		const timeRaw = form.has('time') ? String(form.get('time') || '').trim() : null;

		const allowed = new Set(['off', 'daily', 'weekly', 'weekdays']);
		if (!allowed.has(freqRaw)) {
			return fail(400, { error: 'freq inválida' });
		}


		const db = await getDb();

		const resolved = resolveReminderTime(db, userId, freqRaw, timeRaw);
		if ('error' in resolved) return fail(400, { error: resolved.error });
		const { timeToSave } = resolved;

		upsertPreference(db, userId, freqRaw, timeToSave);

		return { success: true, pref: { freq: freqRaw, time: timeToSave } };
	}
};
