import sqlite3
import asyncio
from typing import Dict, List

from telethon import TelegramClient, events
from telethon.tl.types import MessageMediaPhoto, MessageMediaDocument
from telethon.errors.rpcerrorlist import FloodWaitError

# Konfigurasi
API_ID = '20948733371'
API_HASH = '5d8e7fd00ca5ab55c3995aa324c3ff1b32'
SESSION_FILE = 'yazheng'

MAIN_DB_PATH = "C:\\Users\\USER\\Documents\\Telegram\\Channel Database\\Database\\全库 Database 002.db"
LAST_MSG_DB_PATH = "C:\\Users\\USER\\Documents\\Telegram\\Channel Database\\Database\\last_message_ids.db"

SOURCE_GROUP_IDS = {-1002084127389: 110394}  # {group_id: start_message_id}
TARGET_GROUP_IDS = [-1002093989662]

# dic = {"media": -1002084127389}

class TelegramForwarder:
    def __init__(self, api_id: int, api_hash: str, session_file: str,
                 main_db_path: str, last_msg_db_path: str):
        
        self.client = TelegramClient(session_file, api_id, api_hash)
        self.main_db_path = main_db_path
        self.last_msg_db_path = last_msg_db_path
        self.initialize_databases()

    def initialize_databases(self) -> None:
        """Inisialisasi koneksi dan tabel database."""
        with sqlite3.connect(self.main_db_path) as conn:
            cursor = conn.cursor()
            cursor.execute("CREATE TABLE IF NOT EXISTS photo (file_id INTEGER PRIMARY KEY)")
            cursor.execute("CREATE TABLE IF NOT EXISTS video (file_id INTEGER PRIMARY KEY)")
            cursor.execute("CREATE TABLE IF NOT EXISTS document (file_id INTEGER PRIMARY KEY)")

        with sqlite3.connect(self.last_msg_db_path) as conn:
            cursor = conn.cursor()
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS group_last_message (
                    group_id INTEGER PRIMARY KEY,
                    last_message_id INTEGER
                )
            ''')

    async def load_last_message_ids(self) -> Dict[int, int]:
        """Muat ID pesan terakhir yang diteruskan dari database."""
        last_message_ids = {}
        with sqlite3.connect(self.last_msg_db_path) as conn:
            cursor = conn.cursor()
            cursor.execute("SELECT group_id, last_message_id FROM group_last_message")
            for row in cursor.fetchall():
                last_message_ids[row[0]] = row[1]
        return last_message_ids

    async def is_file_exists(self, file_id: int, file_type: str) -> bool:
        """Periksa apakah file sudah ada dalam database."""
        table_name = {'photo': 'photo', 'video': 'video', 'document': 'document'}.get(file_type)
        with sqlite3.connect(self.main_db_path) as conn:
            cursor = conn.cursor()
            cursor.execute(f"SELECT 1 FROM {table_name} WHERE file_id = ?", (file_id,))
            return cursor.fetchone() is not None

    async def save_file_id(self, file_id: int, file_type: str) -> None:
        """Simpan ID file ke database."""
        table_name = {'photo': 'photo', 'video': 'video', 'document': 'document'}.get(file_type)
        with sqlite3.connect(self.main_db_path) as conn:
            cursor = conn.cursor()
            cursor.execute(f"INSERT OR IGNORE INTO {table_name} (file_id) VALUES (?)", (file_id,))

    async def forward_messages(self, source_group_id: int, start_message_id: int, target_group_ids: List[int]):
        """Teruskan pesan dari grup sumber ke grup tujuan."""
        last_forwarded_message_id = None
        forwarded_count = 0

        async for message in self.client.iter_messages(source_group_id, min_id=start_message_id, reverse=True):
            if isinstance(message.media, (MessageMediaPhoto, MessageMediaDocument)):
                file_id = message.media.photo.id if isinstance(message.media, MessageMediaPhoto) else message.media.document.id
                file_type = 'photo' if isinstance(message.media, MessageMediaPhoto) else 'video' if message.media.document.mime_type.startswith(
                    'video') else 'document'

                if not await self.is_file_exists(file_id, file_type):
                    try:
                        for target_group_id in target_group_ids:
                            await self.client.send_message(target_group_id, message)
                        await self.save_file_id(file_id, file_type)
                        print(f"Pesan dengan ID {message.id} berhasil di-forward dari grup {source_group_id}.")

                        last_forwarded_message_id = message.id
                        forwarded_count += 1

                        if forwarded_count % 500 == 0:
                            print("Tidur Selamat 5 Menit...")
                            await asyncio.sleep(300)
                        elif forwarded_count % 1000 == 0:
                            print("1000 Pesan telah diproses")
                            TelegramClient.disconnect()
                            return last_forwarded_message_id  # Optional: Stop after 1000 messages
                        else:
                            await asyncio.sleep(7)

                    except FloodWaitError as e:
                        print(
                            f"Terjadi flood wait saat mem-forward pesan dengan ID {message.id} dari grup {source_group_id}: {str(e)}")
                        return last_forwarded_message_id
                    except Exception as e:
                        print(
                            f"Terjadi kesalahan saat mem-forward pesan dengan ID {message.id} dari grup {source_group_id}: {str(e)}")
                else:
                    print(f"Pesan dengan ID {message.id} dari grup {source_group_id} sudah ada dalam database.")
            else:
                print(f"Pesan dengan ID {message.id} dari grup {source_group_id} bukan foto, video, atau file.")
        return last_forwarded_message_id

    async def save_last_message_id(self, group_id: int, last_message_id: int) -> None:
        """Simpan ID pesan terakhir yang diteruskan ke database."""
        with sqlite3.connect(self.last_msg_db_path) as conn:
            cursor = conn.cursor()
            cursor.execute("INSERT OR REPLACE INTO group_last_message (group_id, last_message_id) VALUES (?, ?)",
                           (group_id, last_message_id))

    async def start(self, source_group_ids: Dict[int, int], target_group_ids: List[int]):
        """Mulai proses penerusan pesan."""
        last_message_ids = await self.load_last_message_ids()

        for source_group_id, start_message_id in source_group_ids.items():
            print(f"Memproses pesan dari grup {source_group_id}...")
            last_processed_id = await self.forward_messages(source_group_id, start_message_id, target_group_ids)
            if last_processed_id:
                await self.save_last_message_id(source_group_id, last_processed_id)
                print(f"ID pesan terakhir yang berhasil di-forward dari grup {source_group_id}: {last_processed_id}")

async def main():
    """Fungsi utama untuk menjalankan bot."""
    forwarder = TelegramForwarder(API_ID, API_HASH, SESSION_FILE, MAIN_DB_PATH, LAST_MSG_DB_PATH)
    await forwarder.client.start()
    print("Userbot sedang berjalan...")
    await forwarder.start(SOURCE_GROUP_IDS, TARGET_GROUP_IDS)

if __name__ == "__main__":
    asyncio.run(main())



Tolong jelaskan codingan ini dan codingkan kembali