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

/**
 * Prazo de entrega do pedido.
 *
 * Ate agora a tela mostrava a data do orcamento por join, o que significa que
 * depois de aprovado o prazo nao podia mais ser corrigido — e pedido de balcao,
 * que nao tem orcamento, ficava sem data nenhuma. Agora o pedido tem a sua
 * propria, e esta rota e quem a altera.
 *
 * Aceita null de proposito: o prazo e opcional, e limpar precisa ser possivel
 * para quem marcou por engano.
 */

const APENAS_DATA = /^\d{4}-\d{2}-\d{2}$/;

function normalizarData(valor: unknown): { ok: true; data: string | null } | { ok: false; erro: string } {
  if (valor === null || valor === undefined || valor === "") return { ok: true, data: null };
  const texto = String(valor).trim();
  if (!APENAS_DATA.test(texto)) {
    return { ok: false, erro: "Data invalida. Use o formato AAAA-MM-DD." };
  }
  /* O regex aceita 2026-02-31; o Date desmascara. */
  const d = new Date(`${texto}T00:00:00Z`);
  if (Number.isNaN(d.getTime()) || d.toISOString().slice(0, 10) !== texto) {
    return { ok: false, erro: "Essa data nao existe no calendario." };
  }
  return { ok: true, data: texto };
}

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 { delivery_date?: unknown } | null;
  const resultado = normalizarData(body?.delivery_date);
  if (!resultado.ok) {
    return NextResponse.json({ error: resultado.erro }, { status: 400 });
  }

  /* Confere o dono antes de gravar: sem isso, um id de outra empresa passaria
     pela permissao e cairia no update. */
  const tenantIds = companyCtx.tenantIds?.length ? companyCtx.tenantIds : [user.id];
  const { data: pedido, error: erroBusca } = await supabase
    .from("orders")
    .select("id,status")
    .eq("id", id)
    .in("user_id", tenantIds)
    .maybeSingle();

  if (erroBusca) {
    return NextResponse.json({ error: "Falha ao localizar o pedido." }, { status: 400 });
  }
  if (!pedido) {
    return NextResponse.json({ error: "Pedido nao encontrado." }, { status: 404 });
  }

  /* Prazo de entrega no passado so faz sentido para um pedido que ja saiu —
     para quem ainda esta em producao, seria prometer uma entrega que ja nao
     da mais tempo de cumprir. */
  if (resultado.data) {
    const hoje = (() => {
      const d = new Date();
      return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
    })();
    const jaSaiu = ["delivered", "finished", "canceled"].includes(String(pedido.status));
    if (resultado.data < hoje && !jaSaiu) {
      return NextResponse.json(
        { error: "Esse pedido ainda não foi entregue — o prazo não pode ficar no passado." },
        { status: 400 }
      );
    }
  }

  const { error } = await supabase
    .from("orders")
    .update({ delivery_date: resultado.data, updated_at: new Date().toISOString() })
    .eq("id", id);

  if (error) {
    const mensagem = String(error.message || "");
    if (mensagem.includes("delivery_date") || mensagem.includes("schema cache")) {
      return NextResponse.json(
        { error: "A coluna delivery_date ainda nao existe no banco. Aplique a migration e tente de novo." },
        { status: 400 }
      );
    }
    return NextResponse.json({ error: "Falha ao salvar o prazo." }, { status: 400 });
  }

  return NextResponse.json({
    ok: true,
    delivery_date: resultado.data,
    message: resultado.data ? "Prazo de entrega atualizado." : "Prazo de entrega removido.",
  });
}
