import time, os, requests, json, urllib3
from datetime import datetime, timedelta, timezone, time as dtime
from dotenv import load_dotenv

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
load_dotenv("tok.env")

TOKEN = os.getenv("TINKOFF_TOKEN")
TG_TOKEN = os.getenv("TG_TOKEN")
TG_CHAT_ID = os.getenv("TG_CHAT_ID")
ACC_ID = os.getenv("ACCOUNT_ID")

INSTRUMENT_UID = "a78b8349-a1dc-447d-9277-1d75826d089a" 
BASE_URL = "https://invest-public-api.tbank.ru/rest"
STATE_FILE = "bot_state_prod.json"

s = requests.Session()
s.headers.update({"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"})

def get_price():
    path = f"{BASE_URL}/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices"
    try:
        r = s.post(path, json={"instrumentId": [INSTRUMENT_UID]}, timeout=5)
        if r.status_code != 200: return None
        res = r.json()
        if 'lastPrices' in res and res['lastPrices']:
            p = res['lastPrices'][0]['price']
            return int(p.get('units', 0)) + int(p.get('nano', 0)) / 1e9
    except: return None
    return None

def get_atr_steps():
    path = f"{BASE_URL}/tinkoff.public.invest.api.contract.v1.MarketDataService/GetCandles"
    try:
        now_utc = datetime.now(timezone.utc)
        payload = {
            "instrumentId": INSTRUMENT_UID,
            "from": (now_utc - timedelta(days=2)).strftime('%Y-%m-%dT%H:%M:%SZ'),
            "to": now_utc.strftime('%Y-%m-%dT%H:%M:%SZ'),
            "interval": "CANDLE_INTERVAL_HOUR"
        }
        r = s.post(path, json=payload, timeout=10)
        candles = r.json().get('candles', [])
        if len(candles) < 2: return 1.1, 1.5
        
        def to_f(p): return int(p.get('units', 0)) + int(p.get('nano', 0)) / 1e9
        trs = [to_f(c['high']) - to_f(c['low']) for c in candles[-14:]]
        atr = sum(trs) / len(trs)
        
        buy_step = max(round(atr * 0.45, 2), 0.5)
        return buy_step, round(buy_step * 1.2, 2)
    except: return 1.1, 1.5

def post_order(direction):
    path = f"{BASE_URL}/tinkoff.public.invest.api.contract.v1.OrdersService/PostOrder"
    payload = {
        "instrumentId": INSTRUMENT_UID, "quantity": 1, 
        "direction": direction, "orderType": "ORDER_TYPE_MARKET", 
        "accountId": ACC_ID, "orderId": f"p_{int(time.time())}"
    }
    try:
        r = s.post(path, json=payload, timeout=10)
        return r.status_code == 200
    except: return False

def run():
    print("🚀 БОТ ЗАПУЩЕН")
    state = {"phase": "BUY", "base_price": None}
    if os.path.exists(STATE_FILE):
        try:
            with open(STATE_FILE, 'r') as f: state = json.load(f)
        except: pass

    buy_step, profit_step = get_atr_steps()
    
    while True:
        price = get_price()
        if price:
            if state['base_price'] is None:
                state['base_price'] = price
                with open(STATE_FILE, 'w') as f: json.dump(state, f)
                print(f"\n🎯 База установлена: {price}")

            if state['phase'] == "BUY":
                target = round(state['base_price'] - buy_step, 2)
            else:
                target = round(state['base_price'] + profit_step, 2)
            
            print(f"[{datetime.now().strftime('%H:%M:%S')}] Цена: {price:.2f} | Цель: {target:.2f} | {state['phase']}   ", end='\r')
            
            if state['phase'] == "BUY" and price <= target:
                if post_order("ORDER_DIRECTION_BUY"):
                    state.update({"phase": "SELL", "base_price": price})
                    with open(STATE_FILE, 'w') as f: json.dump(state, f)
                    print(f"\n🛒 КУПЛЕНО по {price}")

            elif state['phase'] == "SELL" and price >= target:
                if post_order("ORDER_DIRECTION_SELL"):
                    state.update({"phase": "BUY", "base_price": price})
                    with open(STATE_FILE, 'w') as f: json.dump(state, f)
                    print(f"\n💰 ПРОДАНО по {price}")
        
        time.sleep(1)

if __name__ == "__main__":
    run()
