export const DEFAULT_GATEWAY_MATCHERS = [
  { key: "Stripe:", label: "Stripe" },
  { key: "Airwallex:", label: "Airwallex" },
  { key: "Adyen:", label: "Adyen" },
  { key: "Checkout.com:", label: "Checkout.com" },
  { key: "Checkout:", label: "Checkout" },
  { key: "Braintree:", label: "Braintree" },
  { key: "Paddle:", label: "Paddle" },
  { key: "Square:", label: "Square" },
  { key: "NordPay:", label: "NordPay" },
  { key: "Xsolla:", label: "Xsolla" },
  { key: "Smart Glocal:", label: "Smart Glocal" },
  { key: "EdfaPay:", label: "EdfaPay" },
  { key: "HiPay:", label: "HiPay" },
  { key: "Steam:", label: "Steam" },
  { key: "GOG:", label: "GOG" }
];

const RISK_ORDER = ["low", "medium", "high", "dangerous"];
const GENERIC_DECLINE_PATTERNS = [
  "generic_decline",
  "do_not_honor",
  "card_declined",
  "decline code",
  "declined"
];
const PAYMENT_FAILURE_PATTERNS = [
  "payment intent failed",
  "payment failed",
  "processing_error",
  "authentication_required"
];

function toPercent(part, total) {
  if (!total) {
    return 0;
  }

  return part / total * 100;
}

function getRiskIndex(level) {
  return RISK_ORDER.indexOf(normalizeRiskLevel(level));
}

function getHigherRisk(left, right) {
  return getRiskIndex(left) >= getRiskIndex(right) ? normalizeRiskLevel(left) : normalizeRiskLevel(right);
}

function createSummary(totalTransactions, genericDeclines, paymentFailures, otherDeclines, successes) {
  const total = Math.max(0, Number(totalTransactions) || 0);
  const generic = Math.max(0, Number(genericDeclines) || 0);
  const payment = Math.max(0, Number(paymentFailures) || 0);
  const other = Math.max(0, Number(otherDeclines) || 0);
  const success = Math.max(0, Number(successes) || 0);

  const genericDeclinePct = toPercent(generic, total);
  const paymentIntentFailedPct = toPercent(payment, total);
  const otherDeclinePct = toPercent(other, total);
  const successPct = toPercent(success, total);

  let score = genericDeclinePct * 0.55 + paymentIntentFailedPct * 0.45 + otherDeclinePct * 0.25 - successPct * 0.15;

  if (total >= 8 && generic + payment + other >= Math.ceil(total * 0.6)) {
    score += 18;
  } else if (total >= 4 && generic + payment + other >= Math.ceil(total * 0.5)) {
    score += 10;
  }

  return {
    riskLevel: getRiskBandFromScore(score),
    totalTransactions: total,
    genericDeclinePct,
    paymentIntentFailedPct,
    otherDeclinePct,
    successPct
  };
}

function summarizeGateway(logs, matcher) {
  let total = 0;
  let genericDeclines = 0;
  let paymentFailures = 0;
  let otherDeclines = 0;
  let successes = 0;

  for (const log of Array.isArray(logs) ? logs : []) {
    const message = String(log?.message || "");
    if (!matcher(message)) {
      continue;
    }

    total += 1;
    const normalizedMessage = message.toLowerCase();

    if (log?.logType === "success" || normalizedMessage.includes("payment succeeded") || normalizedMessage.includes("checkout completed") || normalizedMessage.includes("payment paid")) {
      successes += 1;
      continue;
    }

    if (PAYMENT_FAILURE_PATTERNS.some((pattern) => normalizedMessage.includes(pattern))) {
      paymentFailures += 1;
      continue;
    }

    if (GENERIC_DECLINE_PATTERNS.some((pattern) => normalizedMessage.includes(pattern))) {
      genericDeclines += 1;
      continue;
    }

    if (log?.logType === "error" || normalizedMessage.includes("error")) {
      otherDeclines += 1;
    }
  }

  return createSummary(total, genericDeclines, paymentFailures, otherDeclines, successes);
}

export function createRiskEvaluationState() {
  return {
    lastEvaluation: null,
    rateLimit: null,
    lastError: "",
    loading: false
  };
}

export function normalizeRiskLevel(level) {
  const normalized = String(level || "").trim().toLowerCase();

  if (!normalized) {
    return "low";
  }

  if (normalized === "critical" || normalized === "danger" || normalized === "dangerous") {
    return "dangerous";
  }

  if (normalized === "high" || normalized === "elevated" || normalized === "severe") {
    return "high";
  }

  if (normalized === "medium" || normalized === "moderate") {
    return "medium";
  }

  return "low";
}

export function getRiskBandFromScore(score) {
  const numericScore = Number(score);
  if (!Number.isFinite(numericScore)) {
    return "low";
  }

  if (numericScore >= 75) {
    return "dangerous";
  }

  if (numericScore >= 50) {
    return "high";
  }

  if (numericScore >= 25) {
    return "medium";
  }

  return "low";
}

export function formatRiskBandLabel(level) {
  const normalized = normalizeRiskLevel(level);
  return normalized.charAt(0).toUpperCase() + normalized.slice(1);
}

export function getRelativeTimeLabel(timestamp) {
  if (!timestamp) {
    return "just now";
  }

  const then = new Date(timestamp).getTime();
  if (!Number.isFinite(then)) {
    return "just now";
  }

  const deltaMs = Math.max(0, Date.now() - then);
  const deltaMinutes = Math.floor(deltaMs / 60000);
  if (deltaMinutes < 1) {
    return "just now";
  }

  if (deltaMinutes < 60) {
    return `${deltaMinutes}m ago`;
  }

  const deltaHours = Math.floor(deltaMinutes / 60);
  if (deltaHours < 24) {
    return `${deltaHours}h ago`;
  }

  const deltaDays = Math.floor(deltaHours / 24);
  return `${deltaDays}d ago`;
}

export function computeLocalRiskSummary(logs) {
  const stripe = summarizeGateway(logs, (message) => message.includes("Stripe:"));
  const airwallex = summarizeGateway(logs, (message) => message.includes("Airwallex:"));
  const otherGateways = summarizeGateway(
    logs,
    (message) =>
      DEFAULT_GATEWAY_MATCHERS.some((item) => message.includes(item.key)) &&
      !message.includes("Stripe:") &&
      !message.includes("Airwallex:")
  );

  let overallRisk = "low";
  overallRisk = getHigherRisk(overallRisk, stripe.riskLevel);
  overallRisk = getHigherRisk(overallRisk, airwallex.riskLevel);
  overallRisk = getHigherRisk(overallRisk, otherGateways.riskLevel);

  return {
    overallRisk,
    stripe,
    airwallex,
    otherGateways
  };
}
