/**
 * GET  /api/market-position/corpus?orgId=<id>&vertical=<v>&locale=<l>
 *   Returns QueryCorpusEntry rows for the given (vertical, locale) cell.
 *
 * POST /api/market-position/corpus
 *   Body: { orgId, vertical, locale, query, conversionWeight? }
 *   Upserts a CURATED entry. Removes the entry if query is empty string.
 *
 * Authorization: caller must be owner or admin of the given org.
 * Vertical + locale are validated against the org's brand cells so a
 * tenant cannot curate cells outside their own brands.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { getCurrentUser } from "@/lib/auth";
import { getBrandCells } from "@/lib/market-position/cell";

export const dynamic = "force-dynamic";

async function resolveAdminMembership(userId: string, orgId: string) {
  return prisma.orgMembership.findUnique({
    where: { userId_orgId: { userId, orgId } },
    select: { role: true },
  });
}

/** Verify the (vertical, locale) cell belongs to at least one brand in the org. */
async function orgOwnsCell(orgId: string, vertical: string, locale: string): Promise<boolean> {
  const brands = await prisma.brand.findMany({
    where: { orgId },
    select: { id: true, industry: true, location: true, locations: true },
  });
  return brands.some((b) =>
    getBrandCells(b).some((c) => c.vertical === vertical && c.locale === locale),
  );
}

export async function GET(req: Request): Promise<Response> {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const params = new URL(req.url).searchParams;
  const orgId = params.get("orgId");
  const vertical = params.get("vertical");
  const locale = params.get("locale");

  if (!orgId) return NextResponse.json({ error: "orgId is required" }, { status: 400 });
  if (!vertical || !locale)
    return NextResponse.json({ error: "vertical and locale are required" }, { status: 400 });

  const membership = await resolveAdminMembership(user.id, orgId);
  if (!membership || !["owner", "admin"].includes(membership.role)) {
    return NextResponse.json({ error: "Org admin access required" }, { status: 403 });
  }

  if (!(await orgOwnsCell(orgId, vertical, locale))) {
    return NextResponse.json({ error: "Cell not associated with this org" }, { status: 403 });
  }

  const entries = await prisma.queryCorpusEntry.findMany({
    where: { vertical, locale },
    orderBy: [{ conversionWeight: "desc" }, { createdAt: "asc" }],
    select: {
      id: true,
      query: true,
      source: true,
      conversionWeight: true,
      lastProbedAt: true,
      createdAt: true,
    },
  });

  return NextResponse.json({ entries });
}

export async function POST(req: Request): Promise<Response> {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  let body: Record<string, unknown>;
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
  }

  const orgId = typeof body.orgId === "string" && body.orgId.trim() ? body.orgId.trim() : null;
  if (!orgId) return NextResponse.json({ error: "orgId is required" }, { status: 400 });

  const membership = await resolveAdminMembership(user.id, orgId);
  if (!membership || !["owner", "admin"].includes(membership.role)) {
    return NextResponse.json({ error: "Org admin access required" }, { status: 403 });
  }

  const vertical = typeof body.vertical === "string" ? body.vertical.trim() : "";
  const locale = typeof body.locale === "string" ? body.locale.trim() : "";
  const query = typeof body.query === "string" ? body.query.trim() : "";

  if (!vertical || !locale) {
    return NextResponse.json({ error: "vertical and locale are required" }, { status: 400 });
  }

  if (!(await orgOwnsCell(orgId, vertical, locale))) {
    return NextResponse.json({ error: "Cell not associated with this org" }, { status: 403 });
  }

  // Empty query means delete the curated entry
  if (!query) {
    const entryId = typeof body.id === "string" ? body.id.trim() : null;
    if (!entryId) {
      return NextResponse.json({ error: "id is required to delete an entry" }, { status: 400 });
    }
    // Only allow deleting CURATED entries the org controls
    const entry = await prisma.queryCorpusEntry.findUnique({
      where: { id: entryId },
      select: { source: true, vertical: true, locale: true },
    });
    if (!entry || entry.vertical !== vertical || entry.locale !== locale) {
      return NextResponse.json({ error: "Entry not found in this cell" }, { status: 404 });
    }
    if (entry.source !== "CURATED") {
      return NextResponse.json({ error: "Only CURATED entries can be deleted" }, { status: 400 });
    }
    await prisma.queryCorpusEntry.delete({ where: { id: entryId } });
    return NextResponse.json({ ok: true, deleted: true });
  }

  if (query.length < 5 || query.length > 300) {
    return NextResponse.json({ error: "query must be 5-300 characters" }, { status: 400 });
  }

  const rawWeight = typeof body.conversionWeight === "number" ? body.conversionWeight : 0;
  const conversionWeight = Math.max(0, Math.min(1, rawWeight));

  const entry = await prisma.queryCorpusEntry.upsert({
    where: { vertical_locale_query: { vertical, locale, query } },
    update: { conversionWeight, source: "CURATED" },
    create: { vertical, locale, query, source: "CURATED", conversionWeight },
  });

  return NextResponse.json({ entry });
}
