#!/usr/bin/env python3
"""SEEDS Bot Control Server v5 — Linux/DigitalOcean version"""
import subprocess, json, os, sys
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs

BOT_DIR = '/root/seeds'
CTRL_FILE = os.path.join(BOT_DIR, 'bot_control.json')
SUPERVISORCTL = '/usr/local/bin/supervisorctl'
SUPERVISOR_CONF = '/etc/supervisord.conf'

PAIR_MAP = {
    'XETH':'XETHZUSD','XXRP':'XXRPZUSD','XXBT':'XXBTZUSD',
    'XLTC':'XLTCZUSD','XXLM':'XXLMZUSD','SOL':'SOLUSD',
    'ADA':'ADAUSD','DOT':'DOTUSD','LINK':'LINKUSD','AVAX':'AVAXUSD',
    'TRX':'TRXUSD','POL':'POLUSD','KAVA':'KAVAUSD','FIL':'FILUSD',
    'XDGE':'XDGUSD',
}
DISPLAY = {
    'XETH':'ETH','XXRP':'XRP','XXBT':'BTC','XLTC':'LTC',
    'XXLM':'XLM','XDGE':'DOGE','SOL':'SOL','ADA':'ADA',
    'DOT':'DOT','LINK':'LINK','AVAX':'AVAX','TRX':'TRX',
    'POL':'POL','KAVA':'KAVA','FIL':'FIL',
}

def supervisor_cmd(action, program):
    try:
        r = subprocess.run(
            [SUPERVISORCTL, '-c', SUPERVISOR_CONF, action, program],
            capture_output=True, text=True
        )
        return r.stdout.strip()
    except Exception as e:
        return str(e)

def is_running(program):
    try:
        r = subprocess.run(
            [SUPERVISORCTL, '-c', SUPERVISOR_CONF, 'status', program],
            capture_output=True, text=True
        )
        return 'RUNNING' in r.stdout
    except:
        return False

def start_bot(bot):
    program = 'rsi_bot' if bot == 'rsi' else 'master_bot'
    if is_running(program):
        return {'ok': True, 'msg': f'{bot} already running'}
    result = supervisor_cmd('start', program)
    return {'ok': True, 'msg': result}

def stop_bot(bot):
    program = 'rsi_bot' if bot == 'rsi' else 'master_bot'
    result = supervisor_cmd('stop', program)
    return {'ok': True, 'msg': result}

def write_control(flags):
    try:
        existing = {}
        if os.path.exists(CTRL_FILE):
            with open(CTRL_FILE) as f:
                existing = json.load(f)
        existing.update(flags)
        with open(CTRL_FILE, 'w') as f:
            json.dump(existing, f, indent=2)
        return {'ok': True}
    except Exception as e:
        return {'ok': False, 'msg': str(e)}

def get_balance():
    try:
        sys.path.insert(0, BOT_DIR)
        import krakenex
        from config_advanced import API_KEY, API_SECRET
        api = krakenex.API(key=API_KEY, secret=API_SECRET)
        resp = api.query_private('Balance')
        if resp.get('error'):
            return {'ok': False, 'msg': str(resp['error'])}
        bal = resp['result']
        usd = float(bal.get('ZUSD', bal.get('USD', 0)))
        skip = {'ZUSD','USD','USDT','USDC','KFEE'}
        holdings = {k:v for k,v in bal.items() if k not in skip and float(v)>0.0001}
        pairs_needed = [PAIR_MAP[r] for r in holdings if r in PAIR_MAP]
        prices = {}
        if pairs_needed:
            pr = api.query_public('Ticker', {'pair': ','.join(pairs_needed)})
            if not pr.get('error'):
                for pair_result, data in pr['result'].items():
                    price = float(data['c'][0])
                    for raw, pair in PAIR_MAP.items():
                        if pair_result == pair:
                            display = DISPLAY.get(raw, raw)
                            prices[raw] = price
                            prices[display] = price
        return {'ok': True, 'usd': round(usd,2), 'holdings': holdings, 'prices': prices}
    except Exception as e:
        return {'ok': False, 'msg': str(e), 'usd': 0, 'holdings': {}, 'prices': {}}

class Handler(BaseHTTPRequestHandler):
    def log_message(self, *a): pass
    def cors(self):
        self.send_header('Access-Control-Allow-Origin','*')
        self.send_header('Access-Control-Allow-Methods','GET,OPTIONS')
        self.send_header('Access-Control-Allow-Headers','Content-Type')
    def do_OPTIONS(self):
        self.send_response(200); self.cors(); self.end_headers()
    def send_json(self, d, s=200):
        b = json.dumps(d).encode()
        self.send_response(s)
        self.send_header('Content-Type','application/json')
        self.cors()
        self.send_header('Content-Length', len(b))
        self.end_headers()
        self.wfile.write(b)
    def do_GET(self):
        p = urlparse(self.path)
        qs = parse_qs(p.query)
        bot = qs.get('bot',[''])[0]
        if   p.path=='/ping':    self.send_json({'ok':True,'version':'v5'})
        elif p.path=='/status':  self.send_json({'rsi':is_running('rsi_bot'),'master':is_running('master_bot')})
        elif p.path=='/start':   self.send_json(start_bot(bot))
        elif p.path=='/stop':    self.send_json(stop_bot(bot))
        elif p.path=='/balance': self.send_json(get_balance())
        elif p.path=='/flags':
            try:
                d = json.load(open(CTRL_FILE)) if os.path.exists(CTRL_FILE) else {}
                self.send_json({'ok':True,**d})
            except: self.send_json({'ok':False})
        elif p.path=='/control':
            raw = qs.get('flags',['{}'])[0]
            try: flags = json.loads(raw)
            except: flags = {}
            self.send_json(write_control(flags))
        else: self.send_json({'ok':False,'msg':'Unknown'},404)

if __name__=='__main__':
    s = HTTPServer(('0.0.0.0', 8766), Handler)
    print('SEEDS Control Server v5 on port 8766')
    try: s.serve_forever()
    except KeyboardInterrupt: pass
