import argparse
import csv
import sys
import time
from datetime import datetime, timezone
from pathlib import Path

from dotenv import load_dotenv
import os

load_dotenv(Path(".env"))

sys.path.insert(0, str(Path(__file__).parent))
from src.ibkr_client import IBKRClient

parser = argparse.ArgumentParser()
parser.add_argument("--symbol", required=True)
parser.add_argument("--side", required=True)
parser.add_argument("--size", type=int, required=True)
args = parser.parse_args()

host = os.getenv("IBKR_HOST", "127.0.0.1")
port = int(os.getenv("IBKR_PORT", 7497))
client_id = int(os.getenv("IBKR_EXEC_CLIENT_ID", 3))

ibkr = None
try:
    ibkr = IBKRClient(host, port, client_id)
    trade = ibkr.place_order(args.symbol, args.side, args.size)

    status = trade.orderStatus.status
    if status in ("Cancelled", "ApiCancelled", "Inactive"):
        print(f"Order {status}. Log:")
        for entry in trade.log:
            print(" ", entry)
        sys.exit(1)

    fill_price = trade.orderStatus.avgFillPrice or 0
    order_id = trade.order.orderId
    timestamp = datetime.now(timezone.utc).isoformat()

    trades_path = Path("trades.csv")
    write_header = not trades_path.exists()

    for attempt in range(2):
        try:
            with open(trades_path, "a", newline="") as f:
                writer = csv.writer(f)
                if write_header:
                    writer.writerow(["timestamp_iso", "symbol", "side", "size", "fill_price", "order_id", "status"])
                writer.writerow([timestamp, args.symbol, args.side, args.size, fill_price, order_id, status])
            break
        except PermissionError:
            if attempt == 0:
                time.sleep(1)
            else:
                print("trades.csv locked after retry — exiting")
                sys.exit(1)

    print(f"OK symbol={args.symbol} side={args.side} size={args.size} fill={fill_price} status={status} order_id={order_id}")

except Exception as e:
    print(f"Error: {e}")
    sys.exit(1)
finally:
    if ibkr:
        ibkr.disconnect()
