// Round up to the next multiple of MOQ. moq=12, qty=7 → 12; qty=15 → 24; qty=24 → 24.
// MOQ <= 0 or missing means no rounding constraint.
const roundUpToMoq = (qty, moq) => {
  if (!moq || moq <= 1) return Math.max(0, qty);
  if (qty <= 0) return 0;
  return Math.ceil(qty / moq) * moq;
};

// Requisition modal — table with editable order quantities. The displayed
// "Actual" column applies the per-product Minimum Order Quantity rule and
// is what gets submitted (rounded up to the next MOQ multiple).
const RequisitionModal = ({ open, onClose, title, rows, onSubmit }) => {
  const [editedRows, setEditedRows] = React.useState([]);
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState(null);

  React.useEffect(() => {
    if (open) {
      setEditedRows(rows.map(r => ({ ...r, quantity: Math.max(0, r.order_qty_predicted || 0) })));
      setError(null);
      setSubmitting(false);
    }
  }, [open, rows]);

  // "Actual" = quantity rounded up to MOQ multiple. This is what's submitted.
  const withActual = editedRows.map(r => ({
    ...r,
    actual: roundUpToMoq(parseInt(r.quantity) || 0, r.minimumOrderQuantity),
  }));
  const total = withActual.reduce((s, r) => s + r.actual, 0);
  const itemCount = withActual.filter(r => r.actual > 0).length;

  const updateQty = (idx, val) => {
    const v = val === '' ? 0 : Math.max(0, parseInt(val) || 0);
    setEditedRows(prev => prev.map((r, i) => i === idx ? { ...r, quantity: v } : r));
  };

  const handleSubmit = async () => {
    setSubmitting(true);
    setError(null);
    try {
      const payload = withActual
        .filter(r => r.actual > 0)
        .map(r => ({ product_id: r.product_id, branch_id: r.branch_id, quantity: r.actual }));
      const res = await window.authFetch('/api/orders', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ orders: payload }),
      });
      if (!res.ok) {
        let detail = '';
        try { detail = (await res.json()).detail || ''; } catch (_) { detail = await res.text(); }
        throw new Error(detail || `Server returned ${res.status}`);
      }
      onSubmit(payload);
    } catch (e) {
      setError(e.message);
      setSubmitting(false);
    }
  };

  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6">
      <div className="absolute inset-0 bg-slate-900/30" onClick={onClose} />
      <div className="relative bg-white rounded-xl shadow-2xl w-full max-w-4xl max-h-[90vh] flex flex-col border border-slate-200">
        {/* Header */}
        <div className="flex items-start justify-between p-5 border-b border-slate-200">
          <div>
            <h2 className="text-lg font-semibold text-slate-900">{title}</h2>
            <p className="text-sm text-slate-500 mt-0.5">
              Quantities are pre-filled from the forecast model. The <strong>Actual</strong> column rounds up to the next Minimum Order Quantity multiple — that's the value submitted.
            </p>
          </div>
          <button
            onClick={onClose}
            className="p-1.5 hover:bg-slate-100 rounded-md text-slate-400 hover:text-slate-600 transition"
          >
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
              <path d="M5 5l10 10M15 5L5 15" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
            </svg>
          </button>
        </div>

        {/* Table */}
        <div className="flex-1 overflow-auto">
          <table className="w-full text-sm">
            <thead className="sticky top-0 bg-slate-50 border-b border-slate-200 text-xs uppercase tracking-wide text-slate-500">
              <tr>
                <th className="text-left px-5 py-3 font-medium">Product</th>
                <th className="text-left px-3 py-3 font-medium">Branch</th>
                <th className="text-right px-3 py-3 font-medium">Predicted</th>
                <th className="text-right px-3 py-3 font-medium">Inventory</th>
                <th className="text-right px-3 py-3 font-medium" title="Minimum Order Quantity">MOQ</th>
                <th className="text-right px-3 py-3 font-medium w-32">Order Qty</th>
                <th className="text-right px-5 py-3 font-medium" title="Quantity rounded up to next MOQ multiple — this is what's submitted">Actual</th>
              </tr>
            </thead>
            <tbody>
              {withActual.map((r, i) => {
                const bumped = r.actual !== (parseInt(r.quantity) || 0);
                return (
                  <tr key={i} className="border-b border-slate-100 hover:bg-slate-50/50">
                    <td className="px-5 py-2.5 text-slate-900 font-medium">{r.product}</td>
                    <td className="px-3 py-2.5 text-slate-600">{r.branch}</td>
                    <td className="px-3 py-2.5 text-right tabular-nums text-slate-700">{Math.max(0, Math.round(r.predicted || 0))}</td>
                    <td className="px-3 py-2.5 text-right tabular-nums text-slate-700">{Math.max(0, Math.round(r.inventory || 0))}</td>
                    <td className="px-3 py-2.5 text-right tabular-nums text-slate-500">{r.minimumOrderQuantity || '—'}</td>
                    <td className="px-3 py-2 text-right">
                      <input
                        type="number"
                        min="0"
                        value={r.quantity}
                        onChange={(e) => updateQty(i, e.target.value)}
                        className="w-24 px-2.5 py-1.5 border border-slate-200 rounded-md text-right tabular-nums text-slate-900 focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500"
                      />
                    </td>
                    <td className="px-5 py-2.5 text-right tabular-nums">
                      <span className={`inline-flex items-center gap-1 font-semibold ${bumped ? 'text-amber-700' : 'text-slate-900'}`} title={bumped ? `Rounded up from ${r.quantity} to next MOQ multiple` : ''}>
                        {r.actual.toLocaleString()}
                        {bumped && (
                          <svg width="11" height="11" viewBox="0 0 12 12" fill="none">
                            <path d="M6 2v8m0 0L3 7m3 3l3-3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" transform="rotate(180 6 6)"/>
                          </svg>
                        )}
                      </span>
                    </td>
                  </tr>
                );
              })}
              {withActual.length === 0 && (
                <tr><td colSpan="7" className="px-5 py-12 text-center text-slate-400">No products to order.</td></tr>
              )}
            </tbody>
          </table>
        </div>

        {/* Footer */}
        <div className="border-t border-slate-200 p-5 flex items-center justify-between gap-4 bg-slate-50/50">
          <div className="text-sm text-slate-600">
            <span className="font-semibold text-slate-900">{itemCount}</span> items ·
            Total: <span className="font-semibold text-slate-900 tabular-nums">{total.toLocaleString()}</span> units
          </div>
          <div className="flex items-center gap-3">
            {error && <span className="text-sm text-red-600">{error}</span>}
            <button
              onClick={onClose}
              className="px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-100 rounded-md transition"
              disabled={submitting}
            >Cancel</button>
            <button
              onClick={handleSubmit}
              disabled={submitting || itemCount === 0}
              className="px-5 py-2 text-sm font-semibold text-white bg-red-600 hover:bg-red-700 disabled:bg-slate-300 disabled:cursor-not-allowed rounded-md transition shadow-sm"
            >
              {submitting ? 'Submitting…' : 'Submit Order'}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

// Toast notification
const Toast = ({ open, type, message, onClose }) => {
  React.useEffect(() => {
    if (open) {
      const t = setTimeout(onClose, 3500);
      return () => clearTimeout(t);
    }
  }, [open, onClose]);
  if (!open) return null;
  const styles = {
    success: { bg: 'bg-green-50', border: 'border-green-200', text: 'text-green-900', icon: 'text-green-600' },
    error: { bg: 'bg-red-50', border: 'border-red-200', text: 'text-red-900', icon: 'text-red-600' },
  }[type] || { bg: 'bg-slate-50', border: 'border-slate-200', text: 'text-slate-900', icon: 'text-slate-600' };
  return (
    <div className="fixed bottom-6 right-6 z-[60] animate-slide-up">
      <div className={`flex items-center gap-3 px-4 py-3 rounded-lg shadow-lg border ${styles.bg} ${styles.border} ${styles.text} max-w-sm`}>
        <div className={styles.icon}>
          {type === 'success' ? (
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
              <circle cx="10" cy="10" r="9" stroke="currentColor" strokeWidth="1.5" />
              <path d="M6 10l3 3 5-6" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          ) : (
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
              <circle cx="10" cy="10" r="9" stroke="currentColor" strokeWidth="1.5" />
              <path d="M10 6v5M10 14h.01" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
            </svg>
          )}
        </div>
        <div className="text-sm font-medium">{message}</div>
        <button onClick={onClose} className="ml-2 opacity-50 hover:opacity-100">
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
            <path d="M3 3l8 8M11 3l-8 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
          </svg>
        </button>
      </div>
    </div>
  );
};

// Change Password modal — three fields, client-side confirm-match check,
// real validation happens server-side on /api/change-password.
const ChangePasswordModal = ({ open, onClose, onSuccess }) => {
  const [currentPwd, setCurrentPwd] = React.useState('');
  const [newPwd, setNewPwd]         = React.useState('');
  const [confirmPwd, setConfirmPwd] = React.useState('');
  const [error, setError]           = React.useState(null);
  const [submitting, setSubmitting] = React.useState(false);

  React.useEffect(() => {
    if (open) {
      setCurrentPwd(''); setNewPwd(''); setConfirmPwd('');
      setError(null); setSubmitting(false);
    }
  }, [open]);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError(null);

    if (!currentPwd) { setError('Enter your current password.'); return; }
    if (!newPwd)     { setError('Enter a new password.');        return; }
    if (newPwd !== confirmPwd) { setError('New passwords do not match.'); return; }
    if (newPwd === currentPwd) { setError('New password must differ from current password.'); return; }

    setSubmitting(true);
    try {
      const res = await window.authFetch('/api/change-password', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ current_password: currentPwd, new_password: newPwd }),
      });
      if (!res.ok) {
        let detail = 'Failed to change password';
        try { detail = (await res.json()).detail || detail; } catch (_) {}
        throw new Error(detail);
      }
      onSuccess && onSuccess();
      onClose();
    } catch (err) {
      setError(err.message);
      setSubmitting(false);
    }
  };

  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 sm:p-6">
      <div className="absolute inset-0 bg-slate-900/30" onClick={onClose} />
      <div className="relative bg-white rounded-xl shadow-2xl w-full max-w-md border border-slate-200">
        <div className="flex items-start justify-between p-5 border-b border-slate-200">
          <div>
            <h2 className="text-base font-semibold text-slate-900">Change password</h2>
            <p className="text-xs text-slate-500 mt-0.5">Your current session stays signed in.</p>
          </div>
          <button onClick={onClose} className="p-1.5 hover:bg-slate-100 rounded-md text-slate-400 hover:text-slate-600 transition">
            <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
              <path d="M5 5l10 10M15 5L5 15" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
            </svg>
          </button>
        </div>

        <form onSubmit={handleSubmit} className="p-5 space-y-3.5">
          <PwdField label="Current password" value={currentPwd} onChange={setCurrentPwd} autoFocus autoComplete="current-password" />
          <PwdField label="New password"     value={newPwd}     onChange={setNewPwd}     autoComplete="new-password" />
          <PwdField label="Confirm new password" value={confirmPwd} onChange={setConfirmPwd} autoComplete="new-password" />

          {error && (
            <div className="text-xs text-red-700 bg-red-50 border border-red-200 rounded px-3 py-2">{error}</div>
          )}

          <div className="flex items-center justify-end gap-2 pt-1">
            <button type="button" onClick={onClose}
                    className="px-3 py-1.5 text-sm text-slate-600 hover:bg-slate-100 rounded-md transition">
              Cancel
            </button>
            <button type="submit" disabled={submitting}
                    className="px-4 py-1.5 text-sm font-medium text-white bg-red-600 hover:bg-red-700 disabled:bg-slate-300 disabled:cursor-not-allowed rounded-md transition">
              {submitting ? 'Updating…' : 'Update password'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

const PwdField = ({ label, value, onChange, autoFocus = false, autoComplete }) => (
  <div>
    <label className="block text-xs font-medium text-slate-600 mb-1">{label}</label>
    <input
      type="password"
      value={value}
      onChange={(e) => onChange(e.target.value)}
      autoFocus={autoFocus}
      autoComplete={autoComplete}
      className="w-full px-3 py-2 text-sm border border-slate-300 rounded focus:border-red-500 focus:ring-1 focus:ring-red-500 outline-none"
    />
  </div>
);

window.RequisitionModal = RequisitionModal;
window.ChangePasswordModal = ChangePasswordModal;
window.Toast = Toast;
window.roundUpToMoq = roundUpToMoq;
