from telethon.sync import TelegramClient
from telethon.tl.types import MessageEntityCustomEmoji, InputPrivacyValueAllowAll
import pymysql
import logging
import asyncio
import os
from datetime import datetime, timedelta
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from telethon.tl.functions.account import UpdateNotifySettingsRequest
from telethon.tl.types import InputPeerNotifySettings

# تنظیمات لاگینگ
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

# اطلاعات تلگرام
api_id = 29007504  # ID خود را وارد کنید
api_hash = "877e958822f299acd9d72729b9507cd2"  # API Hash خود را وارد کنید
session_name = "my_session"  # نام سشن تلگرام

# اطلاعات دیتابیس MySQL
db_config = {
    "host": "hz.esf.li",      # آدرس سرور MySQL
    "user": "root",           # نام کاربری
    "password": "20222022",   # رمز عبور
    "database": "car",        # نام دیتابیس
}

# ID کانال تلگرام که پیام باید به آن ارسال شود
channel_id = "oto_dianat"  # مثلا: "@mychannel" یا عددی مانند -1001234567890


def get_text_from_db(start_time, end_time):
    conn = None
    try:
        conn = pymysql.connect(**db_config)
        cursor = conn.cursor()

        query = """
            SELECT * FROM (
                SELECT 
                    ci.car_id, 
                    ci.user_id,  
                    b.brand_id,  
                    b.name AS brand_name,  
                    cm.model_id, 
                    cm.name AS model_name, 
                    cc.color_id, 
                    cc.name AS color_name, 
                    cy.year_id,  
                    cy.name AS year,
                    ci.price AS formatted_price, 
                    DATE(ci.created_at) AS created_date,
                    ci.created_at,
                    ci.description, 
                    ci.exchange_available, 
                    ci.exchange_details,  
                    CONCAT(u.first_name, ' ', u.last_name) AS registered_by,  
                    IFNULL(ci.has_warranty, FALSE) AS has_warranty,  
                    IFNULL(ci.warranty_period, 0) AS warranty_period, 
                    IFNULL(ci.has_insurance, FALSE) AS has_insurance, 
                    IFNULL(ci.insurance_period, 0) AS insurance_period, 
                    ci.price / 1000000 AS price_in_million,  
                    ci.mileage AS kilometer, 
                    'sell' AS type
                FROM car_sell ci 
                JOIN Users u ON ci.user_id = u.user_id  
                JOIN car_model cm ON ci.model_id = cm.model_id  
                JOIN Brands b ON cm.brand_id = b.brand_id  
                JOIN car_color cc ON ci.color_id = cc.color_id  
                JOIN car_years cy ON ci.year = cy.year_id
                WHERE ci.created_at BETWEEN %s AND %s
                UNION ALL  
                SELECT 
                    ci.car_id, 
                    ci.user_id,  
                    b.brand_id,  
                    b.name AS brand_name,  
                    cm.model_id, 
                    cm.name AS model_name, 
                    cc.color_id, 
                    cc.name AS color_name, 
                    cy.year_id,  
                    cy.name AS year,
                    ci.price AS formatted_price, 
                    DATE(ci.created_at) AS created_date, 
                    ci.created_at, 
                    ci.description, 
                    NULL AS exchange_available, 
                    NULL AS exchange_details, 
                    CONCAT(u.first_name, ' ', u.last_name) AS registered_by,  
                    NULL AS has_warranty,
                    NULL AS warranty_period,
                    NULL AS has_insurance, 
                    NULL AS insurance_period, 
                    ci.price / 1000000 AS price_in_million,  
                    ci.mileage AS kilometer, 
                    'buy' AS type
                FROM car_buy ci 
                JOIN Users u ON ci.user_id = u.user_id  
                JOIN car_model cm ON ci.model_id = cm.model_id  
                JOIN Brands b ON cm.brand_id = b.brand_id  
                JOIN car_color cc ON ci.color_id = cc.color_id  
                JOIN car_years cy ON ci.year = cy.year_id
                WHERE ci.created_at BETWEEN %s AND %s
            ) AS filtered_table
            ORDER BY created_at DESC
        """
        cursor.execute(query, (start_time, end_time, start_time, end_time))
        results = cursor.fetchall()

        messages = []
        for result in results:
            # ساخت پیام با فرمت دلخواه
            brand_name = result[3]  # برند
            model_name = result[5]  # مدل 
            color_name = result[7]  # رنگ
            year = result[9]  # سال
            price = result[10]  # قیمت
            description = result[13]  # توضیحات
            has_warranty = result[17]  # گارانتی دارد
            warranty_period = result[18]  # مدت گارانتی
            has_insurance = result[19]  # بیمه دارد
            insurance_period = result[20]  # مدت بیمه
            mileage = result[22]  # کارکرد
            whatsapp_link = "https://whatsapp.com/channel/0029VaqXcxrHQbS72MxLCr0v"  # لینک واتساپ
            telegram_link = "https://t.me/oto_dianat"  # لینک تلگرام
            phone_number = "09371408833"  # شماره تماس
            formatted_price = "{:,}".format(price)  # جدا کردن قیمت سه رقم سه رقم
            formatted_mileage = "{:,}".format(mileage)  # جدا کردن کارکرد سه رقم سه رقم

            # متن پیام با فرمت مارک‌داون
            message_text = (
                "{brand_name} | {model_name}\n\n"
                "مدل: {year}\n"
                "رنگ: {color_name}\n"
                "کارکرد: {formatted_mileage} کیلومتر\n"
                "قیمت: {formatted_price} تومان\n"
            )


            if has_warranty:
                message_text += "گارانتی: {warranty_period} ماه\n"

            if has_insurance:
                message_text += "بیمه: {insurance_period} ماه\n"

            if description:
                message_text += "توضیحات: {description}\n"


            message_text += (
                "\n"
                "کانال موجودی واتساپ\n\n"
                "کانال موجودی تلگرام\n\n"
                "تلفن تماس: {phone_number}\n\n"
                "دپارتمان خودرویی دیانت دار"
            )

            message_text = message_text.format(
                brand_name=brand_name,
                model_name=model_name,
                year=year,
                color_name=color_name,
                formatted_mileage=formatted_mileage,
                formatted_price=formatted_price,
                warranty_period=warranty_period,
                insurance_period=insurance_period,
                description=description,
                phone_number=phone_number
            )

            # لیست موقعیت‌ها و داکیومنت آیدی‌ها
            emoji_positions = [
                (message_text.find("مدل"), 5208801655004350721),  # ⭐
                (message_text.find("رنگ"), 5429619972529736627),  # 🎨
                (message_text.find("کارکرد"), 5341715473882955310),  # 📏
                (message_text.find("قیمت"), 5224257782013769471),  # 💰
            ]
            
 
            if has_warranty:
                emoji_positions.append((message_text.find("گارانتی"), 5251203410396458957))  # 🔧
                
            if has_insurance:
                emoji_positions.append((message_text.find("بیمه"), 5472239203590888751))  # ⭐

            if description:
                emoji_positions.append((message_text.find("توضیحات"), 5334544901428229844))  # ⭐
               

            emoji_positions.extend([
                (message_text.find("کانال موجودی واتساپ"), 5334998226636390258),  # 📱
                (message_text.find("کانال موجودی تلگرام"), 5330237710655306682),  # 📱
                (message_text.find("تلفن تماس"), 5253507424127557691),  # 📞
                (message_text.find("دپارتمان"), 5330320040883411678),  # 🗺
                (message_text.rfind("دیانت دار") + len("دیانت دار"), 5330320040883411678)  # 🗺
            ])

            entities = []
            offset_adjustment = 0

            # ایجاد entities و اضافه کردن ایموجی‌ها به متن
            for pos, doc_id in emoji_positions:
                adjusted_pos = pos + offset_adjustment
                message_text = message_text[:adjusted_pos] + "⭐ " + message_text[adjusted_pos:]  # Added space after emoji
                entities.append(MessageEntityCustomEmoji(
                    offset=adjusted_pos,
                    length=1,
                    document_id=doc_id
                ))
                offset_adjustment += 2  # Increased by 2 to account for emoji + space

            # اضافه کردن entities برای لینک‌ها
            from telethon.tl.types import MessageEntityTextUrl

            whatsapp_channel_pos = message_text.find("کانال موجودی واتساپ")
            telegram_pos = message_text.find("کانال موجودی تلگرام")

            if whatsapp_channel_pos != -1:
                entities.append(MessageEntityTextUrl(
                    offset=whatsapp_channel_pos,
                    length=19,  # length of کانال موجودی واتساپ
                    url=whatsapp_link
                ))

            if telegram_pos != -1:
                entities.append(MessageEntityTextUrl(
                    offset=telegram_pos,
                    length=19,  # length of کانال موجودی تلگرام
                    url=telegram_link
                ))

            messages.append((message_text, entities))
            
        return messages
    except pymysql.MySQLError as e:
        logging.error(f"خطای پایگاه داده: {str(e)}")
        return None
    except Exception as e:
        logging.error(f"خطا در پردازش درخواست: {str(e)}")
        return None
    finally:
        if conn:
            conn.close()

async def send_messages(time_range_name, start_time, end_time):
    async with TelegramClient(session_name, api_id, api_hash) as client:
        await client.start()
        
        messages = get_text_from_db(start_time, end_time)
        if not messages:
            logging.warning(f"❌ هیچ متنی برای بازه {time_range_name} در دیتابیس پیدا نشد!")
            return
            
        for message_text, entities in messages:
            try:
                # ارسال پیام
                sent_message = await client.send_message(channel_id, message_text, formatting_entities=entities)
                logging.info(f"✅ پیام برای بازه {time_range_name} با موفقیت ارسال شد!")
                    
            except Exception as e:
                logging.error(f"❌ خطا در ارسال پیام برای بازه {time_range_name}: {str(e)}")

async def manual_send():
    print("لطفا بازه زمانی مورد نظر را انتخاب کنید:")
    print("1. صبح (21:00 دیروز تا 9:00 امروز)")
    print("2. ظهر (9:00 تا 12:00)")
    print("3. بعدازظهر (12:00 تا 15:00)")
    print("4. عصر (15:00 تا 18:00)") 
    print("5. شب (18:00 تا 21:00)")
    
    choice = input("شماره بازه را وارد کنید (1-5): ")
    
    now = datetime.now()
    
    ranges = {
        "1": ("صبح", now.replace(hour=21, minute=0, second=0) - timedelta(days=1),
                     now.replace(hour=9, minute=0, second=0)),
        "2": ("ظهر", now.replace(hour=9, minute=0, second=0),
                     now.replace(hour=12, minute=0, second=0)),
        "3": ("بعدازظهر", now.replace(hour=12, minute=0, second=0),
                         now.replace(hour=15, minute=0, second=0)),
        "4": ("عصر", now.replace(hour=15, minute=0, second=0),
                     now.replace(hour=18, minute=0, second=0)),
        "5": ("شب", now.replace(hour=18, minute=0, second=0),
                     now.replace(hour=21, minute=0, second=0))
    }
    
    if choice in ranges:
        time_range_name, start_time, end_time = ranges[choice]
        await send_messages(time_range_name, start_time, end_time)
    else:
        print("انتخاب نامعتبر!")

def schedule_jobs():
    scheduler = AsyncIOScheduler()
    
    # ساعت ۹ صبح - ارسال ثبت‌های دیشب (۲۱:۰۰ دیروز تا ۹:۰۰ امروز)
    scheduler.add_job(
        send_messages, 
        'cron', 
        hour=9, 
        args=['صبح', 
              datetime.now().replace(hour=21, minute=0, second=0) - timedelta(days=1),
              datetime.now().replace(hour=9, minute=0, second=0)]
    )
    
    # ساعت ۱۲ ظهر - ارسال ثبت‌های صبح (۹:۰۰ تا ۱۲:۰۰)
    scheduler.add_job(
        send_messages, 
        'cron', 
        hour=12, 
        args=['ظهر',
              datetime.now().replace(hour=9, minute=0, second=0),
              datetime.now().replace(hour=12, minute=0, second=0)]
    )
    
    # ساعت ۱۵ (۳ بعدازظهر) - ارسال ثبت‌های ظهر (۱۲:۰۰ تا ۱۵:۰۰)
    scheduler.add_job(
        send_messages, 
        'cron', 
        hour=15, 
        args=['بعدازظهر',
              datetime.now().replace(hour=12, minute=0, second=0),
              datetime.now().replace(hour=15, minute=0, second=0)]
    )
    
    # ساعت ۱۸ (۶ عصر) - ارسال ثبت‌های بعدازظهر (۱۵:۰۰ تا ۱۸:۰۰)
    scheduler.add_job(
        send_messages, 
        'cron', 
        hour=18, 
        args=['عصر',
              datetime.now().replace(hour=15, minute=0, second=0),
              datetime.now().replace(hour=18, minute=0, second=0)]
    )
    
    # ساعت ۲۱ (۹ شب) - ارسال ثبت‌های عصر (۱۸:۰۰ تا ۲۱:۰۰)
    scheduler.add_job(
        send_messages, 
        'cron', 
        hour=21, 
        args=['شب',
              datetime.now().replace(hour=18, minute=0, second=0),
              datetime.now().replace(hour=21, minute=0, second=0)]
    )
    
    scheduler.start()
    
    # نگه داشتن برنامه در حال اجرا
    try:
        asyncio.get_event_loop().run_forever()
    except (KeyboardInterrupt, SystemExit):
        pass

if __name__ == "__main__":
    print("1. اجرای خودکار زمانبندی")
    print("2. ارسال دستی")
    choice = input("لطفا یک گزینه را انتخاب کنید (1-2): ")
    
    if choice == "1":
        schedule_jobs()
    elif choice == "2":
        asyncio.run(manual_send())
    else:
        print("انتخاب نامعتبر!")
