// T2 Falcon Admin — Balance Transfer drawer (right-side slide-in)
// Source / Destination holders, optional channel pickers, amount + description.
//
// Holders (multiple-wallets mode): Master Wallet, the Master's comm-channel
// pools (WhatsApp / Voice / AI-ChatGPT …), and every node/user. A node/user
// holder also exposes WHICH channel wallet (source/destination wallet).
// Allowed pairs are enforced exactly per spec:
//   multiple:  master⇄comm-channel,  comm-channel⇄node/user,  node/user⇄node/user
//   single:    master⇄node/user,     node/user⇄node/user

const { useState: useStateBT, useMemo: useMemoBT, useEffect: useEffectBT } = React;

const BalanceTransferDrawer = ({
  source,            // the holder whose Transfer button was clicked
  rows,              // current org/user rows
  masterName,
  channels,          // active channel ids (multiple) or null (single)
  walletType,        // 'single' | 'multiple'
  balanceType,       // 'node' | 'user'
  masterSubBalances, // { whatsapp, voice, aichat, … } comm-channel pool balances (Falcon view)
  noMaster,          // Show-as-Client: the Master Wallet is NOT a transfer holder
  getAlloc,
  t,
  onClose,
  onConfirm,
}) => {
  const isMulti = walletType === 'multiple';
  const chList = channels || [];

  // ---- Holder option lists ----
  const masterOpt = { id: '__master', type: 'master', label: (masterName ? masterName + ' — ' : '') + t.wbMasterWallet };
  const commchOpts = isMulti ? chList.map(chId => {
    const c = WB_CHANNELS.find(x => x.id === chId);
    const base = noMaster ? (t.wbCommChannelWallet || 'Comm-channel') : t.wbMasterWallet;
    return { id: '__ch_' + chId, type: 'commch', ch: chId, label: base + ' · ' + ((c && t[c.label]) || chId) };
  }) : [];
  // The transfer holders follow Balance Type: USERS in user-based mode, NODES in
  // node-based mode. (tableRows already omits users in node mode, but filter both
  // ways so the Source/Destination lists never mix node and user holders.)
  const entityOpts = rows
    .filter(r => r.depth >= 0 && (balanceType === 'user' ? r.kind === 'user' : r.kind !== 'user'))
    .map(r => {
      const indent = r.depth > 0 ? '— ' : '';
      const prefix = r.kind === 'user' ? '👤 ' : '';
      return { id: r.id, type: 'entity', row: r, label: indent + prefix + r.name };
    });
  const allOpts = (noMaster ? [] : [masterOpt]).concat(commchOpts, entityOpts);
  const findOpt = (id) => allOpts.find(o => o.id === id);

  // ---- State (resolve the clicked holder to a known option id) ----
  const initialSourceId =
    (source && source.isCommch && isMulti) ? '__ch_' + source.ch
    : (source && source.isMaster)          ? '__master'
    : (source && source.id)                ? source.id
    : '';
  const [sourceId, setSourceId] = useStateBT(initialSourceId);
  const [sourceCh, setSourceCh] = useStateBT(isMulti ? (source?.ch || chList[0] || 'whatsapp') : 'single');
  const [destId, setDestId]     = useStateBT('');
  const [destCh, setDestCh]     = useStateBT(isMulti ? (chList[0] || 'whatsapp') : 'single');
  const [amount, setAmount]     = useStateBT('');
  const [description, setDesc]  = useStateBT('');

  const srcOpt = findOpt(sourceId);

  // ---- Valid destinations for the chosen source (enforces the spec's pairs) ----
  const destOptions = useMemoBT(() => {
    if (!srcOpt) return [];
    if (noMaster) {
      // Show-as-Client: master is never a holder. Allowed pairs:
      //   comm-channel → node/user, node → node, user → user.
      if (srcOpt.type === 'commch') return entityOpts;
      return entityOpts.filter(o => o.id !== sourceId);
    }
    if (!isMulti) {
      // single: master ⇄ node/user, node/user ⇄ node/user
      return srcOpt.type === 'master'
        ? entityOpts
        : [masterOpt, ...entityOpts.filter(o => o.id !== sourceId)];
    }
    // multiple
    if (srcOpt.type === 'master') return commchOpts;                  // master → comm-channel pool
    if (srcOpt.type === 'commch') return [masterOpt, ...entityOpts];  // comm-channel → master | node/user
    // node/user → the matching comm-channel pool, or another node/user
    return [...commchOpts.filter(o => o.ch === sourceCh), ...entityOpts.filter(o => o.id !== sourceId)];
  }, [srcOpt, sourceId, sourceCh, isMulti, rows, chList.join(','), noMaster]);

  // keep destination valid as source / its channel changes
  useEffectBT(() => {
    if (!destOptions.find(o => o.id === destId)) setDestId(destOptions[0] ? destOptions[0].id : '');
  }, [destOptions]);

  const dstOpt = findOpt(destId);

  // The transfer's channel (multiple mode): the comm-channel holder carries its
  // own; otherwise it's the node/user source wallet. master is channel-less.
  const lockCh = !isMulti ? 'single'
    : srcOpt && srcOpt.type === 'commch' ? srcOpt.ch
    : dstOpt && dstOpt.type === 'commch' ? dstOpt.ch
    : srcOpt && srcOpt.type === 'entity' ? sourceCh
    : null;

  // a node/user destination wallet is locked to the transfer channel (no cross-channel)
  useEffectBT(() => {
    if (isMulti && dstOpt && dstOpt.type === 'entity' && lockCh && destCh !== lockCh) setDestCh(lockCh);
  }, [dstOpt, lockCh]);

  const showSourceWallet = isMulti && srcOpt && srcOpt.type === 'entity';
  const showDestWallet   = isMulti && dstOpt && dstOpt.type === 'entity';

  // ---- Available balance at the source ----
  const sourceMax =
    !srcOpt                     ? 0
    : srcOpt.type === 'master'  ? Infinity
    : srcOpt.type === 'commch'  ? (masterSubBalances == null ? Infinity : (Number(masterSubBalances[srcOpt.ch]) || 0))
    : getAlloc(srcOpt.row, isMulti ? sourceCh : 'single');

  const amountNum = parseInt(String(amount).replace(/[^\d]/g, ''), 10) || 0;
  const canSave = !!srcOpt && !!dstOpt && sourceId !== destId && amountNum > 0 && amountNum <= sourceMax;

  const handleSave = () => {
    if (!canSave) return;
    onConfirm({
      sourceId: srcOpt.type === 'master' ? null : sourceId,
      sourceCh: srcOpt.type === 'commch' ? srcOpt.ch : (isMulti ? sourceCh : 'single'),
      destId:   dstOpt.type === 'master' ? null : destId,
      destCh:   dstOpt.type === 'commch' ? dstOpt.ch : (isMulti ? destCh : 'single'),
      amount: amountNum,
      description,
    });
  };

  return (
    <Drawer
      title={t.wbBalanceTransfer}
      onClose={onClose}
      footer={(
        <>
          <button className="btn btn-secondary" onClick={onClose}>{t.cancel}</button>
          <button className="btn btn-primary" disabled={!canSave} onClick={handleSave}>{t.save}</button>
        </>
      )}
    >
      <div className="wb-drawer-body wb-drawer-body-shared">
          {/* Source */}
          <div className="wb-fld">
            <label className="wb-fld-label">{t.wbSource}</label>
            <WBSelect value={sourceId} onChange={setSourceId} options={allOpts} placeholder={t.wbSelect} />
          </div>

          {/* Source Wallet — only when the source is a node/user (multiple mode) */}
          {showSourceWallet && (
            <div className="wb-fld">
              <label className="wb-fld-label">{t.wbSourceWallet}</label>
              <WBChannelSelect value={sourceCh} onChange={setSourceCh} channels={chList} t={t} />
            </div>
          )}

          {/* Destination */}
          <div className="wb-fld">
            <label className="wb-fld-label">{t.wbDestination}</label>
            <WBSelect value={destId} onChange={setDestId} options={destOptions} placeholder={t.wbSelect} />
          </div>

          {/* Destination Wallet — only when the destination is a node/user; locked to the transfer channel */}
          {showDestWallet && (
            <div className="wb-fld">
              <label className="wb-fld-label">{t.wbDestinationWallet}</label>
              <WBChannelSelect value={destCh} onChange={setDestCh} channels={chList} t={t} disabled={true} />
              <div className="wb-fld-hint" style={{ justifyContent: 'flex-start', gap: 6 }}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" style={{ color: 'var(--text-muted)' }}>
                  <rect x="3.5" y="7" width="9" height="6.5" rx="1.5" /><path d="M5.5 7V5a2.5 2.5 0 0 1 5 0v2" />
                </svg>
                <span>{t.wbCrossChannelLocked || 'Locked to the source channel'}</span>
              </div>
            </div>
          )}

          {/* Transfer Amount — ريال always shown as a prefix before the number */}
          <div className="wb-fld">
            <label className="wb-fld-label">{t.wbTransferAmount}</label>
            <div className={`wb-amount-input wb-amount-input--prefix${srcOpt && isFinite(sourceMax) && amountNum > sourceMax ? ' is-error' : ''}`}>
              <span className="wb-amount-prefix" aria-hidden="true"><RiyalMark size={14} currency="SAR" /></span>
              <input
                value={amount === '' ? '' : Number(String(amount).replace(/[^\d]/g, '')).toLocaleString('en-US')}
                onChange={(e) => setAmount(e.target.value.replace(/[^\d]/g, ''))}
                placeholder="0"
                inputMode="numeric"
              />
            </div>
            {srcOpt && isFinite(sourceMax) && (
              <div className="wb-fld-hint" style={{ justifyContent: 'flex-start', gap: 4 }}>
                <span>{(t.wbAvailable || 'Available')}:</span>
                <RiyalMark size={11} currency="SAR" />
                <strong>{fmtTotal(sourceMax)}</strong>
              </div>
            )}
            {srcOpt && isFinite(sourceMax) && amountNum > sourceMax && (
              <div className="wb-fld-error">{t.wbExceedsAvailable || 'Amount exceeds the available balance.'}</div>
            )}
          </div>

          {/* Transfer Description */}
          <div className="wb-fld">
            <label className="wb-fld-label">{t.wbTransferDescription}</label>
            <textarea
              className="wb-textarea"
              rows="3"
              value={description}
              onChange={(e) => setDesc(e.target.value)}
              placeholder={t.wbDescPlaceholder}
            />
          </div>
      </div>
    </Drawer>
  );
};

// ====== Lightweight select (custom popover, matches drawer chrome) ======
const WBSelect = ({ value, onChange, options, placeholder }) => {
  const [open, setOpen] = useStateBT(false);
  const wrap = React.useRef(null);
  useEffectBT(() => {
    const onDoc = (e) => { if (wrap.current && !wrap.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);
  const sel = options.find(o => o.id === value);
  return (
    <div className={`wb-select-wrap ${open ? 'open' : ''}`} ref={wrap}>
      <button type="button" className="wb-select-btn" onClick={() => setOpen(!open)}>
        <span className="wb-select-search-icon">
          <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="7" cy="7" r="4.5" /><path d="m13 13-2.5-2.5" />
          </svg>
        </span>
        <span className={`wb-select-value ${!sel ? 'placeholder' : ''}`}>{sel ? sel.label : placeholder}</span>
        <span className="wb-select-chev">
          <svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m4 6 4 4 4-4" /></svg>
        </span>
      </button>
      {open && (
        <div className="wb-select-menu">
          {options.map(o => (
            <button key={o.id} type="button"
              className={`wb-select-opt ${o.id === value ? 'active' : ''}`}
              onClick={() => { onChange(o.id); setOpen(false); }}>
              {o.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

// ====== Channel select for source/destination wallet (icon + name dropdown) ======
const WBChannelSelect = ({ value, onChange, channels, t, disabled }) => {
  const [open, setOpen] = useStateBT(false);
  const wrap = React.useRef(null);
  useEffectBT(() => {
    const onDoc = (e) => { if (wrap.current && !wrap.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);
  const sel = WB_CHANNELS.find(c => c.id === value);
  return (
    <div className={`wb-select-wrap wb-ch-dd ${open ? 'open' : ''} ${disabled ? 'disabled' : ''}`} ref={wrap}>
      <button type="button" className="wb-select-btn"
        disabled={disabled}
        onClick={() => !disabled && setOpen(!open)}>
        <span className={`wb-select-value ${!sel ? 'placeholder' : ''}`}>
          {sel ? t[sel.label] : t.wbSelect}
        </span>
        {disabled ? (
          <span className="wb-select-chev">
            <svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
              <rect x="3.5" y="7" width="9" height="6.5" rx="1.5" /><path d="M5.5 7V5a2.5 2.5 0 0 1 5 0v2" />
            </svg>
          </span>
        ) : (
          <span className="wb-select-chev">
            <svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m4 6 4 4 4-4" /></svg>
          </span>
        )}
      </button>
      {open && !disabled && (
        <div className="wb-select-menu">
          {channels.map(chId => {
            const ch = WB_CHANNELS.find(c => c.id === chId);
            return (
              <button key={chId} type="button"
                className={`wb-select-opt wb-ch-dd-opt ${chId === value ? 'active' : ''}`}
                onClick={() => { onChange(chId); setOpen(false); }}>
                <span>{t[ch.label]}</span>
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
};

window.BalanceTransferDrawer = BalanceTransferDrawer;
