import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';

export const dynamic = 'force-dynamic';

// In-memory cache: { key: { data, fetchedAt } }
const weatherCache = new Map<string, { data: any; fetchedAt: number }>();
const CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes

export async function GET(request: NextRequest) {
    const session = await getServerSession(authOptions);
    const userId = (session?.user as any)?.id;
    if (!userId) {
        return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { weatherEnabled: true, weatherLat: true, weatherLon: true },
    });

    if (!user?.weatherLat || !user.weatherLon) {
        return NextResponse.json({ error: 'Weather not configured' }, { status: 400 });
    }

    const { searchParams } = new URL(request.url);
    const startDate = searchParams.get('start') || new Date().toISOString().slice(0, 10);
    const endDate = searchParams.get('end') || startDate;

    const cacheKey = `${user.weatherLat},${user.weatherLon},${startDate},${endDate}`;
    const cached = weatherCache.get(cacheKey);
    if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
        return NextResponse.json(cached.data);
    }

    try {
        const url = `https://api.open-meteo.com/v1/forecast?latitude=${user.weatherLat}&longitude=${user.weatherLon}&hourly=temperature_2m,apparent_temperature,weather_code,wind_speed_10m,wind_gusts_10m,precipitation_probability,precipitation,relative_humidity_2m,uv_index&start_date=${startDate}&end_date=${endDate}&timezone=auto`;
        const res = await fetch(url, { next: { revalidate: 900 } });

        if (!res.ok) {
            return NextResponse.json({ error: 'Weather API failed' }, { status: 502 });
        }

        const raw = await res.json();

        const hourly: Record<string, {
            temp: number; code: number;
            feelsLike?: number; wind?: number; gusts?: number;
            precipProb?: number; precip?: number; humidity?: number; uv?: number;
        }> = {};
        if (raw.hourly?.time) {
            for (let i = 0; i < raw.hourly.time.length; i++) {
                hourly[raw.hourly.time[i]] = {
                    temp: Math.round(raw.hourly.temperature_2m?.[i] ?? 0),
                    code: raw.hourly.weather_code?.[i] ?? 0,
                    feelsLike: raw.hourly.apparent_temperature?.[i] != null ? Math.round(raw.hourly.apparent_temperature[i]) : undefined,
                    wind: raw.hourly.wind_speed_10m?.[i] != null ? Math.round(raw.hourly.wind_speed_10m[i]) : undefined,
                    gusts: raw.hourly.wind_gusts_10m?.[i] != null ? Math.round(raw.hourly.wind_gusts_10m[i]) : undefined,
                    precipProb: raw.hourly.precipitation_probability?.[i] ?? undefined,
                    precip: raw.hourly.precipitation?.[i] != null ? Math.round(raw.hourly.precipitation[i] * 10) / 10 : undefined,
                    humidity: raw.hourly.relative_humidity_2m?.[i] ?? undefined,
                    uv: raw.hourly.uv_index?.[i] != null ? Math.round(raw.hourly.uv_index[i] * 10) / 10 : undefined,
                };
            }
        }

        const data = { hourly, timezone: raw.timezone };
        weatherCache.set(cacheKey, { data, fetchedAt: Date.now() });

        return NextResponse.json(data);
    } catch (err) {
        console.error('[WEATHER] Fetch failed:', err);
        return NextResponse.json({ error: 'Weather fetch failed' }, { status: 500 });
    }
}
