import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { logger } from "@/lib/logger";
import { computeReputationScore } from "@/lib/marketplace-reputation";
import { routeMarketplaceRequest } from "@/lib/marketplace-router";
import type { MarketplaceNode } from "@/lib/marketplace-router";

/**
 * POST /api/marketplace/route
 *
 * Selects the best available marketplace node for a given model request.
 * Uses the marketplace router pipeline: filter → rank → select.
 */
export async function POST(request: Request) {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const body = await request.json();
    const { model, maxPricePerMToken, preferLowLatency, minReputation } = body;

    if (!model) {
      return NextResponse.json({ error: "model is required" }, { status: 400 });
    }

    // Fetch all marketplace-enabled online devices (exclude caller's own devices)
    const devices = await db.device.findMany({
      where: {
        marketplaceEnabled: true,
        NOT: { userId: session.user.id },
      },
    });

    // Build node list from device records
    const nodes: MarketplaceNode[] = devices.map((d) => {
      const models = JSON.parse(d.models || "[]") as string[];
      const reputation = computeReputationScore(d.status, d.latencyMs, d.lastSeen);
      // Convert marketplacePriceCents (cents/GPU-hour) to pricePerMToken ($/1M tokens)
      // Default $0.10/1M tokens if no price set
      const pricePerMToken = d.marketplacePriceCents != null ? d.marketplacePriceCents / 100 : 0.1;

      return {
        deviceId: d.id,
        userId: d.userId,
        name: d.name,
        status: d.status === "online" ? "online" : d.status === "degraded" ? "degraded" : "offline",
        tunnelUrl: d.tunnelUrl || "",
        models,
        pricePerMToken,
        reputationScore: reputation,
        latencyP95Ms: d.latencyMs ?? 1000,
        uptimePercent: 99, // TODO: Calculate from heartbeat data
      } satisfies MarketplaceNode;
    });

    const result = routeMarketplaceRequest(nodes, {
      model,
      maxPricePerMToken,
      preferLowLatency,
      minReputation,
    });

    if (!result) {
      return NextResponse.json(
        { error: "No available nodes for this model", model, nodesChecked: nodes.length },
        { status: 404 },
      );
    }

    logger.info(
      { userId: session.user.id, model, nodeId: result.node.deviceId, price: result.estimatedCostPerMToken },
      "marketplace_route_selected",
    );

    return NextResponse.json({
      deviceId: result.node.deviceId,
      operatorId: result.node.userId,
      tunnelUrl: result.node.tunnelUrl,
      model,
      estimatedCostPerMToken: result.estimatedCostPerMToken,
      reason: result.reason,
    });
  } catch (error) {
    logger.error({ error }, "marketplace_route_failed");
    return NextResponse.json({ error: "Internal error" }, { status: 500 });
  }
}
