// ============ Unit Conversion Utility ============

// หน่วยที่รู้จัก → base unit และ factor
// key = alias ที่อาจพิมพ์มา, value = { base, factor }
const UNIT_KNOWN = {
  // น้ำหนัก → กรัม
  'กิโลกรัม': { base: 'กรัม', factor: 1000 },
  'กก':       { base: 'กรัม', factor: 1000 },
  'kg':       { base: 'กรัม', factor: 1000 },
  'KG':       { base: 'กรัม', factor: 1000 },
  'กรัม':     { base: 'กรัม', factor: 1 },
  'g':        { base: 'กรัม', factor: 1 },
  'G':        { base: 'กรัม', factor: 1 },
  'มิลลิกรัม':{ base: 'กรัม', factor: 0.001 },
  'mg':       { base: 'กรัม', factor: 0.001 },
  // ปริมาตร → มิลลิลิตร
  'ลิตร':     { base: 'มล', factor: 1000 },
  'L':        { base: 'มล', factor: 1000 },
  'l':        { base: 'มล', factor: 1000 },
  'มิลลิลิตร':{ base: 'มล', factor: 1 },
  'มล':       { base: 'มล', factor: 1 },
  'ml':       { base: 'มล', factor: 1 },
  'ML':       { base: 'มล', factor: 1 },
  'cc':       { base: 'มล', factor: 1 },
  // จำนวน → ชิ้น
  'โหล':      { base: 'ชิ้น', factor: 12 },
  'dozen':    { base: 'ชิ้น', factor: 12 },
  'ชิ้น':     { base: 'ชิ้น', factor: 1 },
  'pcs':      { base: 'ชิ้น', factor: 1 },
  'piece':    { base: 'ชิ้น', factor: 1 },
};

// หน่วยที่ต้องระบุ ratio เอง (แต่ละสินค้าไม่เท่ากัน)
const UNIT_CUSTOM_RATIO = ['แพค', 'pack', 'Pack', 'ลัง', 'case', 'ถุง', 'กล่อง', 'ขวด', 'บรรจุภัณฑ์'];

// รายการหน่วยสำหรับ dropdown
const UNIT_OPTIONS_WEIGHT  = ['กรัม','กิโลกรัม','มิลลิกรัม'];
const UNIT_OPTIONS_VOLUME  = ['มล','ลิตร','มิลลิลิตร'];
const UNIT_OPTIONS_COUNT   = ['ชิ้น','โหล','แพค','ลัง','ถุง','กล่อง','ขวด'];
const UNIT_OPTIONS_ALL     = [...UNIT_OPTIONS_WEIGHT, ...UNIT_OPTIONS_VOLUME, ...UNIT_OPTIONS_COUNT];

// แปลงจาก fromUnit → toUnit ถ้ารู้จัก คืน null ถ้าไม่รู้
function unitConvertFactor(fromUnit, toUnit) {
  const from = UNIT_KNOWN[fromUnit];
  const to   = UNIT_KNOWN[toUnit];
  if (!from || !to) return null;
  if (from.base !== to.base) return null; // ต่างประเภทแปลงไม่ได้
  return from.factor / to.factor;
}

// แปลงค่าตัวเลข qty จาก fromUnit → toUnit (คืน null ถ้าแปลงไม่ได้)
function unitConvert(qty, fromUnit, toUnit) {
  if (!fromUnit || !toUnit || fromUnit === toUnit) return Number(qty);
  const f = unitConvertFactor(fromUnit, toUnit);
  if (f == null) return null;
  return Number(qty) * f;
}

// ฉลากอธิบาย เช่น "1 กก = 1,000 กรัม"
function unitConvertLabel(qty, fromUnit, toUnit) {
  const result = unitConvert(qty, fromUnit, toUnit);
  if (result == null) return '';
  const n = result % 1 === 0 ? result.toLocaleString() : result.toLocaleString(undefined, { maximumFractionDigits: 4 });
  return `= ${n} ${toUnit}`;
}

// ต้องการ ratio จากผู้ใช้ไหม (เช่น แพค ลัง)
function unitNeedsRatio(fromUnit) {
  return UNIT_CUSTOM_RATIO.some(u => u.toLowerCase() === (fromUnit || '').toLowerCase());
}

// ============ Component: UnitQtyInput ============
// ใช้แทน <Input type="number"> + <Input unit> ทุกที่
// Props:
//   qty, unit      = ค่าที่เก็บจริง (base unit)
//   onQtyChange(v) = callback เมื่อ qty เปลี่ยน (ส่ง base qty กลับ)
//   onUnitChange(v)= callback เมื่อ unit เปลี่ยน
//   label          = ป้ายกำกับ
//   readonlyUnit   = ถ้า true unit เปลี่ยนไม่ได้ (แสดงเป็น text)
//   inputUnit      = หน่วยที่กำลังพิมพ์เข้า (state ภายนอก)
//   onInputUnitChange = callback เมื่อเปลี่ยน inputUnit
function UnitQtyInput({ qty, unit, onQtyChange, label, readonlyUnit, inputUnit, onInputUnitChange, placeholder, min, step, style }) {
  // rawQty = ค่าที่ผู้ใช้พิมพ์ใน input (ใน inputUnit)
  const [rawQty, setRawQty] = React.useState(() => {
    if (!qty) return '';
    if (!inputUnit || inputUnit === unit) return String(qty);
    const back = unitConvert(qty, unit, inputUnit);
    return back != null ? String(back) : String(qty);
  });
  const [customRatio, setCustomRatio] = React.useState('');

  const needsRatio = unitNeedsRatio(inputUnit);
  const factor = needsRatio ? (Number(customRatio) || null) : null;
  const convertLabel = React.useMemo(() => {
    const n = Number(rawQty);
    if (!n) return '';
    if (needsRatio) {
      if (!factor) return '';
      const result = n * factor;
      return `= ${result.toLocaleString()} ${unit}`;
    }
    if (!inputUnit || inputUnit === unit) return '';
    return unitConvertLabel(n, inputUnit, unit);
  }, [rawQty, inputUnit, unit, factor, needsRatio]);

  const commit = (raw, iUnit, ratio) => {
    const n = Number(raw);
    if (!n) { onQtyChange(0); return; }
    const needR = unitNeedsRatio(iUnit);
    if (needR) {
      const r = Number(ratio);
      if (!r) { onQtyChange(0); return; }
      onQtyChange(n * r);
    } else {
      const converted = unitConvert(n, iUnit || unit, unit);
      onQtyChange(converted != null ? converted : n);
    }
  };

  const handleRawChange = (v) => {
    setRawQty(v);
    commit(v, inputUnit, customRatio);
  };
  const handleUnitChange = (v) => {
    onInputUnitChange && onInputUnitChange(v);
    commit(rawQty, v, customRatio);
  };
  const handleRatioChange = (v) => {
    setCustomRatio(v);
    commit(rawQty, inputUnit, v);
  };

  return (
    <div style={style}>
      {label && <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink-2)', marginBottom: 5 }}>{label}</div>}
      <div style={{ display: 'flex', gap: 6, alignItems: 'center', flexWrap: 'wrap' }}>
        <input
          type="number" min={min ?? 0} step={step ?? 'any'}
          value={rawQty}
          onChange={e => handleRawChange(e.target.value)}
          placeholder={placeholder || '0'}
          style={{ width: 110, padding: '8px 10px', borderRadius: 8, border: '1px solid var(--line)', fontSize: 14, background: 'var(--surface)', color: 'var(--ink)' }}
        />
        {readonlyUnit
          ? <span style={{ fontSize: 14, color: 'var(--ink-2)', fontWeight: 600 }}>{unit}</span>
          : (
            <select
              value={inputUnit || unit}
              onChange={e => handleUnitChange(e.target.value)}
              style={{ padding: '8px 10px', borderRadius: 8, border: '1px solid var(--line)', fontSize: 13.5, background: 'var(--surface)', color: 'var(--ink)', cursor: 'pointer' }}
            >
              {/* หน่วยปัจจุบัน (base) อยู่ก่อนเสมอ */}
              <option value={unit}>{unit}</option>
              {UNIT_OPTIONS_ALL.filter(u => u !== unit).map(u => <option key={u} value={u}>{u}</option>)}
            </select>
          )
        }
        {needsRatio && (
          <input
            type="number" min="1" step="1"
            value={customRatio}
            onChange={e => handleRatioChange(e.target.value)}
            placeholder={`1 ${inputUnit} = ? ${unit}`}
            style={{ width: 130, padding: '8px 10px', borderRadius: 8, border: '1px solid var(--line)', fontSize: 13, background: 'var(--surface)', color: 'var(--ink)' }}
          />
        )}
      </div>
      {convertLabel && (
        <div style={{ fontSize: 12, color: 'var(--accent)', marginTop: 4, fontWeight: 600 }}>
          {rawQty} {inputUnit || unit} {convertLabel}
        </div>
      )}
    </div>
  );
}

// Component: BuyQtyUnitRow — สำหรับฟอร์ม ingredient/package
// แสดง "ซื้อ X [buyUnit] = Y [baseUnit]" และคำนวณ costPerUnit
// Props: buyPrice, buyQty, buyUnit, unit, yield_, onChange({buyQty, buyUnit, costPerUnit})
function BuyQtyUnitRow({ buyPrice, buyQty, buyUnit, unit, yield_, onChange }) {
  const [inputUnit, setInputUnit] = React.useState(buyUnit || unit || 'กรัม');
  const [rawQty, setRawQty] = React.useState(String(buyQty || ''));
  const [customRatio, setCustomRatio] = React.useState('');

  const needsRatio = unitNeedsRatio(inputUnit);

  function calcBaseQty(raw, iUnit, ratio) {
    const n = Number(raw);
    if (!n) return 0;
    if (unitNeedsRatio(iUnit)) {
      const r = Number(ratio);
      return r ? n * r : 0;
    }
    const converted = unitConvert(n, iUnit, unit);
    return converted != null ? converted : n;
  }

  function calcCpu(bQty) {
    const y = Math.max(0.01, Number(yield_) || 1);
    const q = bQty * y;
    return q ? (Number(buyPrice) || 0) / q : 0;
  }

  const baseQty = React.useMemo(() => calcBaseQty(rawQty, inputUnit, customRatio),
    [rawQty, inputUnit, unit, customRatio]);

  const cpu = React.useMemo(() => calcCpu(baseQty), [buyPrice, baseQty, yield_]);

  const convertLabel = React.useMemo(() => {
    const n = Number(rawQty);
    if (!n || inputUnit === unit) return '';
    if (needsRatio) {
      const r = Number(customRatio);
      return r ? `= ${(n * r).toLocaleString()} ${unit}` : '';
    }
    return unitConvertLabel(n, inputUnit, unit);
  }, [rawQty, inputUnit, unit, needsRatio, customRatio]);

  return (
    <div>
      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink-2)', marginBottom: 5 }}>ปริมาณที่ซื้อ</div>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
        <input
          type="number" min="0" step="any"
          value={rawQty}
          onChange={e => {
            const v = e.target.value;
            setRawQty(v);
            const bq = calcBaseQty(v, inputUnit, customRatio);
            onChange({ buyQty: bq, buyUnit: inputUnit, costPerUnit: calcCpu(bq) });
          }}
          placeholder="0"
          style={{ width: 100, padding: '8px 10px', borderRadius: 8, border: '1px solid var(--line)', fontSize: 14, background: 'var(--surface)', color: 'var(--ink)' }}
        />
        <select
          value={inputUnit}
          onChange={e => {
            const v = e.target.value;
            setInputUnit(v);
            const bq = calcBaseQty(rawQty, v, customRatio);
            onChange({ buyQty: bq, buyUnit: v, costPerUnit: calcCpu(bq) });
          }}
          style={{ padding: '8px 10px', borderRadius: 8, border: '1px solid var(--line)', fontSize: 13.5, background: 'var(--surface)', color: 'var(--ink)', cursor: 'pointer' }}
        >
          <option value={unit}>{unit} (หน่วยหลัก)</option>
          {UNIT_OPTIONS_ALL.filter(u => u !== unit).map(u => <option key={u} value={u}>{u}</option>)}
        </select>
        {needsRatio && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
            <span style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>1 {inputUnit} =</span>
            <input
              type="number" min="1" step="any"
              value={customRatio}
              onChange={e => {
                const v = e.target.value;
                setCustomRatio(v);
                const bq = calcBaseQty(rawQty, inputUnit, v);
                onChange({ buyQty: bq, buyUnit: inputUnit, costPerUnit: calcCpu(bq) });
              }}
              placeholder="?"
              style={{ width: 80, padding: '8px 10px', borderRadius: 8, border: '1px solid var(--line)', fontSize: 14, background: 'var(--surface)', color: 'var(--ink)' }}
            />
            <span style={{ fontSize: 12.5, color: 'var(--ink-3)' }}>{unit}</span>
          </div>
        )}
      </div>
      {convertLabel && (
        <div style={{ fontSize: 12, color: 'var(--accent)', marginTop: 4, fontWeight: 600 }}>
          {rawQty} {inputUnit} {convertLabel}
        </div>
      )}
      {baseQty > 0 && inputUnit !== unit && (
        <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 3 }}>
          บันทึกเป็น {baseQty.toLocaleString()} {unit}
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  unitConvert, unitConvertFactor, unitConvertLabel, unitNeedsRatio,
  UNIT_OPTIONS_ALL, UNIT_OPTIONS_WEIGHT, UNIT_OPTIONS_VOLUME, UNIT_OPTIONS_COUNT,
  UnitQtyInput, BuyQtyUnitRow,
});
