// ─── Locale ───────────────────────────────────────────────────────────────────

export const APP_LOCALE = "en-GB";
export const APP_CURRENCY = "GBP";

// ─── Currency ─────────────────────────────────────────────────────────────────

/**
 * Format cents to a currency string e.g. 1999 -> "£19.99"
 */
export function formatPrice(
  cents: number,
  currency = APP_CURRENCY,
  locale = APP_LOCALE
): string {
  return new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
    minimumFractionDigits: 2,
  }).format(cents / 100);
}

/**
 * Convert dollars to cents for storing in DB e.g. 19.99 -> 1999
 */
export function dollarsToCents(dollars: number): number {
  return Math.round(dollars * 100);
}

/**
 * Convert cents to dollars e.g. 1999 -> 19.99
 */
export function centsToDollars(cents: number): number {
  return cents / 100;
}

// ─── Slugs ───────────────────────────────────────────────────────────────────

/**
 * Generate a URL-safe slug from a string
 * e.g. "Hello World!" -> "hello-world"
 */
export function slugify(text: string): string {
  return text
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, "")
    .replace(/[\s_-]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

// ─── Dates ───────────────────────────────────────────────────────────────────

/**
 * Format an ISO date string to a readable format
 * e.g. "2024-01-15T10:30:00Z" -> "Jan 15, 2024"
 */
export function formatDate(
  isoString: string,
  options: Intl.DateTimeFormatOptions = {
    year: "numeric",
    month: "short",
    day: "numeric",
  }
): string {
  return new Intl.DateTimeFormat(APP_LOCALE, options).format(
    new Date(isoString)
  );
}

/**
 * Format an ISO date string to a relative time
 * e.g. "2 hours ago", "3 days ago"
 */
export function formatRelativeTime(isoString: string): string {
  const diff = Date.now() - new Date(isoString).getTime();
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) return `${days} day${days > 1 ? "s" : ""} ago`;
  if (hours > 0) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
  if (minutes > 0) return `${minutes} minute${minutes > 1 ? "s" : ""} ago`;
  return "just now";
}

// ─── Cart Helpers ───────────────────────────────────────────────────────────

export interface CartTotalsInput {
  quantity: number;
  priceSnapshot?: number;
  unitPrice?: number;
}

/**
 * Calculate subtotal, total, and item count from cart items.
 * Uses priceSnapshot or unitPrice (cents). Used in cart UI and before order creation.
 */
export function calculateCartTotals(
  items: CartTotalsInput[]
): { subtotal: number; total: number; itemCount: number } {
  let subtotal = 0;
  let itemCount = 0;
  for (const item of items) {
    const price = item.priceSnapshot ?? item.unitPrice ?? 0;
    subtotal += item.quantity * price;
    itemCount += item.quantity;
  }
  return { subtotal, total: subtotal, itemCount };
}

// ─── Order Helpers ───────────────────────────────────────────────────────────

import type { OrderStatus, PaymentStatus } from "@repo/types";

export const ORDER_STATUS_LABELS: Record<OrderStatus, string> = {
  pending: "Pending",
  confirmed: "Confirmed",
  processing: "Processing",
  shipped: "Shipped",
  delivered: "Delivered",
  cancelled: "Cancelled",
  refunded: "Refunded",
  return: "Return Requested",
  completed: "Completed",
};

export const PAYMENT_STATUS_LABELS: Record<PaymentStatus, string> = {
  pending: "Pending",
  paid: "Paid",
  failed: "Failed",
  refunded: "Refunded",
};

export const ORDER_STATUS_COLORS: Record<OrderStatus, string> = {
  pending: "yellow",
  confirmed: "blue",
  processing: "purple",
  shipped: "indigo",
  delivered: "green",
  cancelled: "red",
  refunded: "gray",
  return: "orange",
  completed: "teal",
};

// ─── Validation ───────────────────────────────────────────────────────────────

export function isValidEmail(email: string): boolean {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

export function isValidPhone(phone: string): boolean {
  return /^\+?[\d\s\-()]{7,15}$/.test(phone);
}

// ─── Pagination ───────────────────────────────────────────────────────────────

export function getPaginationRange(
  page: number,
  limit: number
): { from: number; to: number } {
  const from = (page - 1) * limit;
  const to = from + limit - 1;
  return { from, to };
}

export function getTotalPages(total: number, limit: number): number {
  return Math.ceil(total / limit);
}

// ─── SKU Generation ───────────────────────────────────────────────────────────

/**
 * Generate a SKU from product metadata.
 * e.g. Royal Canin, Adult Dog Food, flavor: Chicken, 5kg → "ROY-CANI-ADUL-DOG-CHIC-5KG"
 */
export function generateSku(
  brand: string,
  productName: string,
  attributes?: {
    size?: string;
    flavor?: string;
    color?: string;
  },
  weight?: number,
  weightUnit?: string
): string {
  const clean = (str: string) =>
    str
      .toUpperCase()
      .trim()
      .replace(/[^A-Z0-9\s]/g, "")
      .split(/\s+/)
      .map((w) => w.slice(0, 4))
      .join("-");

  const parts = [
    brand       ? clean(brand)       : null,
    productName ? clean(productName) : null,
    attributes?.flavor ? clean(attributes.flavor) : null,
    attributes?.size   ? clean(attributes.size)   : null,
    attributes?.color  ? clean(attributes.color)  : null,
    weight && weightUnit ? `${weight}${weightUnit.toUpperCase()}` : null,
  ].filter(Boolean);

  return parts.join("-");
}

// ─── Misc ─────────────────────────────────────────────────────────────────────

/**
 * Generate a short order number e.g. "ORD-4F2K9"
 */
export function generateOrderNumber(): string {
  return `ORD-${Math.random().toString(36).substring(2, 7).toUpperCase()}`;
}

/**
 * Truncate a string to a max length with ellipsis
 */
export function truncate(text: string, maxLength: number): string {
  if (text.length <= maxLength) return text;
  return `${text.substring(0, maxLength)}...`;
}

/**
 * Deep clone an object safely
 */
export function deepClone<T>(obj: T): T {
  return JSON.parse(JSON.stringify(obj));
}
