/**
 * Marketing Product Calculation Hook
 *
 * Reusable calculation logic for Sales Order and Delivery Order forms.
 * Handles 6 scenarios: TRADING, AYAM_PULLET, AYAM, TELUR+KG, TELUR+PETI, TELUR+QTY
 */

// ============ Types ============

export type MarketingFormValues = {
  qty?: string | number;
  avg_weight?: string | number;
  total_weight?: string | number;
  unit_price?: string | number;
  total_price?: string | number;
  marketing_type?: { value: string; label: string } | null;
  convertion_unit?: { value: string; label: string } | null;
  week?: number | null;
  weight_per_convertion?: number | null;
  price_per_convertion?: number | null;
  total_peti?: number | null;
  sisa_berat?: number | null;
  price_sisa_berat?: number | null;
  /** Harga per butir telur untuk TELUR + QTY */
  price_per_qty?: number | null;
};

export type SetFieldValueFn = (
  field: string,
  value: string | number | null
) => void;

export type CalculationContext = {
  values: MarketingFormValues;
  setFieldValue: SetFieldValueFn;
  hasSisaBerat: boolean;
};

// ============ Helper Functions ============

/**
 * Round weight untuk operasi perkalian (total_weight = avg_weight × qty)
 * Precision: 2 decimal places
 */
export const roundWeight = (value: number): number => Number(value.toFixed(2));

/**
 * Precise weight untuk operasi pembagian (avg_weight = total_weight / qty)
 * Tidak di-round untuk menjaga akurasi maksimal
 */
export const preciseWeight = (value: number): number => value;

export const roundPrice = (value: number): number => Math.round(value);

// ============ Calculation Handlers ============

/**
 * TRADING: Penjualan non-livestock (obat-obatan, pakan, dll)
 * - Formula: total_price = qty × unit_price
 * - Weight fields: always 0
 */
export const calculateTrading = (
  field: string,
  ctx: CalculationContext
): void => {
  const { values, setFieldValue } = ctx;
  const unitPrice = Number(values.unit_price || 0);
  const qty = Number(values.qty || 0);
  const totalPrice = Number(values.total_price || 0);

  // Trading: avg_weight = 0, total_weight = 0
  setFieldValue('avg_weight', 0);
  setFieldValue('total_weight', 0);

  switch (field) {
    case 'unit_price':
    case 'qty': {
      if (unitPrice > 0 && qty > 0) {
        setFieldValue('total_price', unitPrice * qty);
      }
      break;
    }
    case 'total_price': {
      if (totalPrice > 0 && qty > 0) {
        setFieldValue('unit_price', totalPrice / qty);
      }
      break;
    }
  }
};

/**
 * AYAM_PULLET: Penjualan pullet dengan harga berdasarkan umur minggu
 * - Formula: total_price = unit_price × week × qty
 * - total_weight = avg_weight × qty
 */
export const calculateAyamPullet = (
  field: string,
  ctx: CalculationContext
): void => {
  const { values, setFieldValue } = ctx;
  const unitPrice = Number(values.unit_price || 0);
  const week = Number(values.week || 0);
  const qty = Number(values.qty || 0);
  const avgWeight = Number(values.avg_weight || 0);
  const totalWeight = Number(values.total_weight || 0);
  const totalPrice = Number(values.total_price || 0);

  switch (field) {
    case 'unit_price':
    case 'week':
    case 'qty': {
      // total_price = unit_price × week × qty
      if (unitPrice > 0 && week > 0 && qty > 0) {
        setFieldValue('total_price', unitPrice * week * qty);
      }
      // total_weight = avg_weight × qty
      if (avgWeight > 0 && qty > 0) {
        setFieldValue('total_weight', roundWeight(avgWeight * qty));
      }
      break;
    }
    case 'avg_weight': {
      if (avgWeight > 0 && qty > 0) {
        setFieldValue('total_weight', roundWeight(avgWeight * qty));
      }
      break;
    }
    case 'total_weight': {
      if (totalWeight > 0 && qty > 0) {
        setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
      }
      break;
    }
    case 'total_price': {
      // Reverse: unit_price = total_price / (week × qty)
      if (totalPrice > 0 && week > 0 && qty > 0) {
        setFieldValue('unit_price', totalPrice / (week * qty));
      }
      break;
    }
  }
};

/**
 * AYAM: Penjualan ayam hidup/potong dengan harga per kg
 * - Formula: total_price = total_weight × unit_price
 * - total_weight = qty × avg_weight
 */
export const calculateAyam = (field: string, ctx: CalculationContext): void => {
  const { values, setFieldValue } = ctx;
  const unitPrice = Number(values.unit_price || 0);
  const qty = Number(values.qty || 0);
  const avgWeight = Number(values.avg_weight || 0);
  const totalWeight = Number(values.total_weight || 0);
  const totalPrice = Number(values.total_price || 0);

  switch (field) {
    case 'qty':
    case 'avg_weight': {
      // total_weight = qty × avg_weight
      if (qty > 0 && avgWeight > 0) {
        const tw = roundWeight(qty * avgWeight);
        setFieldValue('total_weight', tw);
        // total_price = total_weight × unit_price
        if (unitPrice > 0) {
          setFieldValue('total_price', tw * unitPrice);
        }
      }
      break;
    }
    case 'total_weight': {
      // avg_weight = total_weight / qty
      if (totalWeight > 0 && qty > 0) {
        setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
      }
      // total_price = total_weight × unit_price
      if (unitPrice > 0 && totalWeight > 0) {
        setFieldValue('total_price', totalWeight * unitPrice);
      }
      break;
    }
    case 'unit_price': {
      // total_price = total_weight × unit_price
      if (unitPrice > 0 && totalWeight > 0) {
        setFieldValue('total_price', totalWeight * unitPrice);
      }
      break;
    }
    case 'total_price': {
      // unit_price = total_price / total_weight
      if (totalPrice > 0 && totalWeight > 0) {
        setFieldValue('unit_price', totalPrice / totalWeight);
      }
      break;
    }
  }
};

/**
 * TELUR + PETI: Penjualan telur dalam satuan peti
 *
 * Formulas:
 * - total_weight = (weight_per_convertion × total_peti) + sisa_berat
 * - total_price = (price_per_convertion × total_peti) + price_sisa_berat
 * - unit_price = total_price / total_weight (untuk BE)
 * - avg_weight = total_weight / qty
 */
export const calculateTelurPeti = (
  field: string,
  ctx: CalculationContext
): void => {
  const { values, setFieldValue, hasSisaBerat } = ctx;
  const pricePerConvertion = Number(values.price_per_convertion || 0);
  const totalPeti = Number(values.total_peti || 0);
  const weightPerConvertion = Number(values.weight_per_convertion || 0);
  const sisaBerat = hasSisaBerat ? Number(values.sisa_berat || 0) : 0;
  const priceSisaBerat = hasSisaBerat
    ? Number(values.price_sisa_berat || 0)
    : 0;
  const qty = Number(values.qty || 0);

  // Helper untuk menghitung dan set unit_price = total_price / total_weight
  const updateUnitPrice = (tp: number, tw: number) => {
    if (tw > 0 && tp > 0) {
      const unitPrice = tp / tw;
      setFieldValue('unit_price', unitPrice);
    }
  };

  switch (field) {
    case 'price_per_convertion': {
      // Recalculate total_price = (price_per_convertion × total_peti) + price_sisa_berat
      if (pricePerConvertion > 0 && totalPeti > 0) {
        const totalPrice = pricePerConvertion * totalPeti + priceSisaBerat;
        setFieldValue('total_price', totalPrice);
        // Recalculate unit_price = total_price / total_weight
        const totalWeight = weightPerConvertion * totalPeti + sisaBerat;
        updateUnitPrice(totalPrice, totalWeight);
      }
      break;
    }
    case 'total_peti': {
      // Recalculate total_weight = (weight_per_convertion × total_peti) + sisa_berat
      let totalWeight = 0;
      if (weightPerConvertion > 0 && totalPeti > 0) {
        totalWeight = weightPerConvertion * totalPeti + sisaBerat;
        setFieldValue('total_weight', roundWeight(totalWeight));
        // Recalculate avg_weight = total_weight / qty
        if (qty > 0) {
          setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
        }
      }
      // Recalculate total_price = (price_per_convertion × total_peti) + price_sisa_berat
      if (pricePerConvertion > 0 && totalPeti > 0) {
        const totalPrice = pricePerConvertion * totalPeti + priceSisaBerat;
        setFieldValue('total_price', totalPrice);
        // Recalculate unit_price = total_price / totalWeight
        updateUnitPrice(totalPrice, totalWeight);
      }
      break;
    }
    case 'price_sisa_berat': {
      // Recalculate total_price
      if (pricePerConvertion > 0 && totalPeti > 0) {
        const totalPrice = pricePerConvertion * totalPeti + priceSisaBerat;
        setFieldValue('total_price', totalPrice);
        // Recalculate unit_price = total_price / total_weight
        const totalWeight = weightPerConvertion * totalPeti + sisaBerat;
        updateUnitPrice(totalPrice, totalWeight);
      }
      break;
    }
    case 'weight_per_convertion': {
      // Recalculate total_weight = (weight_per_convertion × total_peti) + sisa_berat
      if (weightPerConvertion > 0 && totalPeti > 0) {
        const totalWeight = weightPerConvertion * totalPeti + sisaBerat;
        setFieldValue('total_weight', roundWeight(totalWeight));
        // Recalculate avg_weight = total_weight / qty
        if (qty > 0) {
          setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
        }
        // Recalculate unit_price = total_price / total_weight
        const totalPrice = pricePerConvertion * totalPeti + priceSisaBerat;
        updateUnitPrice(totalPrice, totalWeight);
      }
      break;
    }
    case 'sisa_berat': {
      // Recalculate total_weight
      if (weightPerConvertion > 0 && totalPeti > 0) {
        const totalWeight = weightPerConvertion * totalPeti + sisaBerat;
        setFieldValue('total_weight', roundWeight(totalWeight));
        // Recalculate avg_weight = total_weight / qty
        if (qty > 0) {
          setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
        }
        // Recalculate unit_price = total_price / total_weight
        const totalPrice = pricePerConvertion * totalPeti + priceSisaBerat;
        updateUnitPrice(totalPrice, totalWeight);
      }
      break;
    }
    case 'total_price': {
      const totalPrice = Number(values.total_price || 0);
      // Reverse calculate price_per_convertion
      if (totalPeti > 0 && totalPrice > priceSisaBerat) {
        setFieldValue(
          'price_per_convertion',
          (totalPrice - priceSisaBerat) / totalPeti
        );
      }
      // Update unit_price = total_price / total_weight
      const totalWeight = weightPerConvertion * totalPeti + sisaBerat;
      updateUnitPrice(totalPrice, totalWeight);
      break;
    }
    case 'qty':
      // Recalculate avg_weight = total_weight / qty
      if (qty > 0 && values.total_weight) {
        setFieldValue(
          'avg_weight',
          preciseWeight(Number(values.total_weight) / qty)
        );
      }
      break;
  }
};

/**
 * TELUR + KG: Penjualan telur dalam satuan kilogram
 * - Formula: total_price = total_weight × unit_price
 * - avg_weight = total_weight / qty (calculated)
 */
export const calculateTelurKg = (
  field: string,
  ctx: CalculationContext
): void => {
  const { values, setFieldValue } = ctx;
  const qty = Number(values.qty || 0);
  const totalWeight = Number(values.total_weight || 0);
  const totalPrice = Number(values.total_price || 0);
  const pricePerConvertion = Number(values.price_per_convertion || 0);

  switch (field) {
    case 'total_weight':
    case 'qty': {
      // avg_weight = total_weight / qty
      if (totalWeight > 0 && qty > 0) {
        setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
      }
      // total_price = total_weight × unit_price
      if (pricePerConvertion > 0 && totalWeight > 0) {
        setFieldValue('total_price', totalWeight * pricePerConvertion);
        setFieldValue('unit_price', pricePerConvertion);
      }
      break;
    }
    case 'price_per_convertion': {
      // total_price = total_weight × price_per_convertion
      if (pricePerConvertion > 0 && totalWeight > 0) {
        setFieldValue('total_price', totalWeight * pricePerConvertion);
        setFieldValue('unit_price', pricePerConvertion);
      }
      break;
    }
    case 'total_price': {
      // unit_price = total_price / total_weight
      if (totalPrice > 0 && totalWeight > 0) {
        setFieldValue('unit_price', totalPrice / totalWeight);
        setFieldValue('price_per_convertion', totalPrice / totalWeight);
      }
      break;
    }
  }
};

/**
 * TELUR + QTY Workaround:
 * - User inputs: qty, avg_weight, unit_price (harga per butir)
 * - FE calculates:
 *   - total_weight = avg_weight × qty
 *   - total_price = qty × unit_price
 *   - price_per_qty = total_price / total_weight (harga per kg)
 */
export const calculateTelurQty = (
  field: string,
  ctx: CalculationContext
): void => {
  const { values, setFieldValue } = ctx;
  const qty = Number(values.qty || 0);
  const avgWeight = Number(values.avg_weight || 0);
  const totalWeight = Number(values.total_weight || 0);
  const pricePerQty = Number(values.price_per_qty || 0);
  const totalPrice = Number(values.total_price || 0);
  const unitPrice = Number(values.unit_price || 0);

  switch (field) {
    case 'qty':
    case 'avg_weight': {
      // total_weight = avg_weight × qty
      if (avgWeight > 0 && qty > 0) {
        const tw = roundWeight(avgWeight * qty);
        setFieldValue('total_weight', tw);
        // total_price = qty × unit_price
        if (unitPrice > 0) {
          const tp = qty * unitPrice;
          setFieldValue('total_price', tp);
          // price_per_qty = total_price / total_weight
          if (tw > 0) {
            setFieldValue('price_per_qty', tp / tw);
          }
        }
      }
      break;
    }
    case 'total_weight': {
      // avg_weight = total_weight / qty
      if (totalWeight > 0 && qty > 0) {
        setFieldValue('avg_weight', preciseWeight(totalWeight / qty));
        // Recalculate total_price jika ada harga per butir
        if (unitPrice > 0) {
          setFieldValue('total_price', qty * unitPrice);
        }
      }
      break;
    }
    case 'price_per_qty': {
      // total_price = total_weight × price_per_qty
      if (pricePerQty > 0 && totalWeight > 0) {
        const tp = totalWeight * pricePerQty;
        setFieldValue('total_price', tp);
        // unit_price = total_price / qty
        if (qty > 0) {
          setFieldValue('unit_price', tp / qty);
        }
      }
      break;
    }
    case 'total_price': {
      // unit_price = total_price / qty
      if (totalPrice > 0 && qty > 0) {
        setFieldValue('unit_price', totalPrice / qty);
        // price_per_qty = total_price / total_weight
        if (totalWeight > 0) {
          setFieldValue('price_per_qty', totalPrice / totalWeight);
        }
      }
      break;
    }
    case 'unit_price': {
      // total_price = qty × unit_price
      const newTotalPrice = qty * unitPrice;

      if (unitPrice > 0 && qty > 0) {
        setFieldValue('total_price', newTotalPrice);
      }

      // price_per_qty = total_price / total_weight
      if (newTotalPrice > 0 && totalWeight > 0) {
        setFieldValue('price_per_qty', newTotalPrice / totalWeight);
      }
      break;
    }
  }
};

// ============ Main Dispatcher ============

/**
 * Handle field blur and dispatch to appropriate calculation handler
 * based on marketing_type and convertion_unit
 */
export const handleMarketingCalculation = (
  field: string,
  ctx: CalculationContext
): void => {
  const { values } = ctx;
  const marketingType = values.marketing_type?.value?.toLowerCase();
  const convertionUnit = values.convertion_unit?.value?.toLowerCase();

  if (!marketingType) return;

  const qty = Number(values.qty || 0);
  if (qty <= 0) return;

  switch (marketingType) {
    case 'trading':
      calculateTrading(field, ctx);
      break;
    case 'ayam_pullet':
      calculateAyamPullet(field, ctx);
      break;
    case 'telur':
      if (convertionUnit === 'peti') {
        calculateTelurPeti(field, ctx);
      } else if (convertionUnit === 'kg') {
        calculateTelurKg(field, ctx);
      } else {
        // QTY mode - workaround dengan kirim KG ke BE
        calculateTelurQty(field, ctx);
      }
      break;
    case 'ayam':
    default:
      calculateAyam(field, ctx);
      break;
  }
};
