import "server-only";

import { createHmac } from "crypto";

const MERCHANT_ID = process.env.PAYTR_MERCHANT_ID ?? "";
const MERCHANT_KEY = process.env.PAYTR_MERCHANT_KEY ?? "";
const MERCHANT_SALT = process.env.PAYTR_MERCHANT_SALT ?? "";

export function isPayTREnabled(): boolean {
  return (
    process.env.PAYMENT_PROVIDER === "paytr" &&
    Boolean(MERCHANT_ID) &&
    Boolean(MERCHANT_KEY) &&
    Boolean(MERCHANT_SALT)
  );
}

type GetPayTRTokenParams = {
  merchantOid: string;
  email: string;
  userName: string;
  userAddress: string;
  userPhone: string;
  paymentAmountKurus: number;
  userBasket: Array<[string, string, number]>; // [name, price_tl_string, qty]
  userIp: string;
  notifyUrl: string;
  okUrl: string;
  failUrl: string;
};

export async function getPayTRToken(params: GetPayTRTokenParams): Promise<string> {
  const {
    merchantOid,
    email,
    userName,
    userAddress,
    userPhone,
    paymentAmountKurus,
    userBasket,
    userIp,
    notifyUrl,
    okUrl,
    failUrl,
  } = params;

  const noInstallment = "1";
  const maxInstallment = "0";
  const currency = "TL";
  const testMode = process.env.PAYTR_TEST_MODE === "1" ? "1" : "0";

  const userBasketEncoded = Buffer.from(JSON.stringify(userBasket)).toString("base64");

  // Hash sırası — token üretirken: salt EN SONDA
  const hashStr =
    MERCHANT_ID +
    userIp +
    merchantOid +
    email +
    String(paymentAmountKurus) +
    userBasketEncoded +
    noInstallment +
    maxInstallment +
    currency +
    testMode +
    MERCHANT_SALT;

  const paytrToken = createHmac("sha256", MERCHANT_KEY).update(hashStr).digest("base64");

  const body = new URLSearchParams({
    merchant_id: MERCHANT_ID,
    user_ip: userIp,
    merchant_oid: merchantOid,
    email,
    payment_amount: String(paymentAmountKurus),
    paytr_token: paytrToken,
    user_basket: userBasketEncoded,
    debug_on: process.env.PAYTR_TEST_MODE === "1" ? "1" : "0",
    no_installment: noInstallment,
    max_installment: maxInstallment,
    currency,
    test_mode: testMode,
    notify_url: notifyUrl,
    merchant_ok_url: okUrl,
    merchant_fail_url: failUrl,
    user_name: userName,
    user_address: userAddress,
    user_phone: userPhone,
  });

  const res = await fetch("https://www.paytr.com/odeme/api/get-token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: body.toString(),
  });

  if (!res.ok) throw new Error(`PayTR token isteği başarısız: HTTP ${res.status}`);

  const json = (await res.json()) as { status: string; token?: string; reason?: string };
  if (json.status !== "success" || !json.token) {
    throw new Error(`PayTR hatası: ${json.reason ?? "Bilinmeyen hata"}`);
  }

  return json.token;
}

export function verifyPayTRCallback(params: {
  merchantOid: string;
  status: string;
  totalAmount: string;
  hash: string;
}): boolean {
  if (!MERCHANT_KEY || !MERCHANT_SALT) return false;

  // Hash sırası — callback'te: salt 2. sırada (token üretmedekinden farklı!)
  const hashStr = params.merchantOid + MERCHANT_SALT + params.status + params.totalAmount;
  const expected = createHmac("sha256", MERCHANT_KEY).update(hashStr).digest("base64");

  try {
    const a = Buffer.from(expected);
    const b = Buffer.from(params.hash);
    if (a.length !== b.length) return false;
    // timing-safe comparison
    let diff = 0;
    for (let i = 0; i < a.length; i++) diff |= a[i]! ^ b[i]!;
    return diff === 0;
  } catch {
    return false;
  }
}
