import { NextRequest, NextResponse } from 'next/server';
import webPush from 'web-push';
import { getUsersForRemindersD1, updateLastNotifiedD1 } from '@/lib/d1';

// Configure web-push
if (process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY && process.env.VAPID_PRIVATE_KEY) {
    webPush.setVapidDetails(
        process.env.VAPID_SUBJECT || 'mailto:example@yourdomain.org',
        process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY,
        process.env.VAPID_PRIVATE_KEY
    );
}

export async function GET(request: NextRequest) {
    try {
        // Protect with a secret if configured
        const authHeader = request.headers.get('authorization');
        if (process.env.CRON_SECRET && authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
            return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
        }

        const users = await getUsersForRemindersD1();
        console.log(`Cron Ping: Processing ${users.length} users...`);
        const now = new Date();
        const processed = [];

        for (const user of users) {
            if (!user.endpoint || !user.p256dh || !user.auth) continue;

            try {
                // Determine User's Local Time
                const userTimezone = user.timezone || 'UTC';
                const userDateString = now.toLocaleDateString('en-CA', { timeZone: userTimezone }); // YYYY-MM-DD
                const userTimeString = now.toLocaleTimeString('en-GB', { timeZone: userTimezone, hour: '2-digit', minute: '2-digit' }); // HH:MM

                console.log(`Checking user ${user.userId}: Time ${userTimeString} (${userTimezone}) - Freq: ${user.frequency}`);

                let shouldSend = false;
                let notificationBody = '';
                let tag = '';

                if (user.frequency === 'hourly') {
                    const [currentH, currentM] = userTimeString.split(':');
                    const [startH, startM] = (user.hourlyStart || '09:00').split(':');
                    const currentHourKey = `${userDateString}-${currentH}`; // YYYY-MM-DD-HH

                    // Check active hours
                    const startStr = user.hourlyStart || '09:00';
                    const endStr = user.hourlyEnd || '21:00';

                    // Only send if we are in the time window AND the current minute matches the start minute
                    if (userTimeString >= startStr && userTimeString <= endStr && currentM === startM) {
                        if (user.lastNotifiedDate !== currentHourKey) {
                            shouldSend = true;
                            notificationBody = "How are you doing? Log your status to stay on track!";
                            tag = 'hourly-reminder';

                            // Update to match current Hour Key so we don't send again this hour
                            await updateLastNotifiedD1(user.userId, currentHourKey);
                        }
                    }

                } else {
                    // Daily
                    // Check if current user time matches reminder time
                    // We allow a small window (e.g. within the same minute). Cron runs every minute.
                    // But we also check lastNotifiedDate to ensure we only send ONCE per day.

                    if (userTimeString === user.reminderTime) {
                        if (user.lastNotifiedDate !== userDateString) {
                            shouldSend = true;
                            notificationBody = "Time to log your daily usage! Every day counts.";
                            tag = 'daily-reminder';

                            await updateLastNotifiedD1(user.userId, userDateString);
                        }
                    }
                }

                if (shouldSend) {
                    const title = user.frequency === 'hourly' ? 'QuitTraq Hourly Check-in' : 'QuitTraq Reminder';
                    const payload = JSON.stringify({
                        title: title,
                        body: notificationBody,
                        tag: tag,
                        url: '/'
                    });

                    // Use generateRequestDetails + fetch to avoid https dependency
                    const requestDetails = await webPush.generateRequestDetails(
                        {
                            endpoint: user.endpoint,
                            keys: { p256dh: user.p256dh, auth: user.auth }
                        },
                        payload
                    );

                    const response = await fetch(requestDetails.endpoint, {
                        method: 'POST',
                        headers: requestDetails.headers as Record<string, string>,
                        // @ts-expect-error - WebPush returns a Buffer which fetch in Workers supports but TS definitions might not match
                        body: requestDetails.body
                    });

                    if (!response.ok) {
                        const text = await response.text();
                        throw new Error(`Upstream error: ${response.status} ${text}`);
                    }

                    processed.push({ userId: user.userId, status: 'sent', tag });
                }

            } catch (err) {
                console.error(`Failed to process user ${user.userId}:`, err);
                processed.push({ userId: user.userId, status: 'error', error: String(err) });
                // If 410 Gone, we should delete subscription, but for now just log
            }
        }

        return NextResponse.json({ success: true, processed });
    } catch (error) {
        console.error('Cron error:', error);
        return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
    }
}
