import type { SupabaseClient, User } from "@supabase/supabase-js";

import type { CompanyContext } from "@/lib/company-context";

/*
 * Duplicar um orçamento: o trabalho da rota /api/quotes/[id]/duplicate, fora
 * dela para o assistente usar o mesmo caminho. Quem chama já conferiu a
 * pessoa e a permissão "quotes.write".
 */

export type RespostaDaDuplicacao = { status: number; corpo: Record<string, unknown> };

function resposta(corpo: Record<string, unknown>, init?: { status: number }): RespostaDaDuplicacao {
  return { status: init?.status ?? 200, corpo };
}

function isMissingColumnError(error: unknown, columnName: string) {
  if (!error || typeof error !== "object") return false;
  const message =
    typeof (error as { message?: unknown }).message === "string"
      ? ((error as { message?: string }).message || "").toLowerCase()
      : "";
  return message.includes(columnName.toLowerCase());
}

async function getNextQuoteNumber(supabase: SupabaseClient, tenantId: string) {
  const { data, error } = await supabase
    .from("quotes")
    .select("number")
    .eq("user_id", tenantId)
    .order("number", { ascending: false })
    .limit(1);

  if (error) throw error;
  const currentMax = data && data.length > 0 ? Number((data[0] as { number?: unknown } | null)?.number ?? 0) : 0;
  return currentMax + 1;
}

async function getQuoteNumberStartFrom(
  supabase: SupabaseClient,
  tenantId: string
) {
  const { data, error } = await supabase
    .from("profiles")
    .select("quote_number_start_from")
    .eq("id", tenantId)
    .maybeSingle();

  if (error) {
    if (error.code === "PGRST116" || isMissingColumnError(error, "quote_number_start_from")) return 1;
    throw error;
  }

  const rawValue = (data as { quote_number_start_from?: unknown } | null)?.quote_number_start_from;
  const parsed = Number(rawValue);
  if (!Number.isFinite(parsed)) return 1;
  return Math.max(1, Math.floor(parsed));
}

async function getNextQuoteNumberWithFloor(
  supabase: SupabaseClient,
  tenantId: string
) {
  const floor = await getQuoteNumberStartFrom(supabase, tenantId);
  const sequential = await getNextQuoteNumber(supabase, tenantId);
  return Math.max(sequential, floor);
}

export async function duplicarOrcamento(
  supabase: SupabaseClient,
  user: User,
  companyCtx: CompanyContext,
  sourceQuoteId: string
): Promise<RespostaDaDuplicacao> {
  const tenantIds = companyCtx.tenantIds?.length ? companyCtx.tenantIds : [user.id];

  const { data: sourceQuote, error: sourceQuoteError } = await supabase
    .from("quotes")
    .select("*")
    .eq("id", sourceQuoteId)
    .in("user_id", tenantIds)
    .maybeSingle();

  if (sourceQuoteError) return resposta({ error: sourceQuoteError.message }, { status: 400 });
  if (!sourceQuote) return resposta({ error: "Orçamento não encontrado." }, { status: 404 });

  const { data: sourceItems, error: sourceItemsError } = await supabase
    .from("quote_items")
    .select("*")
    .eq("quote_id", sourceQuoteId)
    .order("position", { ascending: true });

  if (sourceItemsError) return resposta({ error: sourceItemsError.message }, { status: 400 });
  if (!sourceItems || sourceItems.length === 0) {
    return resposta({ error: "Não é possível duplicar um orçamento sem itens." }, { status: 400 });
  }

  const sourceTenantId = String((sourceQuote as { user_id?: unknown }).user_id || "");
  if (!sourceTenantId) return resposta({ error: "Orçamento inválido." }, { status: 400 });

  const now = new Date().toISOString();
  const nextNumber = await getNextQuoteNumberWithFloor(supabase, sourceTenantId);
  const sourceTitle = String((sourceQuote as { title?: unknown }).title || "").trim();
  const duplicatedTitle = sourceTitle ? `${sourceTitle} (cópia)` : null;

  const insertPayload = {
    user_id: sourceTenantId,
    client_id: (sourceQuote as { client_id?: unknown }).client_id || null,
    number: nextNumber,
    status: "draft",
    title: duplicatedTitle,
    description: (sourceQuote as { description?: unknown }).description || null,
    currency: (sourceQuote as { currency?: unknown }).currency || "BRL",
    subtotal: Number((sourceQuote as { subtotal?: unknown }).subtotal || 0),
    discount: Number((sourceQuote as { discount?: unknown }).discount || 0),
    shipping: Number((sourceQuote as { shipping?: unknown }).shipping || 0),
    shipping_details: (sourceQuote as { shipping_details?: unknown }).shipping_details || null,
    total: Number((sourceQuote as { total?: unknown }).total || 0),
    expires_at: (sourceQuote as { expires_at?: unknown }).expires_at || null,
    delivery_date: (sourceQuote as { delivery_date?: unknown }).delivery_date || null,
    notes: (sourceQuote as { notes?: unknown }).notes || null,
    internal_notes: (sourceQuote as { internal_notes?: unknown }).internal_notes || null,
    list_price_mode: Boolean((sourceQuote as { list_price_mode?: unknown }).list_price_mode),
    /* As condições comerciais viajam com a cópia: quem duplica quer o mesmo
       combinado como ponto de partida. */
    payment_terms: (sourceQuote as { payment_terms?: unknown }).payment_terms ?? null,
    /* Os campos próprios também (migration 187). */
    campos_proprios: (sourceQuote as { campos_proprios?: unknown }).campos_proprios ?? {},
    seller_mode: (sourceQuote as { seller_mode?: unknown }).seller_mode || "single",
    primary_seller_user_id: (sourceQuote as { primary_seller_user_id?: unknown }).primary_seller_user_id || null,
    share_enabled: false,
    share_token: null,
    share_expires_at: null,
    public_view_count: 0,
    public_first_viewed_at: null,
    public_last_viewed_at: null,
    created_by: user.id,
    created_at: now,
    updated_at: now,
  };

  const { data: createdQuote, error: createQuoteError } = await supabase
    .from("quotes")
    .insert([insertPayload])
    .select("id,number")
    .single();

  if (createQuoteError) return resposta({ error: createQuoteError.message }, { status: 400 });

  const duplicatedQuoteId = String((createdQuote as { id?: unknown }).id || "");
  if (!duplicatedQuoteId) return resposta({ error: "Falha ao criar cópia." }, { status: 400 });

  const itemsPayload = sourceItems.map((item, index) => ({
    quote_id: duplicatedQuoteId,
    position: index + 1,
    product_id: (item as { product_id?: unknown }).product_id || null,
    unit_type: (item as { unit_type?: unknown }).unit_type || "unit",
    width_m: (item as { width_m?: unknown }).width_m || null,
    height_m: (item as { height_m?: unknown }).height_m || null,
    length_m: (item as { length_m?: unknown }).length_m || null,
    title: String((item as { title?: unknown }).title || "Item"),
    description: (item as { description?: unknown }).description || null,
    quantity: Number((item as { quantity?: unknown }).quantity || 0),
    unit_price: Number((item as { unit_price?: unknown }).unit_price || 0),
    unit_cost: Number((item as { unit_cost?: unknown }).unit_cost || 0),
    line_total: Number((item as { line_total?: unknown }).line_total || 0),
    selected_options: (item as { selected_options?: unknown }).selected_options || null,
    /* O valor mínimo do item vai junto: a cópia vale o mesmo que a original. */
    valor_minimo_aplicado: (item as { valor_minimo_aplicado?: unknown }).valor_minimo_aplicado ?? null,
    valor_sem_minimo: (item as { valor_sem_minimo?: unknown }).valor_sem_minimo ?? null,
  }));

  const { error: insertItemsError } = await supabase.from("quote_items").insert(itemsPayload);
  if (insertItemsError) {
    await supabase.from("quotes").delete().eq("id", duplicatedQuoteId);
    return resposta({ error: insertItemsError.message }, { status: 400 });
  }

  const { data: sourceAllocations } = await supabase
    .from("sale_commission_allocations")
    .select("seller_user_id,allocation_percent,allocation_basis,is_primary")
    .eq("company_id", companyCtx.companyId)
    .eq("quote_id", sourceQuoteId);

  if (sourceAllocations && sourceAllocations.length > 0) {
    await supabase.from("sale_commission_allocations").insert(
      sourceAllocations.map((allocation) => ({
        company_id: companyCtx.companyId,
        quote_id: duplicatedQuoteId,
        seller_user_id: (allocation as { seller_user_id?: unknown }).seller_user_id,
        allocation_percent: Number((allocation as { allocation_percent?: unknown }).allocation_percent || 0),
        allocation_basis: (allocation as { allocation_basis?: unknown }).allocation_basis || "revenue",
        is_primary: Boolean((allocation as { is_primary?: unknown }).is_primary),
        created_by: user.id,
      }))
    );
  }

  return resposta({
    ok: true,
    quoteId: duplicatedQuoteId,
    quoteNumber: Number((createdQuote as { number?: unknown }).number || nextNumber),
  });
}
