type IntegrationRow = {
  id: string;
  user_id: string;
  provider: string;
  token: string | null;
  refresh_token: string | null;
  settings: Record<string, unknown> | null;
  active: boolean | null;
};

export type MercadoPagoEnvironment = "sandbox" | "production";

export type MercadoPagoIntegrationSettings = {
  environment: MercadoPagoEnvironment;
  checkout_enabled: boolean;
  auto_create_order_on_approved_payment: boolean;
  bank_account_id: string | null;
  sandbox_public_key: string;
  sandbox_access_token: string;
  production_public_key: string;
  production_access_token: string;
  statement_descriptor: string;
};

export type MercadoPagoCredentials = {
  environment: MercadoPagoEnvironment;
  publicKey: string;
  accessToken: string;
};

export type MercadoPagoPublicConfig = {
  integrationId: string;
  environment: MercadoPagoEnvironment;
  publicKey: string;
  checkoutEnabled: boolean;
  autoCreateOrderOnApprovedPayment: boolean;
};

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

function normalizeBoolean(value: unknown, fallback = false) {
  if (typeof value === "boolean") return value;
  if (typeof value === "string") {
    const normalized = value.trim().toLowerCase();
    if (normalized === "true") return true;
    if (normalized === "false") return false;
  }
  return fallback;
}

export function parseMercadoPagoSettings(raw: unknown): MercadoPagoIntegrationSettings {
  const settings = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record<string, unknown>) : {};
  const environment = settings.environment === "production" ? "production" : "sandbox";

  return {
    environment,
    checkout_enabled: normalizeBoolean(settings.checkout_enabled, true),
    auto_create_order_on_approved_payment: normalizeBoolean(settings.auto_create_order_on_approved_payment, true),
    bank_account_id: normalizeText(settings.bank_account_id) || null,
    sandbox_public_key: normalizeText(settings.sandbox_public_key),
    sandbox_access_token: normalizeText(settings.sandbox_access_token),
    production_public_key: normalizeText(settings.production_public_key),
    production_access_token: normalizeText(settings.production_access_token),
    statement_descriptor: normalizeText(settings.statement_descriptor).slice(0, 13),
  };
}

export function getActiveMercadoPagoCredentials(
  settings: MercadoPagoIntegrationSettings
): MercadoPagoCredentials | null {
  if (settings.environment === "production") {
    if (!settings.production_public_key || !settings.production_access_token) return null;
    return {
      environment: "production",
      publicKey: settings.production_public_key,
      accessToken: settings.production_access_token,
    };
  }

  if (!settings.sandbox_public_key || !settings.sandbox_access_token) return null;
  return {
    environment: "sandbox",
    publicKey: settings.sandbox_public_key,
    accessToken: settings.sandbox_access_token,
  };
}

export function resolveMercadoPagoPublicConfig(row: IntegrationRow | null | undefined): MercadoPagoPublicConfig | null {
  if (!row || row.active === false) return null;
  const settings = parseMercadoPagoSettings(row.settings);
  const credentials = getActiveMercadoPagoCredentials(settings);
  if (!credentials || !settings.checkout_enabled) return null;

  return {
    integrationId: row.id,
    environment: credentials.environment,
    publicKey: credentials.publicKey,
    checkoutEnabled: settings.checkout_enabled,
    autoCreateOrderOnApprovedPayment: settings.auto_create_order_on_approved_payment,
  };
}

export function splitPersonName(fullName: string) {
  const normalized = normalizeText(fullName);
  if (!normalized) {
    return { firstName: "Cliente", lastName: "Ktalogu" };
  }

  const parts = normalized.split(/\s+/).filter(Boolean);
  if (parts.length === 1) {
    return { firstName: parts[0], lastName: "Cliente" };
  }

  return {
    firstName: parts[0],
    lastName: parts.slice(1).join(" "),
  };
}

export function detectDocumentType(document: string) {
  const digits = String(document || "").replace(/\D/g, "");
  if (digits.length === 14) return "CNPJ";
  return "CPF";
}

export function normalizeMercadoPagoPaymentStatus(value: unknown) {
  const status = normalizeText(value).toLowerCase();
  if (status === "approved") return "approved";
  if (status === "rejected") return "rejected";
  if (status === "cancelled" || status === "canceled") return "cancelled";
  if (status === "refunded") return "refunded";
  if (status === "charged_back") return "charged_back";
  return "pending";
}

export function normalizeMercadoPagoPaymentMethod(value: unknown, paymentType?: unknown) {
  const method = normalizeText(value).toLowerCase();
  const type = normalizeText(paymentType).toLowerCase();

  if (method === "pix" || type === "bank_transfer") return "pix";
  if (type === "credit_card" || type === "creditcard") return "credit_card";
  if (type === "debit_card" || type === "debitcard") return "debit_card";
  if (type === "ticket") return "ticket";
  if (type === "wallet_purchase" || method === "account_money") return "wallet";
  return "unknown";
}

/*
  Onde ficam o QR do Pix e o link do boleto na resposta do provedor.

  O Pix vem em `point_of_interaction.transaction_data`. O boleto NAO: ele nao
  tem esse bloco, e o link do documento fica em
  `transaction_details.external_resource_url`, com a linha digitavel em
  `barcode.content`. Como a leitura so olhava o bloco do Pix, todo boleto era
  gravado sem link — o cliente clicava em "gerar boleto", o boleto era criado de
  verdade no provedor e a tela nao mostrava absolutamente nada.
*/
function objetoDe(valor: unknown) {
  return valor && typeof valor === "object" && !Array.isArray(valor) ? (valor as Record<string, unknown>) : null;
}

export function extractMercadoPagoQrData(payload: Record<string, unknown> | null | undefined) {
  const dadosDoPix = objetoDe(objetoDe(payload?.point_of_interaction)?.transaction_data);
  const detalhes = objetoDe(payload?.transaction_details);
  const codigoDeBarras = objetoDe(payload?.barcode);

  return {
    qrCode: normalizeText(dadosDoPix?.qr_code) || null,
    qrCodeBase64: normalizeText(dadosDoPix?.qr_code_base64) || null,
    ticketUrl:
      normalizeText(dadosDoPix?.ticket_url) ||
      normalizeText(detalhes?.external_resource_url) ||
      null,
    barcode: normalizeText(codigoDeBarras?.content) || null,
  };
}

export async function fetchMercadoPagoApi<T>(
  path: string,
  accessToken: string,
  init?: RequestInit & { idempotencyKey?: string | null }
): Promise<T> {
  const headers = new Headers(init?.headers || {});
  headers.set("Authorization", `Bearer ${accessToken}`);
  headers.set("Content-Type", "application/json");
  if (init?.idempotencyKey) {
    headers.set("X-Idempotency-Key", init.idempotencyKey);
  }

  const response = await fetch(`https://api.mercadopago.com${path}`, {
    ...init,
    headers,
    cache: "no-store",
  });

  const payload = (await response.json().catch(() => ({}))) as T & { message?: string; error?: string };
  if (!response.ok) {
    const message =
      (payload && typeof payload === "object" && (payload.message || payload.error)) ||
      "Nao foi possivel comunicar com o Mercado Pago.";
    throw new Error(String(message));
  }

  return payload;
}

export async function getMercadoPagoIntegration(
  admin: {
    from: (table: string) => {
      select: (columns: string) => {
        eq: (column: string, value: string) => {
          eq: (column: string, value: string) => { maybeSingle: () => Promise<{ data: IntegrationRow | null; error: { message?: string } | null }> };
          maybeSingle: () => Promise<{ data: IntegrationRow | null; error: { message?: string } | null }>;
        };
      };
    };
  },
  userId: string
) {
  const { data, error } = await admin
    .from("integrations")
    .select("id,user_id,provider,token,refresh_token,settings,active")
    .eq("provider", "mercado_pago")
    .eq("user_id", userId)
    .maybeSingle();

  if (error) {
    throw new Error(error.message || "Nao foi possivel carregar a integracao do Mercado Pago.");
  }

  return data;
}
