export const WEIGHT_UNITS = ['mg', 'g', 'kg'];
export const VOLUME_UNITS = ['ml', 'L'];
export const SELLING_UNITS = ['pcs', 'packet', 'pack', 'box', 'pair', 'dozen', 'bottle', 'can'];

export const MEASUREMENT_UNITS = {
  WEIGHT: WEIGHT_UNITS,
  VOLUME: VOLUME_UNITS,
  SIZE: [],
  QUANTITY: [],
};

export const isMeasurementUnit = (unit) =>
  WEIGHT_UNITS.includes(unit) || VOLUME_UNITS.includes(unit);

export const generateVariantId = () =>
  `v-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;

export const getVariantStatus = (variant) => {
  const stock = Number(variant?.currentStock) || 0;
  const threshold = Number(variant?.lowStockThreshold) || 0;
  if (stock <= 0) return 'OUT_OF_STOCK';
  if (stock <= threshold) return 'LOW_STOCK';
  return 'IN_STOCK';
};

export const buildVariantLabel = (v = {}) => {
  if (v.label && String(v.label).trim()) return String(v.label).trim();
  if (v.size && String(v.size).trim()) return String(v.size).trim();
  const hasValue =
    v.measurementValue !== undefined &&
    v.measurementValue !== null &&
    v.measurementValue !== '';
  if (hasValue && v.measurementUnit) return `${v.measurementValue} ${v.measurementUnit}`;
  return 'Standard';
};

export const normalizeVariant = (v = {}, index = 0, opts = {}) => {
  const trackingType = opts.trackingType || 'QUANTITY';
  const rawValue = v.measurementValue;
  const hasValue =
    rawValue !== undefined && rawValue !== null && rawValue !== '';
  const measurementValue = hasValue ? Number(rawValue) : null;
  const measurementUnit =
    trackingType === 'QUANTITY' || trackingType === 'SIZE'
      ? null
      : (v.measurementUnit && String(v.measurementUnit).trim()) || null;
  const sellingUnit =
    (v.sellingUnit && String(v.sellingUnit).trim()) ||
    opts.sellingUnit ||
    'pcs';
  const size =
    trackingType === 'SIZE' && v.size ? String(v.size).trim() : null;
  let label = v.label && String(v.label).trim() ? String(v.label).trim() : '';
  if (!label) {
    if (size) label = size;
    else if (measurementValue !== null && measurementUnit) label = `${measurementValue} ${measurementUnit}`;
    else label = 'Standard';
  }
  return {
    variantId: (v.variantId && String(v.variantId).trim()) || generateVariantId(),
    label,
    size,
    measurementValue,
    measurementUnit,
    sellingUnit,
    purchasePrice: Number(v.purchasePrice ?? v.costPrice) || 0,
    sellingPrice: Number(v.sellingPrice) || 0,
    currentStock: Number(v.currentStock) >= 0 ? Number(v.currentStock) : 0,
    lowStockThreshold: Number(v.lowStockThreshold) >= 0 ? Number(v.lowStockThreshold) : 10,
    sku: (v.sku || '').trim(),
    barcode: (v.barcode || '').trim(),
    status: v.status || 'ACTIVE',
  };
};

export const normalizeVariants = (variants, opts = {}) => {
  if (!Array.isArray(variants)) return [];
  return variants.map((v, i) => normalizeVariant(v, i, opts));
};

export const legacyVariants = (product) => {
  if (product.trackingType === 'SIZE' && product.sizeVariants && product.sizeVariants.length > 0) {
    return product.sizeVariants.map((v) => ({
      variantId: `legacy-${product._id}-${String(v.size).replace(/\s+/g, '-')}`,
      label: v.size,
      size: v.size,
      measurementValue: null,
      measurementUnit: null,
      sellingUnit: product.unit || 'pcs',
      purchasePrice: product.purchasePrice || 0,
      sellingPrice: product.sellingPrice || 0,
      currentStock: Number(v.stock) || 0,
      lowStockThreshold:
        Number(v.lowStockThreshold) >= 0
          ? Number(v.lowStockThreshold)
          : Number(product.lowStockThreshold) || 10,
      sku: '',
      barcode: '',
      status: 'ACTIVE',
    }));
  }
  const legacyUnit = (product.unit || 'pcs').trim();
  const measurementUnit = isMeasurementUnit(legacyUnit) ? legacyUnit : null;
  return [
    {
      variantId: `legacy-${product._id}-default`,
      label: 'Standard',
      size: null,
      measurementValue: null,
      measurementUnit,
      sellingUnit: measurementUnit ? 'pcs' : legacyUnit,
      purchasePrice: product.purchasePrice || 0,
      sellingPrice: product.sellingPrice || 0,
      currentStock: Number(product.currentStock) || 0,
      lowStockThreshold:
        Number(product.lowStockThreshold) >= 0 ? Number(product.lowStockThreshold) : 10,
      sku: '',
      barcode: '',
      status: 'ACTIVE',
    },
  ];
};

export const getVariants = (product) => {
  if (!product) return [];
  if (product.variants && product.variants.length > 0) return product.variants;
  return legacyVariants(product);
};

export const getVariant = (product, variantId) => {
  const variants = getVariants(product);
  if (!variantId) return variants.length === 1 ? variants[0] : null;
  return variants.find((v) => v.variantId === variantId) || null;
};

export const getTotalStock = (product) => {
  if (!product) return 0;
  if (product.trackingType === 'SIZE' && product.sizeVariants && product.sizeVariants.length > 0) {
    return product.sizeVariants.reduce((s, v) => s + (Number(v.stock) || 0), 0);
  }
  if (product.variants && product.variants.length > 0) {
    return product.variants.reduce((s, v) => s + (Number(v.currentStock) || 0), 0);
  }
  return Number(product.currentStock) || 0;
};

export const buildVariantRow = (product, variant) => ({
  productId: product._id,
  productName: product.name,
  category: product.category,
  image: product.image || '',
  trackingType: product.trackingType || 'QUANTITY',
  variantId: variant.variantId,
  variantLabel: variant.label,
  size: variant.size || '',
  measurementValue: variant.measurementValue ?? null,
  measurementUnit: variant.measurementUnit || null,
  sellingUnit: variant.sellingUnit || 'pcs',
  purchasePrice: Number(variant.purchasePrice) || 0,
  sellingPrice: Number(variant.sellingPrice) || 0,
  currentStock: Number(variant.currentStock) || 0,
  lowStockThreshold: Number(variant.lowStockThreshold) || 0,
  status: getVariantStatus(variant),
  sku: variant.sku || '',
  barcode: variant.barcode || '',
  updatedAt: product.updatedAt,
});

export const allVariantRows = (products) => {
  const rows = [];
  for (const product of products) {
    for (const variant of getVariants(product)) {
      rows.push(buildVariantRow(product, variant));
    }
  }
  return rows;
};

export const getProductStatus = (product) => {
  const total = getTotalStock(product);
  if (total === 0) return 'OUT_OF_STOCK';
  const variants = getVariants(product);
  if (variants.length > 0) {
    const avgThreshold =
      variants.reduce((s, v) => s + (Number(v.lowStockThreshold) || 0), 0) / variants.length;
    if (total <= avgThreshold) return 'LOW_STOCK';
  } else if (total <= (product.lowStockThreshold || 10)) {
    return 'LOW_STOCK';
  }
  return 'IN_STOCK';
};

export const syncProductFromVariants = (product) => {
  const variants = getVariants(product);
  if (variants.length === 0) return;
  product.currentStock = variants.reduce((s, v) => s + (Number(v.currentStock) || 0), 0);
  product.purchasePrice = Number(variants[0].purchasePrice) || 0;
  product.sellingPrice = Number(variants[0].sellingPrice) || 0;
  product.lowStockThreshold = Number(variants[0].lowStockThreshold) || 10;
  product.unit = variants[0].sellingUnit || 'pcs';
  if (product.trackingType === 'SIZE') {
    product.sizeVariants = variants.map((v) => ({
      size: v.size || v.label,
      stock: Number(v.currentStock) || 0,
      lowStockThreshold: Number(v.lowStockThreshold) || 5,
    }));
  } else {
    product.sizeVariants = [];
  }
};