import { NextResponse, NextRequest } from "next/server";
import { db } from "@/app/db/db";
import { postcodeSearch } from "@/app/db/schema/addresses";
import { eq } from "drizzle-orm";
import { lookupOsPlaces } from "@/app/api/postcode/LookupOsPlaces";
import { mapOsPlacesToFlat } from "@/app/api/postcode/OsPlacesToFlat";

export async function GET(
  request: NextRequest,
  props: { params: Promise<{ postcode: string }> }
) {
  const { postcode } = await props.params;
  if (!postcode || typeof postcode !== "string") {
    return NextResponse.json(
      { error: "Missing or invalid postcode" },
      { status: 400 }
    );
  }

  try {
    // Step 1: check cache
    const cached = await db
      .select()
      .from(postcodeSearch)
      .where(eq(postcodeSearch.postcode, postcode))
      .limit(1);

    if (cached.length > 0) {
      console.log("Using cached OS Places data for postcode:", postcode);
      const record = cached[0];
      const addresses = mapOsPlacesToFlat(record.resultData?.results);
      return NextResponse.json({
        status: 200,
        source: "cache",
        total: record.resultData?.header?.totalresults ?? addresses.length,
        results: addresses,
      });
    }

    // Step 2: if no cache, query OS Places API
    const result = await lookupOsPlaces(postcode);
    if (result.error || result.status !== 200 || !result.data) {
      return NextResponse.json(
        {
          error: result.error ?? "Failed to fetch address data",
          status: result.status,
        },
        { status: result.status }
      );
    }

    // Step 3: flatten and cache the result
    const addresses = mapOsPlacesToFlat(result.results);
    const total = result.data.header?.totalresults ?? addresses.length;

    // We shouldn't really run into conflicts here, but just in case, we allow for an update
    await db
      .insert(postcodeSearch)
      .values({
        postcode,
        resultData: result.data,
      })
      .onConflictDoUpdate({
        target: postcodeSearch.postcode,
        set: {
          resultData: result.data,
          createdAt: new Date(), // update timestamp
        },
      });

    // Step 4: return results
    return NextResponse.json({
      status: 200,
      source: "live",
      total,
      results: addresses,
    });
  } catch (err: any) {
    console.error("Error fetching OS Places data:", err);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}
