export interface BaseResponse<T = unknown> {
  statusCode?: number;
  success: boolean;
  data: T;
  message?: string;
}

export interface Category {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string | null;
  parent: string | null;
  title: string;
  isActive: boolean;
  shop: string;
  avatarUrl: string | null;
  order: number | null;
  children: Category[];
}

export type CategoriesResponse = BaseResponse<Category[]>;

export type ProductImage = string | { url: string; alt?: string | null };

/** Category as nested in product list API */
export interface ProductCategory {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string | null;
  parent: string | null;
  title: string;
  isActive: boolean;
  shop: string;
  avatarUrl: string | null;
  order: number | null;
}

export interface ProductVariant {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string | null;
  product: string;
  value: string;
  price: number;
}

export enum PurchaseUnit {
  NUMBER = "number",
  KILOGRAM = "kilogram",
  GRAM = "gram",
  CENTIMETER = "centimeter",
  METER = "meter",
  MILLILITER = "milliliter",
  LITER = "liter",
}

export type PricingType = "fixed" | "variable";

export interface Product {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: string | null;
  shop: string;
  category: ProductCategory;
  attribute: string | null;
  title: string;
  desc: string;
  order: number | null;
  isActive: boolean;
  images: string[];
  score: number | null;
  discount: number;
  isSpecialOffer: boolean;
  price: number | null;
  variants: ProductVariant[];
  pricingType?: PricingType;
  purchaseUnit?: PurchaseUnit | string;
  purchasePitch?: string;
  minPurchaseQuantity?: string;
  maxPurchaseQuantity?: string;
  needAdminAcceptance?: boolean;
  /** Backward compatibility / other APIs */
  name?: string;
  description?: string;
  content?: string[] | string | null;
  image?: string | null;
  inPlaceServe?: boolean;
  pickupServe?: boolean;
  points?: number | null;
  rate?: number | null;
  prepareTime?: number | null;
  isFavorite?: boolean;
}

export type ProductsResponse = BaseResponse<Product[]>;
export type ProductResponse = BaseResponse<Product>;

/** محصول بدون تنوع: attribute خالی → قیمت از اولین واریانت */
export function hasVariants(product: Product): boolean {
  return Boolean(product.attribute?.trim());
}

/** شناسه‌ای که برای سبد/API استفاده می‌شود: همیشه variantId (اگر بدون تنوع، همان واریانت اول) */
export function getPrimaryVariantId(product: Product): string | null {
  const first = product.variants?.[0];
  return first?.id ?? null;
}

/** قیمت مؤثر: بدون تنوع = قیمت واریانت اول، با تنوع = product.price یا اولین واریانت */
export function getProductEffectivePrice(product: Product): number {
  if (product.price != null && product.price > 0) return product.price;
  const first = product.variants?.[0];
  return first?.price ?? 0;
}

export function isVariablePricing(product: Product): boolean {
  return product.pricingType === "variable";
}

export function getPurchaseUnitLabel(unit: string | undefined): string {
  switch (unit) {
    case PurchaseUnit.NUMBER:
      return "عدد";
    case PurchaseUnit.KILOGRAM:
      return "کیلوگرم";
    case PurchaseUnit.GRAM:
      return "گرم";
    case PurchaseUnit.CENTIMETER:
      return "سانتی‌متر";
    case PurchaseUnit.METER:
      return "متر";
    case PurchaseUnit.MILLILITER:
      return "میلی‌لیتر";
    case PurchaseUnit.LITER:
      return "لیتر";
    default:
      return unit ?? "";
  }
}

/** برچسب کوتاه برای نمایش روی اسلایدر */
export function getPurchaseUnitShortLabel(unit: string | undefined): string {
  switch (unit) {
    case PurchaseUnit.KILOGRAM:
      return "kg";
    case PurchaseUnit.GRAM:
      return "gr";
    case PurchaseUnit.CENTIMETER:
      return "cm";
    case PurchaseUnit.METER:
      return "m";
    case PurchaseUnit.MILLILITER:
      return "ml";
    case PurchaseUnit.LITER:
      return "L";
    case PurchaseUnit.NUMBER:
      return "";
    default:
      return unit ?? "";
  }
}

export function formatPurchaseQuantity(value: number, unit: string | undefined): string {
  const short = getPurchaseUnitShortLabel(unit);

  if (unit === PurchaseUnit.KILOGRAM) {
    const grams = Math.round(value * 1000);
    if (grams < 1000) {
      return `${grams} gr`;
    }
    if (Number.isInteger(value)) {
      return `${value} kg`;
    }
    return `${parseFloat(value.toFixed(3))} kg`;
  }

  if (unit === PurchaseUnit.GRAM) {
    return `${Math.round(value)} gr`;
  }

  if (unit === PurchaseUnit.MILLILITER) {
    if (value >= 1000) {
      const liters = value / 1000;
      return Number.isInteger(liters) ? `${liters} L` : `${parseFloat(liters.toFixed(2))} L`;
    }
    return `${Math.round(value)} ml`;
  }

  if (unit === PurchaseUnit.LITER) {
    if (value < 1) {
      return `${Math.round(value * 1000)} ml`;
    }
    return Number.isInteger(value) ? `${value} L` : `${parseFloat(value.toFixed(2))} L`;
  }

  if (unit === PurchaseUnit.CENTIMETER) {
    if (value >= 100) {
      const meters = value / 100;
      return Number.isInteger(meters) ? `${meters} m` : `${parseFloat(meters.toFixed(2))} m`;
    }
    return `${Math.round(value)} cm`;
  }

  if (unit === PurchaseUnit.METER) {
    if (value < 1) {
      return `${Math.round(value * 100)} cm`;
    }
    return Number.isInteger(value) ? `${value} m` : `${parseFloat(value.toFixed(2))} m`;
  }

  if (unit === PurchaseUnit.NUMBER) {
    return `${value}`;
  }

  return short ? `${value} ${short}` : `${value}`;
}

export function parsePurchaseQuantity(value: string | undefined, fallback: number): number {
  const parsed = Number.parseFloat(value ?? "");
  return Number.isFinite(parsed) ? parsed : fallback;
}

export function getVariableQuantityRange(product: Product) {
  const pitch = parsePurchaseQuantity(product.purchasePitch, 0.05);
  const min = parsePurchaseQuantity(product.minPurchaseQuantity, 1);
  const max = parsePurchaseQuantity(product.maxPurchaseQuantity, min);
  return {
    min,
    max: Math.max(max, min),
    pitch: pitch > 0 ? pitch : 0.05,
  };
}

/** @deprecated use getVariableQuantityRange */
export const getVariableWeightRange = getVariableQuantityRange;

export interface NotificationsCountData {
  count: number;
}

export type NotificationsCountResponse = BaseResponse<NotificationsCountData>;
