"""
closer.py — force-close all open positions at/after 15:51 ET.
Run as a scheduler job or manually: python closer.py
"""
import csv
import sys
from datetime import datetime, time
from pathlib import Path
from zoneinfo import ZoneInfo

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

ET = ZoneInfo("America/New_York")

def ts():
    return datetime.now(ET).strftime("[%H:%M:%S ET]")

FORCE_CLOSE_ET = time(15, 51)

now_et = datetime.now(ET).time()
if now_et < FORCE_CLOSE_ET:
    print(f"{ts()} Too early to force-close (before 15:51 ET). Exiting.")
    sys.exit(0)

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))

try:
    ibkr = IBKRClient(host, port, client_id)
except Exception as e:
    print(f"{ts()} Connection failed: {e}")
    sys.exit(1)

try:
    positions = ibkr.ib.positions()
    if not positions:
        print(f"{ts()} No open positions. Nothing to close.")
        sys.exit(0)

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

    for pos in positions:
        symbol = pos.contract.symbol
        qty = int(pos.position)
        if qty <= 0:
            continue

        print(f"{ts()} Closing {qty} shares of {symbol}...")
        try:
            trade = ibkr.place_order(symbol, "SELL", qty)
            status = trade.orderStatus.status
            fill = trade.orderStatus.avgFillPrice or 0
            order_id = trade.order.orderId
            timestamp = datetime.now(ET).isoformat()

            print(f"{ts()} {symbol} SELL {qty} fill={fill} status={status}")

            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"])
                            write_header = False
                        writer.writerow([timestamp, symbol, "SELL", qty, fill, order_id, status])
                    break
                except PermissionError:
                    if attempt == 0:
                        import time as tmod; tmod.sleep(1)
                    else:
                        print(f"{ts()} trades.csv locked — skipping log for {symbol}")

        except Exception as e:
            print(f"{ts()} Failed to close {symbol}: {e}")

finally:
    ibkr.disconnect()

print(f"{ts()} Force-close complete.")
