/**
 * PATCH  /api/brands/[brandId]  — edit user-facing brand metadata
 * DELETE /api/brands/[brandId]  — soft-delete the brand
 *
 * Soft-deletes a brand — sets status to "deleted" and records who
 * deactivated it and when. All data (TrackedEvent, SiteConversion,
 * MetricSnapshot, etc.) is PRESERVED. The brand disappears from the
 * app UI but remains visible in admin.meseoapp.com.
 *
 * Auth: the caller must be an org admin/owner. (Superadmin overrides
 * for plan/billing/compliance live separately at
 * /api/admin/brands/[brandId].)
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { getCurrentUser } from "@/lib/auth";
import { sanitizeBrandArray, deriveLegacyLocation, deriveLegacyServiceType } from "@/lib/brand-helpers";

export const dynamic = "force-dynamic";

// ─── PATCH (user-facing edit) ──────────────────────────────────────
//
// Accepts any subset of editable brand metadata. Arrays are sanitized
// (trim, dedupe, 20-entry / 200-char caps) before write. When an
// array field is provided in the body, the corresponding legacy
// single-string field is rewritten to stay in sync (location =
// locations[0]; serviceType = primaryServices.join(", ")), so
// consumers that haven't migrated to the array helpers keep working.
//
// Body (all optional — only fields present are updated):
//   { name?, domain?, industry?, location?, serviceType?,
//     locations?: string[], primaryServices?: string[],
//     secondaryServices?: string[] }
export async function PATCH(
  req: Request,
  ctx: { params: { brandId: string } },
) {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { brandId } = ctx.params;

  // Auth: org owner/admin only — same gate as DELETE below.
  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: { organization: { include: { memberships: true } } },
  });
  if (!brand) return NextResponse.json({ error: "Brand not found" }, { status: 404 });
  const membership = brand.organization.memberships.find((m) => m.userId === user.id);
  if (!membership || !["owner", "admin"].includes(membership.role)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const body = await req.json().catch(() => null) as Record<string, unknown> | null;
  if (!body) return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });

  const data: Record<string, unknown> = {};

  if (typeof body.name === "string" && body.name.trim()) data.name = body.name.trim();
  if (typeof body.domain === "string" && body.domain.trim()) {
    data.domain = body.domain.trim().replace(/^https?:\/\//, "").replace(/\/+$/, "");
  }
  if (typeof body.industry === "string") {
    data.industry = body.industry.trim() || null;
  } else if (body.industry === null) {
    data.industry = null;
  }

  // Sanitize array fields if present. We track which were provided
  // so we only rewrite the corresponding legacy single-string
  // field — a PATCH that only touches `locations` shouldn't clobber
  // an explicitly-set `serviceType` and vice-versa.
  let nextLocations: string[] | undefined;
  let nextPrimary: string[] | undefined;
  let nextSecondary: string[] | undefined;

  if (body.locations !== undefined) {
    const r = sanitizeBrandArray(body.locations, "locations");
    if (!r.ok) return NextResponse.json({ error: r.error }, { status: 400 });
    nextLocations = r.value;
    data.locations = r.value;
  }
  if (body.primaryServices !== undefined) {
    const r = sanitizeBrandArray(body.primaryServices, "primaryServices");
    if (!r.ok) return NextResponse.json({ error: r.error }, { status: 400 });
    nextPrimary = r.value;
    data.primaryServices = r.value;
  }
  if (body.secondaryServices !== undefined) {
    const r = sanitizeBrandArray(body.secondaryServices, "secondaryServices");
    if (!r.ok) return NextResponse.json({ error: r.error }, { status: 400 });
    nextSecondary = r.value;
    data.secondaryServices = r.value;
  }

  // Legacy single-string sync. Only rewrite when the corresponding
  // array field was provided in this PATCH; otherwise preserve the
  // brand's current legacy value (or accept an explicit override
  // from the body).
  if (nextLocations !== undefined) {
    data.location = deriveLegacyLocation(
      nextLocations,
      typeof body.location === "string" ? body.location : brand.location,
    );
  } else if (typeof body.location === "string") {
    data.location = body.location.trim() || null;
  } else if (body.location === null) {
    data.location = null;
  }
  if (nextPrimary !== undefined) {
    data.serviceType = deriveLegacyServiceType(
      nextPrimary,
      typeof body.serviceType === "string" ? body.serviceType : brand.serviceType,
    );
  } else if (typeof body.serviceType === "string") {
    data.serviceType = body.serviceType.trim() || null;
  } else if (body.serviceType === null) {
    data.serviceType = null;
  }

  if (Object.keys(data).length === 0) {
    return NextResponse.json({ error: "No editable fields supplied" }, { status: 400 });
  }

  const updated = await prisma.brand.update({
    where: { id: brandId },
    data,
    select: {
      id: true,
      name: true,
      domain: true,
      industry: true,
      location: true,
      serviceType: true,
      locations: true,
      primaryServices: true,
      secondaryServices: true,
      updatedAt: true,
    },
  });

  return NextResponse.json({ brand: updated });
}

export async function DELETE(
  _req: Request,
  ctx: { params: { brandId: string } },
) {
  const user = await getCurrentUser();
  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { brandId } = ctx.params;

  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: {
      organization: { include: { memberships: true } },
    },
  });

  if (!brand) {
    return NextResponse.json({ error: "Brand not found" }, { status: 404 });
  }

  const membership = brand.organization.memberships.find(
    (m) => m.userId === user.id,
  );
  if (!membership || !["owner", "admin"].includes(membership.role)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  await prisma.brand.update({
    where: { id: brandId },
    data: {
      status: "deleted",
      deactivatedAt: new Date(),
      deactivatedBy: user.id,
      deactivationReason: "User deleted from Brands Hub",
    },
  });

  return NextResponse.json({
    softDeleted: true,
    brandId,
    status: "deleted",
  });
}
