"""Move cash between Kalshi subaccounts.

    python main\\kalshi_transfer.py            -> sweep ALL of subaccount 1 into 0
    python main\\kalshi_transfer.py 1 0 12.50  -> move $12.50 from 1 to 0

WHY A SCRIPT. The balances endpoint returns DOLLARS as a decimal string
("33.8623") while the transfer endpoint takes an INTEGER amount_cents, so the
conversion is a place to silently lose or invent money. Decimal + ROUND_DOWN
here: never transfer more than the account actually holds, and leave the
sub-cent remainder behind rather than risk a rejection.

SAFE TO RE-RUN. The sweep moves whatever is there; once swept the balance is
~0 and a second run transfers nothing. Each run sends a fresh
client_transfer_id, so this is NOT protection against a deliberate double
transfer -- it just means an accidental re-run is a no-op.

Open positions do NOT need the cash: Kalshi contracts are paid for at purchase,
so a long position is unaffected by sweeping the balance. Proceeds from a
position that settles LATER land in the subaccount that held it, so a swept
subaccount can show a balance again after settlement.
"""
import json
import sys
import uuid
from decimal import Decimal, ROUND_DOWN

sys.path.insert(0, r'E:\soccer\main')
import kalshi_trader as kt

TRANSFER_PATH = '/portfolio/subaccounts/transfer'


def balances():
    out = {}
    for b in kt._get('/portfolio/subaccounts/balances').get(
            'subaccount_balances', []) or []:
        out[int(b['subaccount_number'])] = Decimal(str(b['balance']))
    return out


def main():
    a = sys.argv[1:]
    src = int(a[0]) if len(a) > 0 else 1
    dst = int(a[1]) if len(a) > 1 else 0
    before = balances()
    if src not in before:
        print(f'subaccount {src} not found; have {sorted(before)}')
        return 1
    if len(a) > 2:
        amount = Decimal(a[2])
        if amount > before[src]:
            print(f'refusing: asked ${amount} but subaccount {src} holds '
                  f'${before[src]}')
            return 1
    else:
        amount = before[src]
    cents = int((amount * 100).to_integral_value(rounding=ROUND_DOWN))

    print('BEFORE: ' + '  '.join(f'#{k} ${v}' for k, v in sorted(before.items())))
    if cents <= 0:
        print('nothing to transfer')
        return 0
    print(f'transferring {cents} cents (${cents / 100:.2f}) '
          f'from #{src} -> #{dst}')

    body = {'client_transfer_id': str(uuid.uuid4()),
            'from_subaccount': src, 'to_subaccount': dst,
            'amount_cents': cents}
    try:
        r = kt._post(TRANSFER_PATH, body)
    except Exception as e:
        print(f'TRANSFER FAILED: {type(e).__name__}: {e}')
        return 1
    print('response: ' + (json.dumps(r)[:300] if r else '(empty)'))

    after = balances()
    print('AFTER : ' + '  '.join(f'#{k} ${v}' for k, v in sorted(after.items())))
    moved = after.get(dst, Decimal(0)) - before.get(dst, Decimal(0))
    print(f'#{dst} changed by ${moved}')
    return 0


if __name__ == '__main__':
    sys.exit(main())
