#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import logging
import sys
from typing import Dict, List, Optional, Any
from datetime import datetime
import socket
import json
import requests
from collections import defaultdict
from datetime import datetime, date


def check_port(port=8443):
    """بررسی اینکه پورت در حال استفاده نیست"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(1)
        result = sock.connect_ex(('127.0.0.1', port))
        sock.close()
        return result == 0
    except:
        return False

def main():
    # بررسی پورت‌های مختلف
    ports = [8443, 8444, 8445, 8446]
    for port in ports:
        if not check_port(port):
            print(f"✅ پورت {port} آزاد است")
            break
    else:
        print("❌ همه پورت‌ها مشغول هستند! لطفاً ربات‌های قبلی را متوقف کنید.")
        return
    
    # بقیه کدهای main...
    
    
# بررسی نسخه پایتون
if sys.version_info < (3, 7):
    print("❌ Python 3.7 or higher is required")
    sys.exit(1)

from telegram import (
    Update, 
    ReplyKeyboardMarkup, 
    KeyboardButton, 
    ReplyKeyboardRemove
)
from telegram.ext import (
    Updater,
    CommandHandler,
    MessageHandler,
    Filters,
    CallbackContext,
    ConversationHandler
)
from dotenv import load_dotenv

# بارگذاری متغیرهای محیطی
load_dotenv()

# تنظیمات
BOT_TOKEN = os.getenv('BOT_TOKEN')
API_BASE_URL = "https://amlakjame.ir"

# حالت‌های مکالمه
(
    GET_PROVINCE, GET_CITY, 
    ADVANCED_SEARCH, VIEW_LISTINGS
) = range(4)

# تنظیمات لاگ‌گیری
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO,
    handlers=[
        logging.FileHandler('logs/bot.log', encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

class UserStats:
    def __init__(self):
        self.stats_file = 'logs/user_stats.json'
        self.load_stats()
    
    def load_stats(self):
        """بارگذاری آمار از فایل"""
        try:
            with open(self.stats_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                self.stats = data
                # تبدیل لیست active_users به set
                if 'active_users' in data and isinstance(data['active_users'], list):
                    self.stats['active_users'] = set(data['active_users'])
                else:
                    self.stats['active_users'] = set()
        except FileNotFoundError:
            self.stats = {
                'total_users': 0,
                'active_users': set(),
                'daily_stats': {},
                'user_actions': {},
                'provinces': {},
                'cities': {}
            }
    
    def save_stats(self):
        """ذخیره آمار در فایل"""
        # تبدیل set به list برای JSON
        stats_to_save = self.stats.copy()
        stats_to_save['active_users'] = list(stats_to_save['active_users'])
        
        with open(self.stats_file, 'w', encoding='utf-8') as f:
            json.dump(stats_to_save, f, ensure_ascii=False, indent=2)
    
    def track_user_action(self, user_id: int, username: str, action: str, province: str = None, city: str = None):
        """رهگیری فعالیت کاربر"""
        today = str(date.today())
        
        # مقداردهی اولیه
        if today not in self.stats['daily_stats']:
            self.stats['daily_stats'][today] = {
                'new_users': 0,
                'total_actions': 0,
                'searches': 0
            }
        
        # افزودن کاربر به لیست کاربران فعال
        user_key = str(user_id)
        if user_key not in self.stats['active_users']:
            self.stats['active_users'].add(user_key)
            self.stats['total_users'] = len(self.stats['active_users'])
            self.stats['daily_stats'][today]['new_users'] += 1
        
        # رهگیری اقدامات کاربر
        if user_key not in self.stats['user_actions']:
            self.stats['user_actions'][user_key] = {
                'username': username,
                'first_seen': datetime.now().isoformat(),
                'last_seen': datetime.now().isoformat(),
                'total_actions': 0,
                'actions': []
            }
        
        # به‌روزرسانی آمار کاربر
        self.stats['user_actions'][user_key]['last_seen'] = datetime.now().isoformat()
        self.stats['user_actions'][user_key]['total_actions'] += 1
        self.stats['user_actions'][user_key]['actions'].append({
            'action': action,
            'timestamp': datetime.now().isoformat(),
            'province': province,
            'city': city
        })
        
        # آمار کلی
        self.stats['daily_stats'][today]['total_actions'] += 1
        
        if action == 'search':
            self.stats['daily_stats'][today]['searches'] += 1
        
        # آمار استان‌ها و شهرها
        if province:
            if province not in self.stats['provinces']:
                self.stats['provinces'][province] = 0
            self.stats['provinces'][province] += 1
            
            if city:
                if city not in self.stats['cities']:
                    self.stats['cities'][city] = 0
                self.stats['cities'][city] += 1
        
        self.save_stats()

class AmlakJameBot:
    def __init__(self):
        self.api_base_url = API_BASE_URL
        self.user_city_pages = {}  # ذخیره صفحات شهرهای کاربران
        self.user_stats = UserStats()
        
    def start(self, update: Update, context: CallbackContext) -> int:
        """شروع ربات"""
        user = update.message.from_user
        logger.info("User %s started the bot", user.id)
        
        # رهگیری کاربر
        self.user_stats.track_user_action(
            user.id, 
            user.username or f"user_{user.id}", 
            'start'
        )
        
        # پاک کردن داده‌های قدیمی کاربر
        context.user_data.clear()
        
        update.message.reply_text(
            "🟢 به ربات املاک جامع خوش آمدید!\n\n"
            "🏙️ لطفاً استان مورد نظر خود را انتخاب کنید:",
            reply_markup=self.get_provinces_keyboard()
        )
        
        return GET_PROVINCE

    def get_province(self, update: Update, context: CallbackContext) -> int:
        """دریافت استان از کاربر"""
        province = update.message.text.strip()
        context.user_data['province'] = province
        
        logger.info("Province selected: %s", province)
        
        # رهگیری انتخاب استان
        user = update.message.from_user
        self.user_stats.track_user_action(
            user.id,
            user.username or f"user_{user.id}",
            'select_province',
            province
        )
        
        # پاک کردن صفحات قبلی شهر
        user_id = update.effective_user.id
        if user_id in self.user_city_pages:
            del self.user_city_pages[user_id]
        
        update.message.reply_text(
            "🏙️ استان {} انتخاب شد.\n"
            "🏘️ لطفاً شهر مورد نظر خود را انتخاب کنید:".format(province),
            reply_markup=self.get_cities_keyboard(province, user_id, 0)
        )
        
        return GET_CITY

    def get_city(self, update: Update, context: CallbackContext) -> int:
        """دریافت شهر از کاربر"""
        text = update.message.text.strip()
        user_id = update.effective_user.id
        
        # بررسی اگر دکمه ناوبری باشد
        if text == "⬅️ شهرهای قبلی":
            current_page = self.user_city_pages.get(user_id, 0)
            if current_page > 0:
                self.user_city_pages[user_id] = current_page - 1
                province = context.user_data.get('province', 'نامشخص')
                update.message.reply_text(
                    "🏘️ لطفاً شهر مورد نظر خود را انتخاب کنید:",
                    reply_markup=self.get_cities_keyboard(province, user_id, current_page - 1)
                )
            return GET_CITY
            
        elif text == "➡️ شهرهای بعدی":
            current_page = self.user_city_pages.get(user_id, 0)
            province = context.user_data.get('province', 'نامشخص')
            cities = self.get_all_cities_for_province(province)
            total_pages = (len(cities) + 14) // 15  # 15 شهر در هر صفحه
            
            if current_page < total_pages - 1:
                self.user_city_pages[user_id] = current_page + 1
                update.message.reply_text(
                    "🏘️ لطفاً شهر مورد نظر خود را انتخاب کنید:",
                    reply_markup=self.get_cities_keyboard(province, user_id, current_page + 1)
                )
            return GET_CITY
        
        # اگر نام شهر انتخاب شده
        city = text
        province = context.user_data.get('province', 'نامشخص')
        context.user_data['city'] = city
        
        logger.info("City selected: %s in %s", city, province)
        
        # رهگیری انتخاب شهر
        user = update.message.from_user
        self.user_stats.track_user_action(
            user.id,
            user.username or f"user_{user.id}",
            'select_city',
            province,
            city
        )
        
        # پاک کردن اطلاعات صفحات شهر
        if user_id in self.user_city_pages:
            del self.user_city_pages[user_id]
        
        # نمایش منوی جستجوی پیشرفته بعد از انتخاب شهر
        self.show_advanced_search(update, context)
        return ADVANCED_SEARCH

    def get_provinces_keyboard(self):
        """دریافت کیبورد استان‌ها"""
        try:
            provinces = self.get_provinces_list()
            if provinces:
                keyboard = self.create_keyboard_layout(provinces, columns=2)
                return ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=True)
        except Exception as e:
            logger.error("Error getting provinces keyboard: %s", e)
        
        # کیبورد پیش‌فرض در صورت خطا
        keyboard = [
            ["آذربایجان شرقی", "آذربایجان غربی"],
            ["اردبیل", "اصفهان"],
            ["البرز", "ایلام"],
            ["بوشهر", "تهران"],
            ["چهارمحال و بختیاری", "خراسان جنوبی"],
            ["خراسان رضوی", "خراسان شمالی"],
            ["خوزستان", "زنجان"],
            ["سمنان", "سیستان و بلوچستان"],
            ["فارس", "قزوین"],
            ["قم", "کردستان"],
            ["کرمان", "کرمانشاه"],
            ["کهگیلویه و بویراحمد", "گلستان"],
            ["گیلان", "لرستان"],
            ["مازندران", "مرکزی"],
            ["هرمزگان", "همدان"],
            ["یزد"]
        ]
        return ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=True)

    def get_cities_keyboard(self, province, user_id, page=0):
        """دریافت کیبورد شهرهای یک استان با صفحه‌بندی"""
        try:
            # ذخیره صفحه فعلی برای کاربر
            self.user_city_pages[user_id] = page
            
            # دریافت تمام شهرهای استان
            all_cities = self.get_all_cities_for_province(province)
            
            if not all_cities:
                all_cities = self.get_default_cities(province)
            
            # محاسبه صفحات
            cities_per_page = 15  # 15 شهر در هر صفحه
            total_pages = (len(all_cities) + cities_per_page - 1) // cities_per_page
            
            # محاسبه اندیس‌های شروع و پایان
            start_idx = page * cities_per_page
            end_idx = min(start_idx + cities_per_page, len(all_cities))
            
            # ایجاد کیبورد برای شهرهای صفحه فعلی
            current_cities = all_cities[start_idx:end_idx]
            keyboard = self.create_keyboard_layout(current_cities, columns=3)  # 3 ستونی برای شهرها
            
            # اضافه کردن دکمه‌های ناوبری اگر نیاز باشد
            navigation_row = []
            if page > 0:
                navigation_row.append("⬅️ شهرهای قبلی")
            if page < total_pages - 1:
                navigation_row.append("➡️ شهرهای بعدی")
            
            if navigation_row:
                keyboard.append(navigation_row)
            
            return ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=True)
                        
        except Exception as e:
            logger.error("Error getting cities keyboard for %s: %s", province, e)
            # کیبورد پیش‌فرض در صورت خطا
            default_cities = self.get_default_cities(province)
            keyboard = self.create_keyboard_layout(default_cities, columns=2)
            return ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=True)

    def get_all_cities_for_province(self, province):
        """دریافت تمام شهرهای یک استان از API"""
        try:
            logger.info("Fetching all cities for province: %s", province)
            
            endpoints = [
                f"{self.api_base_url}/realestate/cities",
                f"{self.api_base_url}/cities",
                f"{self.api_base_url}/realestate/get-cities"
            ]
            
            for endpoint in endpoints:
                try:
                    params = {"province": province}
                    response = requests.get(
                        endpoint, 
                        params=params, 
                        timeout=10,
                        headers={
                            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                            'Accept': 'application/json',
                            'Referer': 'https://amlakjame.ir'
                        }
                    )
                    
                    logger.info("Cities API Response status for %s: %s", endpoint, response.status_code)
                    
                    if response.status_code == 200:
                        data = response.json()
                        logger.info("Received %s cities from API", len(data) if isinstance(data, list) else 'unknown')
                        
                        # بررسی ساختارهای مختلف پاسخ API
                        cities = []
                        if isinstance(data, list):
                            cities = data
                        elif isinstance(data, dict):
                            if 'data' in data and isinstance(data['data'], list):
                                cities = data['data']
                            elif 'cities' in data and isinstance(data['cities'], list):
                                cities = data['cities']
                            elif 'items' in data and isinstance(data['items'], list):
                                cities = data['items']
                        
                        if cities:
                            logger.info("Successfully extracted %s cities for %s", len(cities), province)
                            return cities
                
                except Exception as e:
                    logger.error("Error with endpoint %s: %s", endpoint, e)
                    continue
            
            return []
                        
        except Exception as e:
            logger.error("Error getting all cities for %s: %s", province, e)
            return []

    def get_default_cities(self, province):
        """دریافت لیست پیش‌فرض شهرها برای هر استان"""
        cities_map = {
            "آذربایجان شرقی": ["تبریز", "مراغه", "مرند", "میانه", "اهر", "سراب", "هریس", "بناب", "اسکو", "آذرشهر", "شبستر", "کلیبر", "هشترود", "جلفا", "ملکان", "چاراویماق", "ورزقان", "عجبشیر", "خداآفرین"],
            "آذربایجان غربی": ["ارومیه", "خوی", "مهاباد", "سلماس", "بوکان", "ماکو", "میاندوآب", "اشنویه", "پیرانشهر", "تکاب", "چالدران", "شاهین دژ", "پلدشت", "نقده", "سیاهکل", "شوط"],
            "اردبیل": ["اردبیل", "مشگین شهر", "پارس آباد", "خلخال", "گرمی", "بیله سوار", "نمین", "نیر", "کوثر", "سرعین", "انگوت"],
            "اصفهان": ["اصفهان", "کاشان", "خمینی شهر", "شاهین شهر", "نجف آباد", "آران و بیدگل", "فلاورجان", "گلپایگان", "دهاقان", "نطنز", "سمیرم", "شهرضا", "مبارکه", "زرین شهر", "تیران", "ورزنه", "چادگان", "باغ بهادران", "حبیب آباد", "خور و بیابانک"],
            "البرز": ["کرج", "هشتگرد", "نظرآباد", "ماهدشت", "محمدشهر", "طالقان", "اشتهارد", "فردیس", "کمال شهر", "گرمدره", "گلسار"],
            "ایلام": ["ایلام", "دهلران", "ایوان", "آبدانان", "مهران", "دره شهر", "سرابله", "چوار", "بدره", "هلیلان"],
            "بوشهر": ["بوشهر", "برازجان", "جم", "کنگان", "خورموج", "اهرم", "دشتستان", "دشتی", "دیر", "کنگان", "عسلویه", "تنگستان", "جم", "گناوه"],
            "تهران": ["تهران", "اسلامشهر", "شهریار", "ری", "ورامین", "پاکدشت", "قدس", "ملارد", "بهارستان", "قرچک", "پردیس", "دماوند", "شمیرانات", "فیروزکوه", "رباط کریم", "پیشوا", "کهریزک"],
            "چهارمحال و بختیاری": ["شهرکرد", "بروجن", "فارسان", "لردگان", "اردل", "چلگرد", "سامان", "بن", "نافچ", "کیار", "گهرو"],
            "خراسان جنوبی": ["بیرجند", "قائن", "فردوس", "نهبندان", "بشرویه", "سربیشه", "درمیان", "خوسف", "طبس", "زیرکوه"],
            "خراسان رضوی": ["مشهد", "نیشابور", "سبزوار", "تربت حیدریه", "قوچان", "کاشمر", "سرخس", "فریمان", "تربت جام", "چناران", "خواف", "درگز", "رشتخوار", "گناباد", "مه ولات", "باخرز", "فیروزه", "بینالود", "زبرخان"],
            "خراسان شمالی": ["بجنورد", "شیروان", "اسفراین", "فاروج", "گرمه", "جاجرم", "راز و جرگلان", "مانه و سملقان"],
            "خوزستان": ["اهواز", "آبادان", "خرمشهر", "دزفول", "مسجدسلیمان", "اندیمشک", "شوش", "شوشتر", "بندر ماهشهر", "رامهرمز", "بهبهان", "هویزه", "امیدیه", "گتوند", "لالی", "هفتکل", "باغ ملک", "حمیدیه", "کارون"],
            "زنجان": ["زنجان", "ابهر", "خرمدره", "قیدار", "خدابنده", "ماهنشان", "طارم", "سلطانیه", "آببر", "نیکپی"],
            "سمنان": ["سمنان", "شاهرود", "دامغان", "گرمسار", "مهدی شهر", "سرخه", "آرادان", "میامی", "کلاته", "بسطام"],
            "سیستان و بلوچستان": ["زاهدان", "زابل", "چابهار", "ایرانشهر", "خاش", "سراوان", "نیکشهر", "کنارک", "سرباز", "دلگان", "میرجاوه", "قصرقند", "زهک", "هیرمند"],
            "فارس": ["شیراز", "مرودشت", "کازرون", "جهرم", "فسا", "داراب", "لار", "اقلید", "آباده", "استهبان", "لامرد", "ممسنی", "بوانات", "خرامه", "خنج", "قیر و کارزین", "سپیدان", "فراشبند", "کوار", "گراش", "نی ریز"],
            "قزوین": ["قزوین", "البرز", "آبیک", "بویین زهرا", "تاکستان", "آوج", "شال", "اسفرورین", "ضیاءآباد"],
            "قم": ["قم", "جعفریه", "دستجرد", "سلفچگان", "کهک"],
            "کردستان": ["سنندج", "سقز", "مریوان", "بانه", "بیجار", "قروه", "کامیاران", "دهگلان", "دیواندره", "سروآباد"],
            "کرمان": ["کرمان", "رفسنجان", "سیرجان", "بم", "جیرفت", "زرند", "شهربابک", "کهنوج", "بافت", "عنبرآباد", "راور", "بردسیر", "منوجان", "قلعه گنج", "کوهبنان", "فهرج", "رودبار جنوب"],
            "کرمانشاه": ["کرمانشاه", "اسلام آباد غرب", "هرسین", "کنگاور", "سنقر", "پاوه", "جوانرود", "ثلاث باباجانی", "روانسر", "دالاهو", "گیلانغرب", "قصر شیرین", "سرپل ذهاب"],
            "کهگیلویه و بویراحمد": ["یاسوج", "گچساران", "دهدشت", "سی سخت", "لیکک", "چرام", "باشت", "پاتاوه", "مارگون"],
            "گلستان": ["گرگان", "گنبد کاووس", "آق قلا", "بندر ترکمن", "کردکوی", "کلاله", "علی آباد", "مینودشت", "رامیان", "آزادشهر", "مراوه تپه", "گالیکش", "گمیشان"],
            "گیلان": ["رشت", "انزلی", "لاهیجان", "تالش", "آستارا", "رودسر", "صومعه سرا", "فومن", "لنگرود", "ماسال", "رودبار", "شفت", "سیاهکل", "املش", "بندرانزلی", "خمام", "خشکبیجار"],
            "لرستان": ["خرم آباد", "بروجرد", "دورود", "کوهدشت", "الیگودز", "ازنا", "پلدختر", "الشتر", "نورآباد", "سلسله", "رومشکان", "چگنی"],
            "مازندران": ["ساری", "بابل", "آمل", "قائم شهر", "تنکابن", "نور", "نوشهر", "چالوس", "رامسر", "بهشهر", "جویبار", "گلوگاه", "عباس آباد", "میاندورود", "سوادکوه", "سیمرغ", "کلاردشت", "فریدونکنار", "محمودآباد"],
            "مرکزی": ["اراک", "ساوه", "خمین", "محلات", "تفرش", "آشتیان", "شازند", "دلیجان", "زرندیه", "کمیجان", "فراهان", "خنداب"],
            "هرمزگان": ["بندر عباس", "قشم", "کیش", "میناب", "بندر لنگه", "حاجی آباد", "رودان", "بستک", "جاسک", "خمیر", "پارسیان", "ابوموسی", "سیریک"],
            "همدان": ["همدان", "ملایر", "نهاوند", "تویسرکان", "کبودرآهنگ", "اسدآباد", "بهار", "رزن", "فامنین", "قروه درجزین"],
            "یزد": ["یزد", "میبد", "اردکان", "بافق", "مهریز", "اشکذر", "تفت", "ابرکوه", "بهاباد", "خاتم", "صدوق"]
        }
        return cities_map.get(province, ["مرکز استان"])

    def create_keyboard_layout(self, items, columns=2):
        """ایجاد طرح‌بندی کیبورد"""
        if not items:
            return [["مرکز استان"]]
            
        keyboard = []
        row = []
        
        for i, item in enumerate(items):
            row.append(item)
            if len(row) == columns or i == len(items) - 1:
                keyboard.append(row)
                row = []
        
        return keyboard

    def get_provinces_list(self):
        """دریافت لیست استان‌ها از API"""
        try:
            logger.info("Fetching provinces list from API...")
            response = requests.get(
                f"{self.api_base_url}/realestate/provinces", 
                timeout=10,
                headers={
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
                }
            )
            logger.info("API Response status: %s", response.status_code)
            
            if response.status_code == 200:
                data = response.json()
                logger.info("API Response data: %s", data)
                
                # بررسی ساختارهای مختلف پاسخ API
                if isinstance(data, list):
                    return data
                elif isinstance(data, dict):
                    if 'data' in data:
                        return data['data']
                    elif 'provinces' in data:
                        return data['provinces']
                    elif 'items' in data:
                        return data['items']
                
                logger.warning("Unexpected API response structure: %s", data)
                return []
            else:
                logger.error("API returned status %s: %s", response.status_code, response.text)
                return []
                
        except Exception as e:
            logger.error("Error getting provinces list: %s", e)
            return []

    def show_advanced_search(self, update, context):
        """نمایش منوی جستجوی پیشرفته"""
        province = context.user_data.get('province', 'نامشخص')
        city = context.user_data.get('city', 'نامشخص')
        
        keyboard = [
            ["فروش خانه / ویلا", "اجاره خانه / ویلا"],
            ["فروش زمین", "فروش مغازه / واحد تجاری"],
            ["اجاره مغازه / واحد تجاری"],
            ["📍 تغییر موقعیت"]
        ]
        reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
        
        update.message.reply_text(
            "🏙️ موقعیت: {} - {}\n\n"
            "🔍 لطفاً نوع ملک مورد نظر خود را انتخاب کنید:".format(province, city),
            reply_markup=reply_markup
        )

    def handle_advanced_search(self, update, context):
        """مدیریت جستجوی پیشرفته"""
        text = update.message.text
        
        province = context.user_data.get('province')
        city = context.user_data.get('city')
        
        if text == "📍 تغییر موقعیت":
            update.message.reply_text(
                "🏙️ لطفاً استان مورد نظر خود را انتخاب کنید:",
                reply_markup=self.get_provinces_keyboard()
            )
            return GET_PROVINCE
        
        # بررسی اینکه آیا گزینه معتبری انتخاب شده است
        valid_property_types = [
            "فروش خانه / ویلا",
            "اجاره خانه / ویلا", 
            "فروش زمین",
            "فروش مغازه / واحد تجاری",
            "اجاره مغازه / واحد تجاری"
        ]
        
        if text in valid_property_types:
            # رهگیری جستجو
            user = update.message.from_user
            self.user_stats.track_user_action(
                user.id,
                user.username or f"user_{user.id}",
                'search',
                province,
                city
            )
            
            # ذخیره نوع ملک انتخاب شده
            context.user_data['property_type'] = text
            context.user_data['current_page'] = 0
            
            # نمایش آگهی‌ها
            return self.show_listings_page(update, context)
        else:
            update.message.reply_text(
                "❌ لطفاً یکی از گزینه‌های موجود را انتخاب کنید."
            )
            return ADVANCED_SEARCH

    def show_listings_page(self, update, context):
        """نمایش یک صفحه از آگهی‌ها"""
        try:
            province = context.user_data.get('province')
            city = context.user_data.get('city')
            property_type = context.user_data.get('property_type')
            current_page = context.user_data.get('current_page', 0)
            
            if not province or not city:
                update.message.reply_text(
                    "لطفاً ابتدا موقعیت مکانی خود را تنظیم کنید.",
                    reply_markup=self.get_provinces_keyboard()
                )
                return GET_PROVINCE
            
            # نمایش پیام در حال بارگذاری
            loading_msg = update.message.reply_text("🔍 در حال دریافت آگهی‌ها...")
            
            # دریافت آگهی‌ها از API
            all_listings = self.get_listings_from_api(province, city, property_type)
            
            # حذف پیام در حال بارگذاری
            try:
                context.bot.delete_message(chat_id=update.effective_chat.id, message_id=loading_msg.message_id)
            except:
                pass
            
            if not all_listings:
                message = "📭 در حال حاضر آگهی‌ای در {} - {} موجود نیست.".format(province, city)
                if property_type:
                    message += "\nدسته‌بندی: {}".format(property_type)
                message += "\nلطفاً نوع ملک یا موقعیت مکانی را تغییر دهید."
                
                update.message.reply_text(
                    message,
                    reply_markup=self.get_navigation_keyboard(0, 0, has_listings=False)
                )
                return VIEW_LISTINGS
            
            # ذخیره تمام آگهی‌ها
            context.user_data['all_listings'] = all_listings
            total_listings = len(all_listings)
            
            # محاسبه صفحات
            listings_per_page = 5
            total_pages = (total_listings + listings_per_page - 1) // listings_per_page
            
            # محدود کردن صفحه جاری به محدوده مجاز
            current_page = max(0, min(current_page, total_pages - 1))
            context.user_data['current_page'] = current_page
            
            # محاسبه اندیس‌های شروع و پایان
            start_idx = current_page * listings_per_page
            end_idx = min(start_idx + listings_per_page, total_listings)
            
            # ارسال خلاصه آگهی‌ها
            summary_msg = "🏠 آگهی‌های املاک در {} - {}".format(province, city)
            if property_type:
                summary_msg += "\n📋 دسته‌بندی: {}".format(property_type)
            summary_msg += "\n📊 تعداد کل آگهی‌ها: {}".format(total_listings)
            summary_msg += "\n📄 صفحه: {}/{} (آگهی‌های {}-{})".format(
                current_page + 1, total_pages, start_idx + 1, end_idx
            )
            
            update.message.reply_text(summary_msg)
            
            # نمایش آگهی‌های صفحه جاری
            for i in range(start_idx, end_idx):
                listing = all_listings[i]
                message = self.format_listing_message(listing)
                
                try:
                    # ارسال پیام بدون parse_mode برای تست
                    # اگر مشکل حل شد، می‌توانید دوباره از HTML استفاده کنید
                    update.message.reply_text(
                        message,
                        parse_mode='HTML',
                        disable_web_page_preview=True,  # غیرفعال کردن پیش‌نمایش برای جلوگیری از مشکلات
                        disable_notification=True
                    )
                except Exception as e:
                    logger.error("Error sending listing %s: %s", i, e)
                    # ارسال پیام ساده در صورت خطا
                    try:
                        simple_message = "🏠 {}\n💰 {}\n📍 {}\n🔗 {}".format(
                            listing.get('titleAd', 'بدون عنوان'),
                            listing.get('price', 'قیمت تماس'),
                            listing.get('province', 'نامشخص') + ' - ' + listing.get('city', 'نامشخص'),
                            "https://amlakjame.ir/listing/{}".format(listing.get('id', ''))
                        )
                        update.message.reply_text(simple_message)
                    except Exception as e2:
                        logger.error("Error sending simple message: %s", e2)
                        continue
            
            # نمایش کیبورد ناوبری
            update.message.reply_text(
                "از دکمه‌های زیر برای پیمایش استفاده کنید:",
                reply_markup=self.get_navigation_keyboard(current_page, total_pages, has_listings=True)
            )
            
            return VIEW_LISTINGS
                    
        except Exception as e:
            logger.error("Error showing listings page: %s", e)
            update.message.reply_text(
                "❌ خطا در دریافت آگهی‌ها. لطفاً بعداً مجدداً تلاش کنید.",
                reply_markup=self.get_navigation_keyboard(0, 0, has_listings=False)
            )
            return VIEW_LISTINGS

    def get_listings_from_api(self, province, city, property_type=None):
        """دریافت آگهی‌ها از API وب‌سایت"""
        try:
            # پارامترهای پایه
            params = {
                'province': province,
                'city': city
            }
            
            # اضافه کردن نوع ملک اگر مشخص شده باشد
            if property_type:
                # نگاشت نوع ملک به مقادیر API بر اساس تابع getFilteredProperties
                type_mapping = {
                    "فروش خانه / ویلا": "خانه فروشی",
                    "اجاره خانه / ویلا": "خانه اجاره ایی", 
                    "فروش زمین": "فروش زمین",
                    "فروش مغازه / واحد تجاری": "فروش مغازه",
                    "اجاره مغازه / واحد تجاری": "اجاره مغازه"
                }
                
                api_property_type = type_mapping.get(property_type)
                if api_property_type:
                    params['type'] = api_property_type
            
            logger.info("Fetching listings with params: %s", params)
            
            # فراخوانی API
            response = requests.get(
                "{}/realestate/listings".format(self.api_base_url), 
                params=params, 
                timeout=15,
                headers={
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                    'Accept': 'application/json',
                    'Referer': 'https://amlakjame.ir'
                }
            )
            
            logger.info("Listings API response status: %s", response.status_code)
            
            if response.status_code == 200:
                data = response.json()
                logger.info("Listings API response data sample: %s", data[:1] if isinstance(data, list) and data else data)
                
                if isinstance(data, list):
                    return data
                elif isinstance(data, dict):
                    if data.get('success'):
                        listings = data.get('data', [])
                        logger.info("Found %s listings", len(listings))
                        return listings
                    else:
                        logger.error("API returned success=false: %s", data.get('message', 'Unknown error'))
                        return []
                else:
                    logger.error("Unexpected API response format: %s", type(data))
                    return []
            else:
                logger.error("API returned status %s: %s", response.status_code, response.text)
                return []
                        
        except Exception as e:
            logger.error("Error getting listings: %s", e)
            return []

    def format_listing_message(self, listing):
        """قالب‌بندی پیام آگهی"""
        try:
            title = listing.get('titleAd', 'بدون عنوان')
            price = listing.get('price', 'قیمت تماس')
            
            # برای املاک اجاره‌ای، قیمت را به صورت ترکیبی نشان بده
            if not price or price == 'قیمت تماس':
                deposite = listing.get('deposite')
                rent = listing.get('rent')
                if deposite or rent:
                    price_parts = []
                    if deposite:
                        price_parts.append("ودیعه: {}".format(deposite))
                    if rent:
                        price_parts.append("اجاره: {}".format(rent))
                    price = " + ".join(price_parts) if price_parts else 'قیمت تماس'
            
            location = listing.get('province', 'نامشخص') + ' - ' + listing.get('city', 'نامشخص')
            description = listing.get('discription', '')
            
            # پاکسازی و محدود کردن طول توضیحات
            if description:
                # حذف تگ‌های HTML از توضیحات
                import re
                description = re.sub('<[^<]+?>', '', description)
                # جایگزینی کاراکترهای خاص
                description = description.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
                # محدود کردن طول توضیحات
                if len(description) > 300:
                    description = description[:300] + "..."
            else:
             description = "بدون توضیحات"
            
            property_type = listing.get('type', 'نامشخص')
            area = listing.get('area', 'نامشخص')
            bedrooms = listing.get('bedroom')
            
            # ساخت لینک جزئیات بر اساس نوع ملک
            listing_id = listing.get('id', '')
            
            # نگاشت نوع ملک به مسیرهای URL صحیح
            url_mapping = {
                "خانه فروشی": "Realestate/Homesellings/detail",
                "خانه اجاره ایی": "Realestate/Homerent/detail",
                "فروش زمین": "Realestate/Landselling/detail", 
                "فروش مغازه": "Realestate/Storeselling/detail",
                "اجاره مغازه": "Realestate/Storerent/detail"
            }
            
            # استفاده از مسیر صحیح بر اساس نوع ملک
            base_path = url_mapping.get(property_type, "listing")
            details_url = f"https://amlakjame.ir/{base_path}{listing_id}" if listing_id else "https://amlakjame.ir"
            
            # ساخت پیام با فرمت ساده‌تر
            message_parts = []
            message_parts.append("🏠 <b>{}</b>".format(self.escape_html(title)))
            message_parts.append("")
            message_parts.append("💰 قیمت: {}".format(self.escape_html(str(price))))
            message_parts.append("📍 موقعیت: {}".format(self.escape_html(location)))
            message_parts.append("📐 نوع ملک: {}".format(self.escape_html(property_type)))
            message_parts.append("📊 متراژ: {}".format(self.escape_html(str(area))))
            
            if bedrooms is not None:
                message_parts.append("🛏️ تعداد خواب: {}".format(self.escape_html(str(bedrooms))))
            
            message_parts.append("")
            message_parts.append("📝 توضیحات:")
            message_parts.append(description)
            message_parts.append("")
            message_parts.append('🔗 <a href="{}">مشاهده جزئیات کامل و تماس</a>'.format(details_url))
            
            return "\n".join(message_parts)
            
        except Exception as e:
            logger.error("Error formatting listing message: %s", e)
            # پیام ساده در صورت خطا
            return "❌ خطا در نمایش اطلاعات آگهی\n\nبرای مشاهده جزئیات کامل به سایت مراجعه کنید."

    def escape_html(self, text):
        """فرار کردن کاراکترهای HTML"""
        if text is None:
            return ""
        
        text = str(text)
        escape_chars = {
            '&': '&amp;',
            '<': '&lt;', 
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#39;'
        }
        
        for char, escaped in escape_chars.items():
            text = text.replace(char, escaped)
        
        return text
            
    def get_navigation_keyboard(self, current_page, total_pages, has_listings=True):
        """دریافت کیبورد ناوبری"""
        keyboard = []
        
        if has_listings and total_pages > 1:
            nav_row = []
            if current_page > 0:
                nav_row.append("⬅️ صفحه قبلی")
            if current_page < total_pages - 1:
                nav_row.append("➡️ صفحه بعدی")
            if nav_row:
                keyboard.append(nav_row)
        
        keyboard.append(["🔍 جستجوی جدید", "📍 تغییر موقعیت"])
        
        return ReplyKeyboardMarkup(keyboard, resize_keyboard=True)

    def handle_view_listings(self, update, context):
        """مدیریت نمایش آگهی‌ها"""
        text = update.message.text
        
        if text == "⬅️ صفحه قبلی":
            current_page = context.user_data.get('current_page', 0)
            if current_page > 0:
                context.user_data['current_page'] = current_page - 1
                return self.show_listings_page(update, context)
            else:
                update.message.reply_text("❌ شما در اولین صفحه هستید.")
                return VIEW_LISTINGS
                
        elif text == "➡️ صفحه بعدی":
            current_page = context.user_data.get('current_page', 0)
            all_listings = context.user_data.get('all_listings', [])
            total_pages = (len(all_listings) + 4) // 5  # 5 listings per page
            
            if current_page < total_pages - 1:
                context.user_data['current_page'] = current_page + 1
                return self.show_listings_page(update, context)
            else:
                update.message.reply_text("❌ شما در آخرین صفحه هستید.")
                return VIEW_LISTINGS
                
        elif text == "🔍 جستجوی جدید":
            # بازگشت به منوی جستجوی پیشرفته
            self.show_advanced_search(update, context)
            return ADVANCED_SEARCH
            
        elif text == "📍 تغییر موقعیت":
            update.message.reply_text(
                "🏙️ لطفاً استان مورد نظر خود را انتخاب کنید:",
                reply_markup=self.get_provinces_keyboard()
            )
            return GET_PROVINCE
        
        else:
            update.message.reply_text(
                "لطفاً از دکمه‌های زیر استفاده کنید:",
                reply_markup=self.get_navigation_keyboard(
                    context.user_data.get('current_page', 0), 
                    (len(context.user_data.get('all_listings', [])) + 4) // 5,
                    has_listings=len(context.user_data.get('all_listings', [])) > 0
                )
            )
            return VIEW_LISTINGS

    def stats_command(self, update: Update, context: CallbackContext):
        """دستور مشاهده آمار"""
        user = update.message.from_user
        
        # فقط ادمین‌ها بتوانند آمار را ببینند
        admin_ids = [589435914]  # جایگزین کنید با ID ادمین‌ها
        if user.id not in admin_ids:
            update.message.reply_text("❌ شما دسترسی به این command را ندارید.")
            return
        
        stats = self.user_stats.stats
        today = str(date.today())
        
        # محاسبه آمار امروز
        today_stats = stats['daily_stats'].get(today, {
            'new_users': 0,
            'total_actions': 0,
            'searches': 0
        })
        
        # محاسبه آمار هفته جاری
        week_ago = date.today().replace(day=date.today().day-7)
        weekly_stats = {
            'new_users': 0,
            'total_actions': 0,
            'searches': 0
        }
        
        for day in stats['daily_stats']:
            day_date = datetime.strptime(day, '%Y-%m-%d').date()
            if day_date >= week_ago:
                weekly_stats['new_users'] += stats['daily_stats'][day].get('new_users', 0)
                weekly_stats['total_actions'] += stats['daily_stats'][day].get('total_actions', 0)
                weekly_stats['searches'] += stats['daily_stats'][day].get('searches', 0)
        
        # محبوب‌ترین استان‌ها و شهرها
        top_provinces = sorted(stats['provinces'].items(), key=lambda x: x[1], reverse=True)[:5]
        top_cities = sorted(stats['cities'].items(), key=lambda x: x[1], reverse=True)[:5]
        
        message = """
📊 **آمار ربات املاک جامع**

👥 **آمار کاربران:**
• کاربران کل: {}
• کاربران فعال: {}
• کاربران جدید امروز: {}

📈 **آمار امروز:**
• اقدامات: {}
• جستجوها: {}

📅 **آمار هفته جاری:**
• کاربران جدید: {}
• اقدامات: {}
• جستجوها: {}

🏙️ **محبوب‌ترین استان‌ها:**
{}
    
🏘️ **محبوب‌ترین شهرها:**
{}
    """.format(
        stats['total_users'],
        len(stats['active_users']),
        today_stats['new_users'],
        today_stats['total_actions'],
        today_stats['searches'],
        weekly_stats['new_users'],
        weekly_stats['total_actions'],
        weekly_stats['searches'],
        "\n".join([f"• {prov}: {count}" for prov, count in top_provinces]),
        "\n".join([f"• {city}: {count}" for city, count in top_cities])
    )
        
        update.message.reply_text(message, parse_mode='Markdown')

    def detailed_stats_command(self, update: Update, context: CallbackContext):
        """آمار دقیق‌تر"""
        user = update.message.from_user
        admin_ids = [589435914]  # جایگزین کنید با ID ادمین‌ها
        
        if user.id not in admin_ids:
            update.message.reply_text("❌ شما دسترسی به این command را ندارید.")
            return
        
        stats = self.user_stats.stats
        
        # فعالیت‌های اخیر کاربران
        recent_activities = []
        user_actions = list(stats['user_actions'].items())
        for user_id, user_data in user_actions[-10:]:  # 10 کاربر آخر
            recent_activities.append(
                f"👤 {user_data.get('username', 'بدون نام')} - {user_data['total_actions']} اقدام"
            )
        
        message = """
📋 **آمار دقیق ربات**

🔢 **تعداد کاربران منحصر به فرد:** {}
📅 **روزهای فعال:** {}

📊 **10 کاربر اخیر:**
{}
    """.format(
        stats['total_users'],
        len(stats['daily_stats']),
        "\n".join(recent_activities) if recent_activities else "هیچ کاربری وجود ندارد"
    )
        
        update.message.reply_text(message, parse_mode='Markdown')

    def cancel(self, update, context):
        """لغو عملیات"""
        user = update.message.from_user
        logger.info("User %s canceled the conversation", user.id)
        
        # پاک کردن صفحات شهر کاربر
        user_id = update.effective_user.id
        if user_id in self.user_city_pages:
            del self.user_city_pages[user_id]
        
        update.message.reply_text(
            "عملیات لغو شد. برای شروع مجدد /start را ارسال کنید."
        )
        return ConversationHandler.END

    def error_handler(self, update, context):
        """مدیریت خطاهای全局"""
        logger.error("Exception while handling an update: %s", context.error, exc_info=context.error)
        
        try:
            # ارسال پیام خطا به کاربر
            if update and update.effective_message:
                update.effective_message.reply_text(
                    "❌ متأسفانه خطایی رخ داده است. لطفاً بعداً مجدداً تلاش کنید."
                )
        except Exception as e:
            logger.error("Error in error handler: %s", e)

def main():
    """تابع اصلی اجرای ربات"""
    # ایجاد پوشه logs اگر وجود ندارد
    if not os.path.exists('logs'):
        os.makedirs('logs')
    
    try:
        # ایجاد ربات
        bot = AmlakJameBot()
        
        # ایجاد updater
        updater = Updater(BOT_TOKEN, use_context=True)
        
        # دریافت dispatcher
        dp = updater.dispatcher
        
        # افزودن handler مدیریت خطا
        dp.add_error_handler(bot.error_handler)
        
        # افزودن دستورهای آمار
        dp.add_handler(CommandHandler("stats", bot.stats_command))
        dp.add_handler(CommandHandler("detailed_stats", bot.detailed_stats_command))
        
        # تعریف مکالمه اصلی
        conv_handler = ConversationHandler(
            entry_points=[CommandHandler('start', bot.start)],
            states={
                GET_PROVINCE: [
                    MessageHandler(Filters.text & ~Filters.command, bot.get_province)
                ],
                GET_CITY: [
                    MessageHandler(Filters.text & ~Filters.command, bot.get_city)
                ],
                ADVANCED_SEARCH: [
                    MessageHandler(Filters.text & ~Filters.command, bot.handle_advanced_search)
                ],
                VIEW_LISTINGS: [
                    MessageHandler(Filters.text & ~Filters.command, bot.handle_view_listings)
                ],
            },
            fallbacks=[CommandHandler('cancel', bot.cancel)],
        )
        
        dp.add_handler(conv_handler)
        
        # شروع ربات
        logger.info("🤖 ربات املاک جامع در حال راه‌اندازی...")
        print("🤖 ربات املاک جامع فعال شد...")
        print("🐍 Python Version: {}".format(sys.version.split()[0]))
        print("📦 python-telegram-bot Version: 13.15")
        print("🕒 Start Time: {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
        print("🔗 API Base URL: {}".format(API_BASE_URL))
        print("📍 سیستم صفحه‌بندی شهرها فعال شد")
        print("📊 سیستم آمار کاربران فعال شد")
        
        updater.start_polling()
        updater.idle()
        
    except Exception as e:
        logger.error("Failed to start bot: %s", e)
        print("❌ خطا در راه‌اندازی ربات: {}".format(e))

if __name__ == '__main__':
    main()