import { createClient as createSupabaseClient } from "@supabase/supabase-js";
import { createAdminClient } from "@/lib/supabase-admin";

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

function readRecord(value: unknown) {
  return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : null;
}

function formatPaymentBrandName(value: string) {
  return value
    .split(/[_\-\s]+/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(" ");
}

function buildPaymentPresentation(params: {
  method?: string | null;
  paymentType?: string | null;
  rawRequest?: unknown;
  rawResponse?: unknown;
}) {
  const rawRequest = readRecord(params.rawRequest);
  const rawResponse = readRecord(params.rawResponse);
  const formData = readRecord(rawRequest?.formData);
  const installmentsFromRequest = Number(formData?.installments || 0);
  const installmentsFromResponse = Number(rawResponse?.installments || 0);
  const installments = installmentsFromRequest > 0 ? installmentsFromRequest : installmentsFromResponse > 0 ? installmentsFromResponse : null;
  const providerMethodId =
    normalizeText(rawResponse?.payment_method_id) ||
    normalizeText(formData?.payment_method_id) ||
    normalizeText(params.method) ||
    null;
  const paymentType = normalizeText(rawResponse?.payment_type_id) || normalizeText(params.paymentType) || null;
  const brandLabel =
    providerMethodId && !["pix", "account_money"].includes(providerMethodId)
      ? formatPaymentBrandName(providerMethodId)
      : null;

  const normalizedMethod = normalizeText(params.method);
  if (normalizedMethod === "pix") {
    return {
      methodLabel: "Pix",
      conditionsLabel: "Pix a vista",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  if (normalizedMethod === "credit_card") {
    return {
      methodLabel: brandLabel ? `Cartao de credito ${brandLabel}` : "Cartao de credito",
      conditionsLabel: installments && installments > 1 ? `${installments}x no cartao` : "A vista no cartao",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  if (normalizedMethod === "debit_card") {
    return {
      methodLabel: brandLabel ? `Cartao de debito ${brandLabel}` : "Cartao de debito",
      conditionsLabel: "A vista no cartao",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  if (normalizedMethod === "ticket") {
    return {
      methodLabel: "Boleto",
      conditionsLabel: "Pagamento por boleto",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  if (normalizedMethod === "wallet") {
    return {
      methodLabel: "Saldo em conta",
      conditionsLabel: "Pagamento a vista",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  if (normalizedMethod === "cash") {
    return {
      methodLabel: "Dinheiro",
      conditionsLabel: "Pagamento em dinheiro",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  if (normalizedMethod === "transfer") {
    return {
      methodLabel: "Transferencia",
      conditionsLabel: "Transferencia bancaria",
      providerMethodId,
      paymentType,
      installments,
    };
  }

  return {
    methodLabel: brandLabel || "Pagamento online",
    conditionsLabel: installments && installments > 1 ? `${installments}x` : "Pagamento online",
    providerMethodId,
    paymentType,
    installments,
  };
}

function generateShareToken() {
  const bytes = new Uint8Array(24);
  crypto.getRandomValues(bytes);
  return Array.from(bytes)
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

function resolveOrderPaymentStatus(params: {
  financialStatus?: string | null;
  paidAmount?: number | null;
  totalAmount?: number | null;
}) {
  const financialStatus = normalizeText(params.financialStatus).toLowerCase();
  const paidAmount = Number(params.paidAmount || 0);
  const totalAmount = Number(params.totalAmount || 0);

  if (financialStatus === "paid") return "approved";
  if (financialStatus === "partially_paid") return "partially_paid";
  if (financialStatus === "unpaid") return "unpaid";

  if (paidAmount > 0.009 && totalAmount > 0 && paidAmount + 0.01 < totalAmount) {
    return "partially_paid";
  }

  if (paidAmount > 0.009) {
    return "approved";
  }

  return "unpaid";
}

function normalizeShippingProviderLabel(value: unknown) {
  const normalized = normalizeText(value).toLowerCase();
  if (!normalized) return null;
  if (normalized === "melhor_envio") return "Melhor Envio";
  if (normalized === "superfrete") return "Super Frete";
  if (normalized === "pickup") return "Retirada no balcão";
  return normalized
    .split(/[_\-\s]+/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(" ");
}

function extractCatalogShippingDetails(value: unknown, fallbackAmount = 0) {
  const root = readRecord(value);
  if (!root) {
    return fallbackAmount > 0
      ? {
          provider_label: null,
          carrier_name: null,
          service_name: null,
          amount: fallbackAmount,
          delivery_time: null,
          destination_zip: null,
          logo_url: null,
        }
      : null;
  }

  const shipping = readRecord(root.shipping);
  const shippingRecord = shipping || root;
  const option = readRecord(shippingRecord.option);
  const amountCandidate = Number(shippingRecord.amount ?? option?.price ?? fallbackAmount ?? 0);
  const amount = Number.isFinite(amountCandidate) && amountCandidate > 0 ? amountCandidate : Math.max(0, fallbackAmount);
  const providerLabel = normalizeShippingProviderLabel(
    shippingRecord.provider_label ?? option?.provider_label ?? shippingRecord.provider ?? option?.provider
  );
  const carrierName = normalizeText(option?.name ?? shippingRecord.name) || null;
  const serviceName = normalizeText(option?.service ?? shippingRecord.service) || null;
  const deliveryTimeCandidate = Number(option?.delivery_time ?? shippingRecord.delivery_time ?? 0);
  const deliveryTime = Number.isFinite(deliveryTimeCandidate) && deliveryTimeCandidate > 0 ? deliveryTimeCandidate : null;
  const destinationZip = normalizeText(shippingRecord.destination_zip) || null;
  const logoUrl = normalizeText(option?.logo_url ?? shippingRecord.logo_url) || null;
  const provider = normalizeText(option?.provider ?? shippingRecord.provider).toLowerCase() || null;
  const pickupRecord = readRecord(option?.pickup ?? shippingRecord.pickup);
  const pickup = pickupRecord
    ? {
        name: normalizeText(pickupRecord.name) || null,
        address_summary: normalizeText(pickupRecord.address_summary) || null,
        instructions: normalizeText(pickupRecord.instructions) || null,
      }
    : null;

  if (!providerLabel && !carrierName && !serviceName && amount <= 0) {
    return null;
  }

  return {
    provider,
    provider_label: providerLabel,
    carrier_name: carrierName,
    service_name: serviceName,
    amount,
    delivery_time: deliveryTime,
    destination_zip: destinationZip,
    logo_url: logoUrl,
    pickup,
  };
}

function formatZipCode(value: string | null | undefined) {
  const digits = String(value || "").replace(/\D/g, "");
  if (digits.length !== 8) return value || null;
  return `${digits.slice(0, 5)}-${digits.slice(5)}`;
}

function extractCatalogDeliveryAddress(value: unknown) {
  const root = readRecord(value);
  if (!root) return null;

  const delivery = readRecord(root.delivery_address);
  const clientProfile = readRecord(root.client_profile);
  const selected = delivery || clientProfile;
  if (!selected) return null;

  const zip = normalizeText(delivery?.zip ?? clientProfile?.address_zip) || null;
  const street = normalizeText(delivery?.street ?? clientProfile?.address_street) || null;
  const number = normalizeText(delivery?.number ?? clientProfile?.address_number) || null;
  const complement = normalizeText(delivery?.complement ?? clientProfile?.address_complement) || null;
  const neighborhood = normalizeText(delivery?.neighborhood ?? clientProfile?.address_neighborhood) || null;
  const city = normalizeText(delivery?.city ?? clientProfile?.address_city) || null;
  const state = normalizeText(delivery?.state ?? clientProfile?.address_state) || null;
  const summary =
    normalizeText(delivery?.summary) ||
    [
      [street, number].filter(Boolean).join(", "),
      complement || "",
      neighborhood || "",
      [city, state].filter(Boolean).join(" / "),
      zip ? `CEP ${formatZipCode(zip)}` : "",
    ]
      .filter(Boolean)
      .join(" • ");

  if (!summary && !street && !zip) return null;

  return {
    source: normalizeText(delivery?.source) || "legacy_snapshot",
    label: normalizeText(delivery?.label) || null,
    recipient_name: normalizeText(delivery?.recipient_name ?? clientProfile?.company_name ?? clientProfile?.name) || null,
    phone: normalizeText(delivery?.phone ?? clientProfile?.phone ?? clientProfile?.whatsapp) || null,
    zip,
    street,
    number,
    complement,
    neighborhood,
    city,
    state,
    reference: normalizeText(delivery?.reference ?? clientProfile?.notes) || null,
    summary: summary || null,
  };
}

function normalizeTrackingCodes(value: unknown) {
  if (!Array.isArray(value)) return [];
  return value
    .map((entry) => normalizeText(entry))
    .filter(Boolean);
}

function buildDeliveryTrackingDetails(orderRow: Record<string, unknown> | null) {
  const codes = normalizeTrackingCodes(orderRow?.shipping_tracking_codes);
  const url = normalizeText(orderRow?.shipping_tracking_url) || null;
  const notes = normalizeText(orderRow?.shipping_tracking_notes) || null;
  const updatedAt = normalizeText(orderRow?.shipping_tracking_updated_at) || null;

  if (!codes.length && !url && !notes) return null;

  return {
    codes,
    url,
    notes,
    updated_at: updatedAt,
  };
}

export type ClientPortalOrderDetails = {
  status_token?: string | null;
  status_payload?: {
    profile?: {
      slug?: string | null;
      store_name?: string | null;
      catalog_name?: string | null;
      logo_url?: string | null;
      catalog_logo_url?: string | null;
      phone?: string | null;
      company_phone?: string | null;
      company_whatsapp?: string | null;
    } | null;
    client?: { name?: string | null } | null;
    quote?: { currency?: string | null; delivery_date?: string | null } | null;
    order?: {
      number?: number | null;
      status?: string | null;
      created_at?: string | null;
      updated_at?: string | null;
      total_amount?: number | null;
      paid_amount?: number | null;
      production_stage_label?: string | null;
    } | null;
  } | null;
  order: {
    id: string;
    number: number;
    created_at: string;
    updated_at?: string | null;
    status: string;
    total_amount: number;
    paid_amount?: number | null;
    financial_status?: string | null;
    production_stage_label?: string | null;
    share_token?: string | null;
    /* A data que a loja combinou para a entrega. O portal so conhecia a data do
       orcamento, e pedido de catalogo nao tem orcamento: a previsao aparecia
       como "A definir" mesmo quando a loja ja tinha uma data. */
    delivery_date?: string | null;
    /* Situacao da arte enviada na conversa: o portal usa para destacar o
       atalho de aprovacao. */
    art_status?: "pending" | "approved" | "rejected" | null;
  };
  quote?: {
    id?: string | null;
    currency?: string | null;
    subtotal?: number | null;
    discount?: number | null;
    shipping?: number | null;
    total?: number | null;
    delivery_date?: string | null;
  } | null;
  catalog_shipping?: {
    provider?: string | null;
    provider_label?: string | null;
    carrier_name?: string | null;
    service_name?: string | null;
    amount?: number | null;
    delivery_time?: number | null;
    destination_zip?: string | null;
    logo_url?: string | null;
    pickup?: {
      name?: string | null;
      address_summary?: string | null;
      instructions?: string | null;
    } | null;
  } | null;
  delivery_address?: {
    source?: string | null;
    label?: string | null;
    recipient_name?: string | null;
    phone?: string | null;
    zip?: string | null;
    street?: string | null;
    number?: string | null;
    complement?: string | null;
    neighborhood?: string | null;
    city?: string | null;
    state?: string | null;
    reference?: string | null;
    summary?: string | null;
  } | null;
  delivery_tracking?: {
    codes: string[];
    url?: string | null;
    notes?: string | null;
    updated_at?: string | null;
  } | null;
  items?: Array<{
    id: string;
    product_id?: string | null;
    product_name?: string | null;
    product_image_url?: string | null;
    title?: string | null;
    description?: string | null;
    quantity: number;
    unit_price: number;
    total_price: number;
    unit_type?: string | null;
    selected_options?: { options?: Array<{ attribute_name?: string | null; label?: string | null }> } | null;
  }>;
  payment_receipt?: {
    source?: "order" | "catalog" | null;
    provider?: string | null;
    status?: string | null;
    method?: string | null;
    method_label?: string | null;
    conditions_label?: string | null;
    provider_method_id?: string | null;
    payment_type?: string | null;
    installments?: number | null;
    status_detail?: string | null;
    reference?: string | null;
    amount?: number | null;
    currency?: string | null;
    paid_at?: string | null;
    created_at?: string | null;
    environment?: "sandbox" | "production" | string | null;
    payer_name?: string | null;
    payer_email?: string | null;
    payer_document?: string | null;
  } | null;
};

export async function getClientPortalOrderDetails(params: {
  slug: string;
  token: string;
  orderId: string;
}): Promise<ClientPortalOrderDetails | null> {
  const { slug, token, orderId } = params;
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL;
  const anon = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

  if (!url || !anon || !slug || !token || !orderId) return null;

  const supabase = createSupabaseClient(url, anon);
  const detailsResult = await supabase.rpc("client_portal_get_order_details", {
    p_slug: slug,
    p_session_token: token,
    p_order_id: orderId,
  });

  if (detailsResult.error || !detailsResult.data?.ok || !detailsResult.data?.order) return null;

  const resolved = detailsResult.data as ClientPortalOrderDetails;
  const quoteId = String(resolved?.quote?.id || "").trim();

  if (orderId) {
    try {
      const admin = createAdminClient();
      const { data: orderRow, error: orderRowError } = await admin
        .from("orders")
        .select("*")
        .eq("id", orderId)
        .maybeSingle();

      if (!orderRowError) {
        const orderRecord = readRecord(orderRow);
        let nextToken = String(orderRecord?.share_token || "").trim();
        const statusEnabled = Boolean(orderRecord?.share_enabled ?? true);

        if (!nextToken) {
          nextToken = generateShareToken();
          await admin
            .from("orders")
            .update({ share_enabled: true, share_token: nextToken } as never)
            .eq("id", orderId);
        } else if (!statusEnabled) {
          await admin.from("orders").update({ share_enabled: true } as never).eq("id", orderId);
        }

        if (nextToken) {
          resolved.status_token = nextToken;
        }

        resolved.delivery_tracking = buildDeliveryTrackingDetails(orderRecord);
        const dataDeEntrega = normalizeText(orderRecord?.delivery_date);
        if (dataDeEntrega) resolved.order.delivery_date = dataDeEntrega;
        const situacaoDaArte = normalizeText(orderRecord?.art_status);
        if (situacaoDaArte === "pending" || situacaoDaArte === "approved" || situacaoDaArte === "rejected") {
          resolved.order.art_status = situacaoDaArte;
        }
      }
    } catch {
    }
  }

  if (!String(resolved.status_token || "").trim() && quoteId) {
    try {
      const admin = createAdminClient();
      const { data: quoteRow } = await admin
        .from("quotes")
        .select("id, share_token, share_enabled")
        .eq("id", quoteId)
        .maybeSingle();

      let nextToken = String((quoteRow as { share_token?: string | null } | null)?.share_token || "").trim();
      const shareEnabled = Boolean((quoteRow as { share_enabled?: boolean | null } | null)?.share_enabled);

      if (!nextToken) {
        nextToken = generateShareToken();
        const { error: updateErr } = await admin
          .from("quotes")
          .update({ share_enabled: true, share_token: nextToken, share_expires_at: null } as never)
          .eq("id", quoteId);
        if (updateErr) {
          await admin.from("quotes").update({ share_enabled: true, share_token: nextToken } as never).eq("id", quoteId);
        }
      } else if (!shareEnabled) {
        const { error: enableErr } = await admin
          .from("quotes")
          .update({ share_enabled: true, share_expires_at: null } as never)
          .eq("id", quoteId);
        if (enableErr) {
          await admin.from("quotes").update({ share_enabled: true } as never).eq("id", quoteId);
        }
      }

      if (nextToken) resolved.status_token = nextToken;
    } catch {
    }
  }

  const statusToken = String(resolved?.status_token || "").trim();
  if (statusToken) {
    try {
      const orderStatusResult = await supabase.rpc("get_public_order_status", { p_token: statusToken });
      const orderStatusPayload = orderStatusResult?.data;
      if (!orderStatusResult.error && orderStatusPayload?.order) {
        resolved.status_payload = orderStatusPayload;
      } else {
        const statusResult = await supabase.rpc("get_public_quote", { p_token: statusToken });
        const statusPayload = statusResult?.data;
        if (!statusResult.error && statusPayload?.order) {
          resolved.status_payload = statusPayload;
        }
      }
    } catch {
    }
  }

  try {
    const admin = createAdminClient();
    const { data: catalogOrder } = await admin
      .from("catalog_orders")
      .select("id,payment_provider,payment_status,payment_method,payment_reference,paid_at,cart_payload")
      .eq("approved_order_id", resolved.order.id)
      .maybeSingle();

    if (catalogOrder?.id) {
      resolved.catalog_shipping = extractCatalogShippingDetails(
        catalogOrder.cart_payload,
        Math.max(0, Number(resolved.quote?.shipping || 0))
      );
      resolved.delivery_address = extractCatalogDeliveryAddress(catalogOrder.cart_payload);
    }

    const orderPaidAmount = Number(resolved.order.paid_amount || 0);
    const orderPaymentStatus = resolveOrderPaymentStatus({
      financialStatus: resolved.order.financial_status,
      paidAmount: resolved.order.paid_amount,
      totalAmount: resolved.order.total_amount,
    });
    const { data: orderPayments } = await admin
      .from("payments")
      .select("id,amount,payment_method,payment_date,created_at")
      .eq("order_id", resolved.order.id)
      .order("payment_date", { ascending: false, nullsFirst: false })
      .order("created_at", { ascending: false, nullsFirst: false })
      .limit(20);

    const latestOrderPayment = Array.isArray(orderPayments) ? orderPayments[0] : null;
    if (
      latestOrderPayment ||
      orderPaymentStatus === "approved" ||
      orderPaymentStatus === "partially_paid"
    ) {
      const paymentPresentation = buildPaymentPresentation({
        method:
          typeof latestOrderPayment?.payment_method === "string"
            ? latestOrderPayment.payment_method
            : null,
      });

      resolved.payment_receipt = {
        source: "order",
        provider: "admin",
        status: orderPaymentStatus,
        method:
          typeof latestOrderPayment?.payment_method === "string"
            ? latestOrderPayment.payment_method
            : null,
        method_label:
          paymentPresentation.methodLabel === "Pagamento online" && !latestOrderPayment?.payment_method
            ? "A definir"
            : paymentPresentation.methodLabel,
        conditions_label:
          orderPaymentStatus === "partially_paid"
            ? "Pagamento parcial registrado"
            : orderPaymentStatus === "approved"
              ? "Pagamento confirmado"
              : "Pagamento pendente",
        provider_method_id: paymentPresentation.providerMethodId,
        payment_type: paymentPresentation.paymentType,
        installments: paymentPresentation.installments,
        status_detail: null,
        reference: typeof latestOrderPayment?.id === "string" ? latestOrderPayment.id : null,
        amount: orderPaidAmount,
        currency: "BRL",
        paid_at:
          typeof latestOrderPayment?.payment_date === "string" && orderPaidAmount > 0.009
            ? latestOrderPayment.payment_date
            : null,
        created_at:
          typeof latestOrderPayment?.created_at === "string" ? latestOrderPayment.created_at : null,
        environment: null,
        payer_name: null,
        payer_email: null,
        payer_document: null,
      };

      return resolved;
    }

    if (catalogOrder?.id) {
      const { data: paymentRow } = await admin
        .from("catalog_order_payments")
        .select(
          "provider,status,payment_method,payment_type,provider_status_detail,provider_payment_id,amount,currency,approved_at,created_at,payer_name,payer_email,payer_document,checkout_environment,raw_request,raw_response"
        )
        .eq("catalog_order_id", catalogOrder.id)
        .order("status", { ascending: true })
        .order("approved_at", { ascending: false, nullsFirst: false })
        .order("created_at", { ascending: false })
        .limit(1)
        .maybeSingle();

      if (paymentRow || catalogOrder.payment_status) {
        const catalogStatus =
          typeof paymentRow?.status === "string" && paymentRow.status.trim()
            ? paymentRow.status
            : typeof catalogOrder.payment_status === "string" && catalogOrder.payment_status.trim()
              ? catalogOrder.payment_status
              : "unpaid";
        const paymentPresentation = buildPaymentPresentation({
          method: paymentRow?.payment_method || catalogOrder.payment_method || null,
          paymentType: paymentRow?.payment_type || null,
          rawRequest: paymentRow?.raw_request,
          rawResponse: paymentRow?.raw_response,
        });
        resolved.payment_receipt = {
          source: "catalog",
          provider: paymentRow?.provider || catalogOrder.payment_provider || null,
          status: catalogStatus,
          method: paymentRow?.payment_method || catalogOrder.payment_method || null,
          method_label: paymentPresentation.methodLabel,
          conditions_label: paymentPresentation.conditionsLabel,
          provider_method_id: paymentPresentation.providerMethodId,
          payment_type: paymentPresentation.paymentType,
          installments: paymentPresentation.installments,
          status_detail: paymentRow?.provider_status_detail || null,
          reference: paymentRow?.provider_payment_id || catalogOrder.payment_reference || null,
          amount:
            catalogStatus === "approved" || catalogStatus === "partially_paid"
              ? Number(paymentRow?.amount || resolved.order.total_amount || 0)
              : 0,
          currency: paymentRow?.currency || "BRL",
          paid_at:
            catalogStatus === "approved" || catalogStatus === "partially_paid"
              ? paymentRow?.approved_at || catalogOrder.paid_at || null
              : null,
          created_at: paymentRow?.created_at || null,
          environment: paymentRow?.checkout_environment || null,
          payer_name: paymentRow?.payer_name || null,
          payer_email: paymentRow?.payer_email || null,
          payer_document: paymentRow?.payer_document || null,
        };
      }
    }
  } catch {
  }

  return resolved;
}
