#!/usr/bin/env python3
"""
LuckySt - Deposit USDC from Base wallet to Kalshi via Base network.

Usage:
    python deposit_to_kalshi.py <kalshi_deposit_address> [amount_usdc]

Steps:
    1. Go to kalshi.com -> Add Funds -> Crypto -> Select Base network
    2. Copy the deposit address Kalshi gives you
    3. Run this script with that address
"""

import os
import sys
import json
import asyncio
from decimal import Decimal

# Network config
NETWORK = os.environ.get("LUCKYST_NETWORK", "mainnet")

NETWORK_CONFIG = {
    "mainnet": {
        "chain_id": 8453,
        "rpc_url": "https://mainnet.base.org",
        "usdc_address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "name": "Base Mainnet",
    },
    "testnet": {
        "chain_id": 84532,
        "rpc_url": "https://sepolia.base.org",
        "usdc_address": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
        "name": "Base Sepolia",
    },
}

config = NETWORK_CONFIG[NETWORK]
USDC_DECIMALS = 6

# Minimal ERC20 ABI for transfer and balanceOf
ERC20_ABI = json.loads("""[
    {"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},
    {"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"type":"function"}
]""")

WALLET_PATH = os.path.expanduser("~/.luckyst_base_wallet.json")


def load_wallet():
    """Load wallet from secure keyfile"""
    if not os.path.exists(WALLET_PATH):
        print(f"Wallet not found at {WALLET_PATH}")
        sys.exit(1)

    with open(WALLET_PATH, "r") as f:
        data = json.load(f)

    return data["address"], data["private_key"]


async def check_balance(w3, address):
    """Check USDC balance on Base"""
    usdc = w3.eth.contract(
        address=w3.to_checksum_address(config["usdc_address"]),
        abi=ERC20_ABI,
    )
    balance = usdc.functions.balanceOf(w3.to_checksum_address(address)).call()
    return balance


async def check_eth_balance(w3, address):
    """Check ETH balance for gas"""
    return w3.eth.get_balance(w3.to_checksum_address(address))


async def send_usdc(w3, private_key, from_address, to_address, amount_raw):
    """Send USDC on Base"""
    usdc = w3.eth.contract(
        address=w3.to_checksum_address(config["usdc_address"]),
        abi=ERC20_ABI,
    )

    from_addr = w3.to_checksum_address(from_address)
    to_addr = w3.to_checksum_address(to_address)

    # Build transaction
    nonce = w3.eth.get_transaction_count(from_addr)

    tx = usdc.functions.transfer(to_addr, amount_raw).build_transaction({
        "chainId": config["chain_id"],
        "from": from_addr,
        "nonce": nonce,
        "gas": 100000,
        "maxFeePerGas": w3.eth.gas_price * 2,
        "maxPriorityFeePerGas": w3.to_wei("0.001", "gwei"),
    })

    # Sign and send
    signed = w3.eth.account.sign_transaction(tx, private_key)
    tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)

    print(f"Transaction sent: 0x{tx_hash.hex()}")
    print("Waiting for confirmation...")

    receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)

    if receipt["status"] == 1:
        print(f"Confirmed in block {receipt['blockNumber']}")
        return tx_hash.hex()
    else:
        print("Transaction FAILED")
        return None


async def main():
    from web3 import Web3

    if len(sys.argv) < 2:
        print("Usage: python deposit_to_kalshi.py <kalshi_deposit_address> [amount_usdc]")
        print()
        print("Steps:")
        print("  1. Go to kalshi.com -> Add Funds -> Crypto -> Base")
        print("  2. Copy the deposit address")
        print("  3. Run: python deposit_to_kalshi.py 0xYourKalshiDepositAddress 20")
        sys.exit(1)

    kalshi_address = sys.argv[1]
    amount_usdc = Decimal(sys.argv[2]) if len(sys.argv) > 2 else None

    # Validate address
    if not kalshi_address.startswith("0x") or len(kalshi_address) != 42:
        print("Invalid address format. Must be 0x... (42 characters)")
        sys.exit(1)

    # Load wallet
    wallet_address, private_key = load_wallet()
    print(f"Network: {config['name']}")
    print(f"Wallet: {wallet_address}")
    print(f"Kalshi deposit address: {kalshi_address}")

    # Connect to Base
    w3 = Web3(Web3.HTTPProvider(config["rpc_url"]))
    if not w3.is_connected():
        print("Failed to connect to Base RPC")
        sys.exit(1)
    print(f"Connected to {config['name']} (chain {config['chain_id']})")

    # Check balances
    usdc_balance = await check_balance(w3, wallet_address)
    eth_balance = await check_eth_balance(w3, wallet_address)
    usdc_human = usdc_balance / 10**USDC_DECIMALS
    eth_human = eth_balance / 10**18

    print(f"USDC balance: {usdc_human:.2f} USDC")
    print(f"ETH balance: {eth_human:.6f} ETH (for gas)")

    if usdc_balance == 0:
        print()
        print(f"No USDC in wallet. Send USDC on Base to: {wallet_address}")
        sys.exit(0)

    if eth_balance == 0:
        print()
        print(f"No ETH for gas. Send a small amount of ETH on Base to: {wallet_address}")
        print("(~$0.01 worth of ETH is enough for Base transactions)")
        sys.exit(0)

    # Determine amount
    if amount_usdc is None:
        amount_usdc = usdc_human  # Send all

    amount_raw = int(amount_usdc * 10**USDC_DECIMALS)

    if amount_raw > usdc_balance:
        print(f"Insufficient balance: {usdc_human:.2f} USDC < {amount_usdc:.2f} USDC")
        sys.exit(1)

    print()
    print(f"=== DEPOSIT TO KALSHI ===")
    print(f"Amount: {amount_usdc:.2f} USDC")
    print(f"From:   {wallet_address}")
    print(f"To:     {kalshi_address}")
    print(f"Network: {config['name']}")
    print(f"=========================")
    print()

    confirm = input("Confirm deposit? (yes/no): ").strip().lower()
    if confirm != "yes":
        print("Cancelled.")
        sys.exit(0)

    tx_hash = await send_usdc(w3, private_key, wallet_address, kalshi_address, amount_raw)

    if tx_hash:
        explorer = "https://basescan.org" if NETWORK == "mainnet" else "https://sepolia.basescan.org"
        print()
        print(f"Deposit successful!")
        print(f"TX: {explorer}/tx/0x{tx_hash}")
        print()
        print("Kalshi typically processes Base deposits within 30 minutes.")
        print("Check your Kalshi balance at kalshi.com")


if __name__ == "__main__":
    asyncio.run(main())
