import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase-server";
import { canCompany, getCompanyContext } from "@/lib/company-context";

function normalizeText(value: unknown) {
  return String(value || "").trim();
}

function normalizeTrackingCodes(value: unknown) {
  const raw = typeof value === "string" ? value : Array.isArray(value) ? value.join("\n") : "";
  const seen = new Set<string>();
  return raw
    .split(/[\r\n,;]+/)
    .map((entry) => normalizeText(entry))
    .filter((entry) => {
      if (!entry || seen.has(entry)) return false;
      seen.add(entry);
      return true;
    });
}

function normalizeTrackingUrl(value: unknown) {
  const normalized = normalizeText(value);
  if (!normalized) return null;
  if (/^https?:\/\//i.test(normalized)) return normalized;
  return `https://${normalized}`;
}

function mapTrackingPersistenceError(error: { message?: string | null } | null | undefined) {
  const message = normalizeText(error?.message).toLowerCase();
  if (
    message.includes("shipping_tracking_codes") ||
    message.includes("shipping_tracking_url") ||
    message.includes("shipping_tracking_notes") ||
    message.includes("shipping_tracking_updated_at") ||
    message.includes("schema cache")
  ) {
    return "Os campos de rastreio ainda nao existem no banco. Aplique a migration 104_add_order_catalog_tracking_fields.sql e tente novamente.";
  }
  return normalizeText(error?.message) || "Falha ao salvar rastreio.";
}

function isCatalogOrder(order: {
  internal_notes?: string | null;
  quotes?: { title?: string | null; internal_notes?: string | null } | { title?: string | null; internal_notes?: string | null }[] | null;
}) {
  const quote = Array.isArray(order.quotes) ? order.quotes[0] : order.quotes;
  const quoteTitle = normalizeText(quote?.title).toLowerCase();
  const quoteInternalNotes = normalizeText(quote?.internal_notes).toLowerCase();
  const orderInternalNotes = normalizeText(order.internal_notes).toLowerCase();
  return (
    quoteTitle.includes("pedido do catálogo") ||
    quoteInternalNotes.includes("origem:catalogo") ||
    orderInternalNotes.includes("origem:catalogo")
  );
}

export async function POST(req: Request, ctx: { params: Promise<{ id: string }> }) {
  const { id } = await ctx.params;
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    return NextResponse.json({ error: "Nao autenticado." }, { status: 401 });
  }

  const companyCtx = await getCompanyContext(supabase, user);
  if (!canCompany(companyCtx, user.id, "orders.edit")) {
    return NextResponse.json({ error: "Sem permissao para editar pedido." }, { status: 403 });
  }

  const body = (await req.json().catch(() => null)) as
    | {
        tracking_codes?: unknown;
        tracking_url?: unknown;
        tracking_notes?: unknown;
      }
    | null;

  const tenantIds = companyCtx.tenantIds?.length ? companyCtx.tenantIds : [user.id];
  const { data: orderRow, error: orderError } = await supabase
    .from("orders")
    .select("id,user_id,internal_notes,quotes(title,internal_notes)")
    .eq("id", id)
    .in("user_id", tenantIds)
    .maybeSingle();

  if (orderError) {
    return NextResponse.json({ error: mapTrackingPersistenceError(orderError) }, { status: 400 });
  }

  if (!orderRow) {
    return NextResponse.json({ error: "Pedido nao encontrado." }, { status: 404 });
  }

  if (!isCatalogOrder(orderRow)) {
    return NextResponse.json({ error: "Rastreio manual disponivel apenas para pedidos do catalogo." }, { status: 400 });
  }

  const trackingCodes = normalizeTrackingCodes(body?.tracking_codes);
  const trackingUrl = normalizeTrackingUrl(body?.tracking_url);
  const trackingNotes = normalizeText(body?.tracking_notes) || null;
  const hasTrackingData = trackingCodes.length > 0 || Boolean(trackingUrl) || Boolean(trackingNotes);

  const payload = {
    shipping_tracking_codes: trackingCodes.length ? trackingCodes : null,
    shipping_tracking_url: trackingUrl,
    shipping_tracking_notes: trackingNotes,
    shipping_tracking_updated_at: hasTrackingData ? new Date().toISOString() : null,
  };

  const { data: updatedOrder, error: updateError } = await supabase
    .from("orders")
    .update(payload)
    .eq("id", id)
    .in("user_id", tenantIds)
    .select("shipping_tracking_codes,shipping_tracking_url,shipping_tracking_notes,shipping_tracking_updated_at")
    .single();

  if (updateError) {
    return NextResponse.json({ error: mapTrackingPersistenceError(updateError) }, { status: 400 });
  }

  return NextResponse.json({
    message: hasTrackingData ? "Rastreio atualizado com sucesso." : "Rastreio removido com sucesso.",
    tracking: updatedOrder,
  });
}
