import type { GoogleUserInfo } from '$lib/server/google-auth';
import {
	assignMemberLangganan,
	getPaketByKode
} from '$lib/server/langganan';
import {
	createMember,
	findMemberByEmail,
	findMemberByGoogleId,
	linkMemberGoogle
} from '$lib/server/member';
import type { CreateMemberInput, MemberSession } from '$lib/types/member';

export interface RegisterEmailInput {
	nama: string;
	email: string;
	password: string;
}

export type RegisterResult =
	| { ok: true; member: MemberSession }
	| { ok: false; error: string; field?: string };

async function assignFreePaket(memberId: number): Promise<void> {
	const freePaket = await getPaketByKode('free');
	if (!freePaket) return;

	await assignMemberLangganan({
		memberId,
		paketId: freePaket.id,
		interval: 'bulanan',
		keterangan: 'Paket gratis saat registrasi'
	});
}

export async function registerWithEmail(input: RegisterEmailInput): Promise<RegisterResult> {
	const nama = input.nama.trim();
	const email = input.email.trim().toLowerCase();

	if (!nama || nama.length < 2) {
		return { ok: false, error: 'Nama minimal 2 karakter.', field: 'nama' };
	}
	if (!email || !email.includes('@')) {
		return { ok: false, error: 'Email tidak valid.', field: 'email' };
	}
	if (!input.password || input.password.length < 6) {
		return { ok: false, error: 'Password minimal 6 karakter.', field: 'password' };
	}

	const existing = await findMemberByEmail(email);
	if (existing) {
		if (existing.google_id && !existing.password) {
			return {
				ok: false,
				error: 'Email sudah terdaftar via Google. Silakan masuk dengan Google.',
				field: 'email'
			};
		}
		return { ok: false, error: 'Email sudah terdaftar. Silakan masuk.', field: 'email' };
	}

	const memberId = await createMember({
		nama,
		email,
		password: input.password
	} satisfies CreateMemberInput);

	await assignFreePaket(memberId);

	return {
		ok: true,
		member: { id: memberId, nama, email }
	};
}

export async function authenticateWithGoogle(
	user: GoogleUserInfo
): Promise<RegisterResult> {
	const email = user.email.trim().toLowerCase();
	const nama = user.name?.trim() || email.split('@')[0];

	let member = await findMemberByGoogleId(user.id);

	if (!member) {
		const byEmail = await findMemberByEmail(email);
		if (byEmail) {
			await linkMemberGoogle(byEmail.id, {
				google_id: user.id,
				avatar_url: user.picture ?? null
			});
			member = await findMemberByGoogleId(user.id);
		}
	}

	if (!member) {
		const memberId = await createMember({
			nama,
			email,
			password: null,
			google_id: user.id,
			avatar_url: user.picture ?? null
		});
		await assignFreePaket(memberId);
		member = { id: memberId, nama, email };
	}

	return { ok: true, member };
}
