#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
RSI Monitor Push Script
Monitors RSI indicator for long/short signals
Developer: TradingIndicators.pro
Support: support@tradingindicators.pro
"""

# === Version ===
VERSION = "1.0"

import os
import time
import datetime
import re
import traceback
import json

# Try to use requests, fallback to urllib
try:
    import requests
    USE_REQUESTS = True
except ImportError:
    import urllib.request
    USE_REQUESTS = False

# === Configuration ===
# NOTE: Users must replace this WEBHOOK URL with their own WeChat Work webhook URL
# To get your webhook: Open WeChat Work -> Go to your group -> Settings -> Group Robot -> Add Robot -> Copy Webhook URL
WEBHOOK = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_WEBHOOK_KEY_HERE"
MARKER = "[Pushed]"

# === File Path Configuration ===
# NOTE: The monitor script should be placed in or point to the MQL5\Files folder
# because RSI indicator writes alert files there
# Default: Current directory (place this script in MQL5\Files folder)
ALERT_FILE_PATH = "."  # Use "." for current directory or specify full path like "C:\\Users\\YourUsername\\AppData\\Roaming\\MetaQuotes\\Terminal\\XXX\\MQL5\\Files"

# Global state
file_status = {}
last_push_time = 0          # Last push time for business messages

# Separate push time tracking for long/short signals
last_long_time = 0          # Last long signal push time
last_short_time = 0         # Last short signal push time
MIN_MESSAGE_INTERVAL = 30 * 60  # Minimum interval between same type messages (seconds), 30 minutes

# Track latest RSI signal state
latest_rsi_signal = "unknown"  # "long", "short", "unknown"

# Track latest RSI snapshot values
latest_rsi_value = "N/A"
latest_threshold = "N/A"
latest_rsi_numeric = None  # Store numeric RSI value for comparison
latest_oversold_level = 30.0  # Default oversold level
latest_overbought_level = 70.0  # Default overbought level


def get_today_file():
    today = datetime.datetime.now().strftime('%Y.%m.%d')
    return os.path.join(ALERT_FILE_PATH, f"RSI_Alert_{today}.txt")


def send_wecom(content):
    data = {"msgtype": "text", "text": {"content": content}}
    try:
        if USE_REQUESTS:
            resp = requests.post(WEBHOOK, json=data, timeout=5)
            return resp.status_code == 200
        else:
            req = urllib.request.Request(
                WEBHOOK,
                data=json.dumps(data).encode('utf-8'),
                headers={'Content-Type': 'application/json'}
            )
            with urllib.request.urlopen(req, timeout=5) as r:
                return True
    except Exception as e:
        print(f"[WeCom] ❌ Send failed: {repr(e)}")
        return False


def format_rsi_message(segment):
    lines = segment.strip().split('\n')
    formatted_lines = []
    formatted_lines.append("📊 RSI Monitor Alert")
    formatted_lines.append("=" * 30)

    for line in lines:
        line = line.strip()
        if not line or "Server Time" in line or "Local Time" in line:
            continue

        if "Symbol" in line:
            formatted_lines.append(f"💱 {line}")
        elif "RSI" in line:
            formatted_lines.append(f"📈 {line}")
        elif "Threshold" in line:
            formatted_lines.append(f"🎯 {line}")
        elif "Time" in line:
            formatted_lines.append(f"⏰ {line}")
        elif "Period" in line:
            formatted_lines.append(f"📋 {line}")
        elif "Signal" in line:
            formatted_lines.append(f"📋 {line}")
        elif "Price" in line:
            formatted_lines.append(f"💰 {line}")
        elif "[RSI Buy Signal]" in line:
            formatted_lines.append(f"📈 {line}")
        elif "[RSI Sell Signal]" in line:
            formatted_lines.append(f"📉 {line}")
        elif "[RSI" in line and "Initialization" in line:
            formatted_lines.append(f"📋 {line}")
        else:
            formatted_lines.append(f"   {line}")

    formatted_lines.append("=" * 30)
    formatted_lines.append(f"Sent at: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    return "\n".join(formatted_lines)


def process_file(filename):
    global file_status, last_push_time, last_long_time, last_short_time, latest_rsi_signal, latest_rsi_value, latest_threshold, latest_rsi_numeric

    if filename not in file_status:
        if not os.path.exists(filename):
            return False
        mtime = os.path.getmtime(filename)
        size = os.path.getsize(filename)
        file_status[filename] = {'last_mtime': mtime, 'last_size': size}
        return False

    if not os.path.exists(filename):
        return False

    has_new_message = False
    try:
        mtime = os.path.getmtime(filename)
        size = os.path.getsize(filename)

        if mtime == file_status[filename]['last_mtime'] and size == file_status[filename]['last_size']:
            return False
        if size == 0:
            file_status[filename]['last_mtime'], file_status[filename]['last_size'] = mtime, size
            return False

        with open(filename, 'r', encoding='gbk', errors='replace') as f:
            content = f.read()

        segments = re.split(r'\n*--- New Message ---\n*', content)
        updated = False

        for i in range(len(segments)-1, -1, -1):
            seg = segments[i].strip()
            if seg and MARKER not in seg:
                print(f"[Message] Processing: {seg[:60]}...")

                current_message_type = ""
                if "[RSI Buy Signal]" in seg:
                    current_message_type = "RSI Buy Signal"
                    latest_rsi_signal = "long"
                elif "[RSI Sell Signal]" in seg:
                    current_message_type = "RSI Sell Signal"
                    latest_rsi_signal = "short"
                elif "Initialization" in seg and "[RSI" in seg:
                    current_message_type = "RSI Initialization"
                elif "[RSI Scheduled Snapshot]" in seg:
                    current_message_type = "RSI Scheduled Snapshot"
                else:
                    current_message_type = "Other"
                
                # Extract RSI value and threshold information
                rsi_value_found = False
                for line in seg.split('\n'):
                    line = line.strip()
                    if "RSI Value" in line:
                        latest_rsi_value = line
                        match = re.search(r'RSI Value[：:\s]*([\d.]+)', line)
                        if match:
                            try:
                                latest_rsi_numeric = float(match.group(1))
                                rsi_value_found = True
                            except ValueError:
                                pass
                    elif "Oversold Level" in line:
                        latest_threshold = line
                        match = re.search(r'Oversold Level[：:\s]*([\d.]+)', line)
                        if match:
                            try:
                                latest_oversold_level = float(match.group(1))
                                print(f"[Threshold] Extracted oversold level: {latest_oversold_level}")
                            except ValueError:
                                pass
                    elif "Overbought Level" in line:
                        latest_threshold = line
                        match = re.search(r'Overbought Level[：:\s]*([\d.]+)', line)
                        if match:
                            try:
                                latest_overbought_level = float(match.group(1))
                                print(f"[Threshold] Extracted overbought level: {latest_overbought_level}")
                            except ValueError:
                                pass
                    elif "Threshold" in line:
                        latest_threshold = line
                
                if rsi_value_found:
                    print(f"[RSI Extraction] Extracted RSI value: {latest_rsi_numeric}")

                current_time = time.time()
                
                # Check if should skip based on message type (long/short independent)
                should_skip = False
                if current_message_type == "RSI Buy Signal":
                    if current_time - last_long_time < MIN_MESSAGE_INTERVAL:
                        print(f"[Message] Skip push: Buy signal sent within last {MIN_MESSAGE_INTERVAL//60} minutes")
                        should_skip = True
                elif current_message_type == "RSI Sell Signal":
                    if current_time - last_short_time < MIN_MESSAGE_INTERVAL:
                        print(f"[Message] Skip push: Sell signal sent within last {MIN_MESSAGE_INTERVAL//60} minutes")
                        should_skip = True
                elif current_message_type == "RSI Scheduled Snapshot":
                    # Scheduled snapshots are not pushed, only extract RSI info for heartbeat
                    print(f"[Message] Scheduled snapshot not pushed, extracting RSI info")
                    segments[i] = seg + f"\n{MARKER}"
                    updated = True
                    if rsi_value_found:
                        print(f"[RSI Extraction] Extracted RSI from snapshot: {latest_rsi_numeric}")
                        # Update signal state based on RSI value
                        if latest_rsi_numeric <= latest_oversold_level:
                            latest_rsi_signal = "long"
                        elif latest_rsi_numeric >= latest_overbought_level:
                            latest_rsi_signal = "short"
                    continue
                elif current_message_type == "RSI Initialization":
                    # Initialization message only pushed once
                    should_skip = True
                    print(f"[Message] Skip push: Initialization message only pushed once")
                
                if should_skip:
                    segments[i] = seg + f"\n{MARKER}"
                    updated = True
                    continue

                formatted_content = format_rsi_message(seg)
                wx_ok = send_wecom(formatted_content)
                time.sleep(0.5)

                segments[i] = seg + f"\n{MARKER}"
                updated = True
                has_new_message = True
                last_push_time = time.time()      # Only update for business messages
                
                # Track long/short push times separately
                if current_message_type == "RSI Buy Signal":
                    last_long_time = current_time
                elif current_message_type == "RSI Sell Signal":
                    last_short_time = current_time
                
                continue

        if updated:
            with open(filename, 'w', encoding='gbk', errors='replace') as f:
                f.write('\n--- New Message ---\n'.join(segments))
            print(f"[File] {os.path.basename(filename)} updated with markers")

        file_status[filename]['last_mtime'] = os.path.getmtime(filename)
        file_status[filename]['last_size'] = os.path.getsize(filename)

    except Exception as e:
        print(f"[Main Process] ❌ {os.path.basename(filename)} error: {repr(e)}")
        print(traceback.format_exc())

    return has_new_message


def is_weekend():
    """Check if it's weekend (Saturday or Sunday). Saturday before 5 AM considered Friday trading time"""
    now = datetime.datetime.now()
    weekday = now.weekday()
    
    # Sunday - no sending
    if weekday == 6:
        return True
    
    # Saturday - before 5 AM is still Friday trading time
    if weekday == 5:
        if now.hour < 5:
            return False
        else:
            return True
    
    # Monday-Friday - normal sending
    return False


def main():
    global last_push_time, latest_rsi_signal

    # Startup notification
    start_msg = f"""🚀 RSI Pro Alert Monitor Service Started
{"=" * 30}
📊 Version: v{VERSION}
🕒 Start Time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
📅 Monitoring Date: {datetime.datetime.now().strftime('%Y-%m-%d')}
{"=" * 30}
💡 System ready, monitoring RSI signals..."""
    print("[Startup] Sending initialization notification...")
    send_wecom(start_msg)
    last_push_time = time.time()
    time.sleep(1)

    while True:
        now = datetime.datetime.now()
        
        if is_weekend():
            weekday_name = "Saturday" if now.weekday() == 5 else "Sunday"
            print(f"[INFO] Today is {weekday_name}, no messages will be sent. Waiting for next check cycle...")
            time.sleep(60)
            continue

        has_new_message = False
        import glob
        file_pattern = "RSI_Alert_*.txt"
        files = glob.glob(file_pattern)
        today_file = get_today_file()
        if today_file in files:
            has_new_message = process_file(today_file)

        print(f"[DEBUG] {now.strftime('%H:%M:%S')} | Signal Status: {latest_rsi_signal}")

        time.sleep(60)


if __name__ == "__main__":
    main()
