#!/usr/bin/env python3
"""
Telegram Crypto Signal Parser
Parses exported Telegram JSON chat history and extracts structured trading signals.
"""

import json
import re
import sys
from datetime import datetime
from pathlib import Path

# Signal patterns - adapt as we see more formats
PATTERNS = {
    # #TICKER direction entry SL target leverage balance%
    'standard': re.compile(
        r'#(\w+)\s+'                           # ticker
        r'(Long|Short)\s+'                      # direction
        r'(?:market\s+entry!?|entry[:\s]+([0-9.]+))\s*'  # entry type/price
        r'SL[;:\s]+([0-9.]+)\s*'               # stop loss
        r'(?:Targets?|TP)[;:\s]+([0-9.,\s]+)\s*'  # targets (can be multiple)
        r'(?:Lev(?:erage)?[:\s]*x?([0-9.]+))?\s*'  # leverage (optional)
        r'(?:([0-9.]+)%?\s*balance)?',          # balance % (optional)
        re.IGNORECASE
    ),
    # Simpler: #TICKER Short/Long entry SL targets
    'simple': re.compile(
        r'#(\w+)\s+(Long|Short)',
        re.IGNORECASE
    ),
}


def parse_signal_text(text):
    """Parse a single message text into structured signal(s)."""
    signals = []
    
    # Try to find all ticker mentions
    ticker_blocks = re.split(r'(?=#\w+USDT)', text)
    
    for block in ticker_blocks:
        if not block.strip():
            continue
            
        signal = {}
        
        # Extract ticker
        ticker_match = re.search(r'#(\w+)', block)
        if not ticker_match:
            continue
        signal['ticker'] = ticker_match.group(1).upper()
        
        # Extract direction
        dir_match = re.search(r'\b(Long|Short)\b', block, re.IGNORECASE)
        if not dir_match:
            continue
        signal['direction'] = dir_match.group(1).lower()
        
        # Extract entry price (or "market")
        entry_match = re.search(r'(?:entry|enter)[:\s]*([0-9.]+)', block, re.IGNORECASE)
        if entry_match:
            signal['entry'] = float(entry_match.group(1))
        else:
            signal['entry'] = 'market'
        
        # Extract stop loss
        sl_match = re.search(r'SL[;:\s]+([0-9.]+)', block, re.IGNORECASE)
        if sl_match:
            signal['stop_loss'] = float(sl_match.group(1))
        
        # Extract targets (can be multiple, comma or space separated)
        tp_match = re.search(r'(?:Targets?|TP)[;:\s]+([0-9.,\s]+)', block, re.IGNORECASE)
        if tp_match:
            targets_str = tp_match.group(1)
            targets = [float(t.strip()) for t in re.findall(r'[0-9.]+', targets_str)]
            signal['targets'] = targets
        
        # Extract leverage
        lev_match = re.search(r'Lev(?:erage)?[:\s]*x?([0-9.]+)', block, re.IGNORECASE)
        if lev_match:
            signal['leverage'] = float(lev_match.group(1))
        
        # Extract balance percentage
        bal_match = re.search(r'([0-9.]+)%?\s*balance', block, re.IGNORECASE)
        if bal_match:
            signal['balance_pct'] = float(bal_match.group(1))
        
        if signal.get('ticker') and signal.get('direction'):
            signals.append(signal)
    
    return signals


def parse_telegram_export(json_path):
    """Parse a Telegram JSON export file."""
    with open(json_path, 'r') as f:
        data = json.load(f)
    
    messages = data.get('messages', [])
    all_signals = []
    
    for msg in messages:
        if msg.get('type') != 'message':
            continue
        
        # Get text content (can be string or list of text entities)
        text_parts = msg.get('text', '')
        if isinstance(text_parts, list):
            text = ''.join(
                p if isinstance(p, str) else p.get('text', '')
                for p in text_parts
            )
        else:
            text = text_parts
        
        if not text or '#' not in text:
            continue
        
        # Check if it looks like a signal
        if not re.search(r'(Long|Short)', text, re.IGNORECASE):
            continue
        
        signals = parse_signal_text(text)
        
        for signal in signals:
            signal['timestamp'] = msg.get('date', '')
            signal['message_id'] = msg.get('id', '')
            signal['raw_text'] = text[:500]
            all_signals.append(signal)
    
    return all_signals


def parse_forwarded_messages(messages_text):
    """Parse signals from forwarded message text (copy-pasted or forwarded to bot)."""
    signals = parse_signal_text(messages_text)
    return signals


if __name__ == '__main__':
    if len(sys.argv) < 2:
        # Demo with the test signals
        test_text = """#ASTERUSDT Short market entry! SL: 0.6385 Targets: 0.51 Lev x15 1.3% balance
#HYPEUSDT Short market entry! SL; 33.5 Target 25 Lev x12 1.4% balance"""
        
        signals = parse_signal_text(test_text)
        print(f"Parsed {len(signals)} signals:\n")
        for s in signals:
            print(json.dumps(s, indent=2))
    else:
        json_path = sys.argv[1]
        signals = parse_telegram_export(json_path)
        print(f"Parsed {len(signals)} signals from export\n")
        
        # Save to output
        out_path = json_path.replace('.json', '_signals.json')
        with open(out_path, 'w') as f:
            json.dump(signals, f, indent=2)
        print(f"Saved to {out_path}")
        
        # Quick summary
        longs = sum(1 for s in signals if s['direction'] == 'long')
        shorts = sum(1 for s in signals if s['direction'] == 'short')
        print(f"Longs: {longs}, Shorts: {shorts}")
        tickers = set(s['ticker'] for s in signals)
        print(f"Unique tickers: {len(tickers)}")
