import asyncio
import os
import sys
import json
import re
from telethon import TelegramClient, events
from telethon.sessions import StringSession

sys.stdout.reconfigure(line_buffering=True)

API_ID = int(os.environ.get("API_ID", "0"))
API_HASH = os.environ.get("API_HASH")
SESSION_STRING = os.environ.get("TG_SESSION_STRING")
SOURCES = [s.strip() for s in os.environ.get("SOURCES", "").split(",") if s.strip()]
DESTINATION = os.environ.get("DESTINATION")
POLL_INTERVAL = int(os.environ.get("POLL_INTERVAL", "60"))
HISTORY_LIMIT = int(os.environ.get("HISTORY_LIMIT", "0"))

if not all([API_ID, API_HASH, SESSION_STRING, SOURCES, DESTINATION]):
    print("缺少必要的环境变量")
    sys.exit(1)

last_ids_file = "last_ids.json"
polling_sources = []

async def load_last_ids():
    try:
        with open(last_ids_file, "r") as f:
            return json.load(f)
    except:
        return {}

async def save_last_ids(last_ids):
    with open(last_ids_file, "w") as f:
        json.dump(last_ids, f)

async def forward_messages(client, source_entity, dest_entity, messages):
    for msg in messages:
        try:
            await client.forward_messages(dest_entity, msg)
            print(f"已转发消息 {msg.id} 从 {source_entity.username or source_entity.id}")
            await asyncio.sleep(0.5)
        except Exception as e:
            print(f"转发失败 {msg.id}: {e}")

async def forward_history(client, source_entity, dest_entity, limit):
    print(f"正在获取 {source_entity.username or source_entity.id} 的历史消息（最多 {limit} 条）...")
    messages = []
    async for msg in client.iter_messages(source_entity, limit=limit, reverse=True):
        messages.append(msg)
    if not messages:
        print(f"源 {source_entity.username or source_entity.id} 没有历史消息")
        return None
    await forward_messages(client, source_entity, dest_entity, messages)
    return messages[-1].id

async def forward_new_messages(client, source_entity, dest_entity, last_id):
    try:
        async for msg in client.iter_messages(source_entity, limit=1):
            latest_msg = msg
            break
        else:
            return last_id
        if latest_msg.id > last_id:
            new_messages = []
            async for msg in client.iter_messages(source_entity, min_id=last_id, max_id=latest_msg.id, reverse=True):
                new_messages.append(msg)
            await forward_messages(client, source_entity, dest_entity, new_messages)
            return latest_msg.id
        else:
            return last_id
    except Exception as e:
        print(f"检查源 {source_entity.username or source_entity.id} 时出错: {e}")
        return last_id

async def get_recent_verification_messages(client, count=5):
    print(f"正在获取来自官方通知用户的最近 {count} 条消息...")
    messages = []
    async for msg in client.iter_messages(777000, limit=count, reverse=False):
        messages.append(msg)
    for i, msg in enumerate(reversed(messages), 1):
        text = msg.text
        print(f"--- 第 {i} 条（{msg.date}）---")
        print(f"消息内容: {text}")
        match = re.search(r"\b(\d{5,6})\b", text)
        if match:
            print(f"验证码: {match.group(1)}")
        else:
            print("未找到验证码")
    if not messages:
        print("未找到来自官方通知用户的消息")

async def main():
    print("等待 60 秒，确保旧容器已退出...")
    await asyncio.sleep(60)

    client = TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH)
    await client.start()
    print("连接成功")

    await get_recent_verification_messages(client, count=5)

    @client.on(events.NewMessage(from_users=777000))
    async def verification_handler(event):
        text = event.message.text
        print(f"收到新官方通知（实时）")
        print(f"消息内容: {text}")
        match = re.search(r"\b(\d{5,6})\b", text)
        if match:
            print(f"验证码: {match.group(1)}")
        else:
            print("未找到验证码")

    source_entities = []
    for src in SOURCES:
        try:
            entity = await client.get_entity(src)
            source_entities.append(entity)
            print(f"已加载源: {src}")
        except Exception as e:
            print(f"无法加载源 {src}: {e}")

    if not source_entities:
        print("没有可用的源频道，退出")
        return

    dest_entity = await client.get_entity(DESTINATION)
    print(f"目标频道: {DESTINATION}")

    last_ids = await load_last_ids()

    if HISTORY_LIMIT > 0:
        print(f"开始转发历史消息（每个源最多 {HISTORY_LIMIT} 条）...")
        for entity in source_entities:
            key = str(entity.id)
            new_last_id = await forward_history(client, entity, dest_entity, HISTORY_LIMIT)
            if new_last_id is not None:
                last_ids[key] = new_last_id
                await save_last_ids(last_ids)
        print("历史消息转发完成")

    for entity in source_entities:
        try:
            async for _ in client.iter_messages(entity, limit=1):
                pass
            @client.on(events.NewMessage(chats=entity))
            async def handler(event, dest=dest_entity, src_entity=entity):
                try:
                    await client.forward_messages(dest, event.message)
                    print(f"实时转发消息 {event.message.id} 从 {src_entity.username or src_entity.id}")
                except Exception as e:
                    print(f"实时转发失败: {e}")
            print(f"已为 {entity.username or entity.id} 启用实时监听（已加入频道）")
        except Exception as e:
            print(f"无法为 {entity.username or entity.id} 启用实时监听，将使用轮询: {e}")
            polling_sources.append(entity)

    for entity in polling_sources:
        key = str(entity.id)
        if key not in last_ids:
            async for msg in client.iter_messages(entity, limit=1):
                last_ids[key] = msg.id
                break
            else:
                last_ids[key] = 0
    await save_last_ids(last_ids)

    async def poll_loop():
        while True:
            for entity in polling_sources:
                key = str(entity.id)
                last_id = last_ids.get(key, 0)
                new_last_id = await forward_new_messages(client, entity, dest_entity, last_id)
                if new_last_id != last_id:
                    last_ids[key] = new_last_id
                    await save_last_ids(last_ids)
            await asyncio.sleep(POLL_INTERVAL)

    if polling_sources:
        asyncio.create_task(poll_loop())
        print(f"轮询任务已启动，间隔 {POLL_INTERVAL} 秒，监控 {len(polling_sources)} 个未加入的频道")

    print("监听已启动...")
    await client.run_until_disconnected()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("停止")
    except Exception as e:
        print(f"主程序异常: {e}")
        import traceback
        traceback.print_exc()

