import { fail } from '@sveltejs/kit';
import prisma from '$lib/server/prisma';
import {
	legislationSchema,
	type FormErrors,
	type LegislationData
} from '$lib/validations/validationSchemas';
import { sendEmail } from '$lib/server/mailService';
import type { Actions, PageServerLoad } from './$types';
import type { LegislationType } from '@prisma/client';



export const load: PageServerLoad = async ({ url }) => {
	const page = parseInt(url.searchParams.get('page') || '1');
	const limit = 10;
	const offset = (page - 1) * limit;
	const search = url.searchParams.get('search') || '';

	const where = search
		? {
				OR: [
					{ title: { contains: search, mode: 'insensitive' as const } },
					{ number: { contains: search, mode: 'insensitive' as const } }
				]
			}
		: {};

	const [legislations, totalCount] = await Promise.all([
		prisma.legislationItem.findMany({
			where,
			orderBy: [{ year: 'desc' }, { type: 'asc' }, { number: 'asc' }],
			skip: offset,
			take: limit
		}),
		prisma.legislationItem.count({ where })
	]);

	return {
		legislations,
		totalCount,
		page,
		totalPages: Math.ceil(totalCount / limit),
		search
	};
};

export const actions: Actions = {
    create: async ({ request, url }) => {
        const formData = await request.formData();

        const data = {
            year: parseInt(formData.get('year') as string),
            type: formData.get('type') as LegislationType,
            number: (formData.get('number') as string) || null,
            title: (formData.get('title') as string) || null,
            parentStatute: (formData.get('parentStatute') as string) || null,
            sponsor: (formData.get('sponsor') as string) || null,
            house: (formData.get('house') as string) || null,
            legislativeEffects: (formData.get('legislativeEffects') as string) || null,
            dateGazetted: formData.get('dateGazetted') ? new Date(formData.get('dateGazetted') as string) : null,
            gazetteDetails: (formData.get('gazetteDetails') as string) || null,
            availabilityAt: formData.get('availabilityAt') ? new Date(formData.get('availabilityAt') as string) : null,
            uploadedAt: formData.get('uploadedAt') ? new Date(formData.get('uploadedAt') as string) : null,
            kgsPublicationAt: formData.get('kgsPublicationAt')
                ? new Date(formData.get('kgsPublicationAt') as string)
                : null,
            commencementAt: formData.get('commencementAt') ? new Date(formData.get('commencementAt') as string) : null,
            pagination: (formData.get('pagination') as string) || null,
            statusOnDatabase: (formData.get('statusOnDatabase') as string) || null,
            legislativeUpdates: (formData.get('legislativeUpdates') as string) || null,
            comments: (formData.get('comments') as string) || null,
            kenyaGazetteSuppNo: (formData.get('kenyaGazetteSuppNo') as string) || null,
            revocationsAmendments: (formData.get('revocationsAmendments') as string) || null,
            assentAt: formData.get('assentAt') ? new Date(formData.get('assentAt') as string) : null,
            dateAvailedAt: formData.get('dateAvailedAt') ? new Date(formData.get('dateAvailedAt') as string) : null,
            availability: (formData.get('availability') as string) || null
        };

        const result = legislationSchema.safeParse(data);
        if (!result.success) {
            const errors: FormErrors<LegislationData> = {};
            for (const [key, value] of Object.entries(result.error.flatten().fieldErrors)) {
                errors[key as keyof LegislationData] = value;
            }
            return fail(400, { data, errors });
        }

        try {
            // Save to DB (use cast if TS complains about shape)
            const newLegislation = await prisma.legislationItem.create({
                data: result.data as any
            });

            // Fire-and-forget background email task so response is not delayed
            void (async () => {
                try {
                    const subscribers = await prisma.user.findMany({ select: { email: true } });
                    if (subscribers.length === 0) return;

                    const origin = url.origin;
                    const legislationData = {
                        title: newLegislation.title ?? 'Untitled Legislation',
                        category: newLegislation.type ?? 'General',
                        summary:
                            newLegislation.legislativeUpdates ||
                            newLegislation.comments ||
                            'New legislation has been added to the Kenya Law database.',
                        datePublished: newLegislation.dateGazetted?.toISOString() ?? new Date().toISOString(),
                        link: `${origin}/legislation/${newLegislation.id}`
                    };

                    await Promise.allSettled(
                        subscribers.map((subscriber) =>
                            sendEmail(
                                subscriber.email,
                                `New Legislation Published – ${legislationData.title}`,
                                'new-legislation',
                                { legislation: legislationData, origin }
                            ).catch((emailError) =>
                                console.error(`Failed to send email to ${subscriber.email}:`, emailError)
                            )
                        )
                    );
                } catch (bgError) {
                    console.error('Background email task failed:', bgError);
                }
            })();

            // Return success immediately so client enhance handler receives success and can close modal
            return { success: true, legislation: newLegislation };
        } catch (error) {
            console.error('Error creating legislation:', error);
            return fail(500, {
                data,
                errors: { _errors: ['Failed to create legislation item'] }
            });
        }
    },

	update: async ({ request, url }) => {
        const formData = await request.formData();
        const id = parseInt(formData.get('id') as string);

        const data = {
            year: parseInt(formData.get('year') as string),
            type: formData.get('type') as string,
            number: (formData.get('number') as string) || null,
            title: (formData.get('title') as string) || null,
            parentStatute: (formData.get('parentStatute') as string) || null,
            sponsor: (formData.get('sponsor') as string) || null,
            house: (formData.get('house') as string) || null,
            legislativeEffects: (formData.get('legislativeEffects') as string) || null,
            dateGazetted: formData.get('dateGazetted') ? new Date(formData.get('dateGazetted') as string) : null,
            gazetteDetails: (formData.get('gazetteDetails') as string) || null,
            availabilityAt: formData.get('availabilityAt') ? new Date(formData.get('availabilityAt') as string) : null,
            uploadedAt: formData.get('uploadedAt') ? new Date(formData.get('uploadedAt') as string) : null,
            kgsPublicationAt: formData.get('kgsPublicationAt')
                ? new Date(formData.get('kgsPublicationAt') as string)
                : null,
            commencementAt: formData.get('commencementAt') ? new Date(formData.get('commencementAt') as string) : null,
            pagination: (formData.get('pagination') as string) || null,
            statusOnDatabase: (formData.get('statusOnDatabase') as string) || null,
            legislativeUpdates: (formData.get('legislativeUpdates') as string) || null,
            comments: (formData.get('comments') as string) || null,
            kenyaGazetteSuppNo: (formData.get('kenyaGazetteSuppNo') as string) || null,
            revocationsAmendments: (formData.get('revocationsAmendments') as string) || null,
            assentAt: formData.get('assentAt') ? new Date(formData.get('assentAt') as string) : null,
            dateAvailedAt: formData.get('dateAvailedAt') ? new Date(formData.get('dateAvailedAt') as string) : null,
            availability: (formData.get('availability') as string) || null
        };

        const result = legislationSchema.safeParse(data);
        if (!result.success) {
            const errors: FormErrors<LegislationData> = {};
            for (const [key, value] of Object.entries(result.error.flatten().fieldErrors)) {
                errors[key as keyof LegislationData] = value;
            }
            return fail(400, { data, errors, id });
        }

        try {
                // 1. Update legislation in DB
                const updatedLegislation = await prisma.legislationItem.update({
                    where: { id },
                    data: result.data as any
                });

                // 2. Fetch subscribers
                const subscribers = await prisma.user.findMany({
                    select: { email: true }
                });

                const sendNotifications = formData.get('sentnotifications') === 'on';

                if (sendNotifications && subscribers.length > 0) {
                    const origin = url.origin;
                    const legislationData = {
                        title: updatedLegislation.title ?? 'Untitled Legislation',
                        category: updatedLegislation.type ?? 'General',
                        summary:
                            updatedLegislation.legislativeUpdates ||
                            updatedLegislation.comments ||
                            'A legislation item has been updated on Kenya Law.',
                        dateUpdated: new Date().toISOString(),
                        link: `${origin}/legislation/${updatedLegislation.id}`
                    };

                    // ✅ Run email sending in the background (non-blocking)
                    (async () => {
                        await Promise.allSettled(
                            subscribers.map(async (subscriber) => {
                                try {
                                    await sendEmail(
                                        subscriber.email,
                                        `Legislation Updated – ${legislationData.title}`,
                                        'legislation-update',
                                        { legislation: legislationData, origin }
                                    );
                                    console.log(`✅ Sent update email to ${subscriber.email}`);
                                } catch (err) {
                                    console.error(`❌ Failed to send to ${subscriber.email}:`, err);
                                }
                            })
                        );
                    })();
                } else {
                    console.log('🔕 Notifications skipped');
                }

                // ✅ Respond immediately (no waiting for emails)
                return { success: true };
            } catch (error) {
                console.error('Error updating legislation:', error);
                return fail(500, {
                    data,
                    errors: { _errors: ['Failed to update legislation item'] },
                    id
                });
            }

},


	delete: async ({ request }) => {
		const formData = await request.formData();
		const id = parseInt(formData.get('id') as string);

		try {
			await prisma.legislationItem.delete({
				where: { id }
			});
			return { success: true };
		} catch (error) {
			console.error('Error deleting legislation:', error);
			return fail(500, {
				errors: { _errors: ['Failed to delete legislation item'] }
			});
		}
	}
};
