# ================================================================
# وبسایت نمایندگی تعمیرات دوو - نسخه نهایی کامل
# ================================================================

import os
import sys
import json
import hashlib
import secrets
from datetime import datetime, timedelta
from functools import wraps
from math import radians, sin, cos, sqrt, atan2

# ===== تنظیم encoding =====
try:
    reload(sys)
    sys.setdefaultencoding('utf-8')
except:

    pass

# ===== نصب خودکار کتابخانه‌ها =====
import subprocess
packages = [
    'flask', 'flask_sqlalchemy', 'werkzeug', 'jdatetime', 
    'requests', 'pillow', 'redis', 'celery', 'flask_migrate',
    'flask_caching', 'flask_limiter', 'flask_mail', 'flask_restx','faker','apscheduler'
]

for pkg in packages:
    try:
        __import__(pkg.replace('-', '_'))
    except (ImportError, ModuleNotFoundError):
        try:
            subprocess.check_call([
                sys.executable, '-m', 'pip', 'install', pkg,
                '--quiet', '--no-cache-dir', '--disable-pip-version-check'
            ], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
        except:
            pass

# ===== Import کتابخانه‌ها =====
from flask import Flask, render_template, request, redirect, url_for, flash, session, jsonify, abort, send_from_directory
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_caching import Cache
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from flask_mail import Mail, Message
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
from PIL import Image
import redis
import re
from flask import send_file

# ===== مقداردهی Flask =====
app = Flask(__name__)
app.secret_key = os.environ.get('SECRET_KEY', 'daewoo-tehran-super-secret-2024')

# ===== تنظیمات دیتابیس =====
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///daewoo_tehran.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_POOL_SIZE'] = 10
app.config['SQLALCHEMY_POOL_TIMEOUT'] = 30

# ===== تنظیمات کش =====
app.config['CACHE_TYPE'] = 'simple'
app.config['CACHE_DEFAULT_TIMEOUT'] = 300
cache = Cache(app)

# ===== تنظیمات Limiter =====
limiter = Limiter(
    key_func=get_remote_address,
    app=app,
    default_limits=["200 per day", "50 per hour"],
    storage_uri="memory://"  # برای رفع هشدار
)

# ===== تنظیمات آپلود =====
UPLOAD_FOLDER = 'static/uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'mp4', 'webm', 'mov', 'avi'}
MAX_CONTENT_LENGTH = 50 * 1024 * 1024  # 50MB
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = MAX_CONTENT_LENGTH

# ایجاد پوشه‌های لازم
for folder in ['categories', 'errors', 'seo', 'header', 'articles']:
    path = os.path.join(UPLOAD_FOLDER, folder)
    try:
        os.makedirs(path, exist_ok=True)
    except:
        pass
# ===== تنظیمات ایمیل =====
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME', '')
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD', '')
mail = Mail(app)

# ===== مقداردهی دیتابیس =====
db = SQLAlchemy(app)
migrate = Migrate(app, db)
# ============================================================
# امنیت و سئو - هدرهای امنیتی
# ============================================================
@app.after_request
def add_security_headers(response):
    response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains; preload'
    response.headers['Content-Security-Policy'] = (
        "default-src 'self'; "
        "script-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net unpkg.com cdnjs.cloudflare.com; "
        "style-src 'self' 'unsafe-inline' cdn.jsdelivr.net unpkg.com cdnjs.cloudflare.com fonts.googleapis.com; "
        "img-src 'self' data: https: img.freepik.com; "
        "font-src 'self' cdn.jsdelivr.net cdnjs.cloudflare.com fonts.gstatic.com; "
        "connect-src 'self' *.tile.openstreetmap.org; "
        "frame-src 'self' www.youtube.com www.google.com"
    )
    return response
# ================================================================
# ===== مدل‌های دیتابیس کامل =====
# ================================================================
# ================================================================
# ===== فیلتر nl2br برای Jinja2 =====
# ================================================================
@app.template_filter('escapejs')
def escapejs_filter(value):
    if value is None:
        return ''
    value = value.replace('\\', '\\\\')
    value = value.replace("'", "\\'")
    value = value.replace('"', '\\"')
    value = value.replace('\n', '\\n')
    value = value.replace('\r', '\\r')
    value = value.replace('\t', '\\t')
    return value
    
    
@app.template_filter('nl2br')
def nl2br_filter(value):
    """تبدیل خطوط جدید به تگ <br> در HTML"""
    if value is None:
        return ''
    # تبدیل \n به <br>
    return value.replace('\n', '<br>')
    
    
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    fullname = db.Column(db.String(100), nullable=False)
    phone = db.Column(db.String(15), unique=True, nullable=False, index=True)
    email = db.Column(db.String(100), unique=True, index=True)
    password = db.Column(db.String(200), nullable=False)
    role = db.Column(db.String(20), default='user', index=True)
    avatar = db.Column(db.String(200))
    wallet = db.Column(db.Float, default=0)
    wallet_credit = db.Column(db.Float, default=0)
    is_active = db.Column(db.Boolean, default=True)
    is_verified = db.Column(db.Boolean, default=False)
    verification_code = db.Column(db.String(10))
    last_login = db.Column(db.DateTime)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    transactions = db.relationship('WalletTransaction', backref='user', lazy='dynamic')
    bookings = db.relationship('Booking', backref='user', lazy='dynamic')
    reviews = db.relationship('Review', backref='user', lazy='dynamic')
    
    def get_wallet_balance(self):
        return self.wallet + self.wallet_credit
    
    def get_total_bookings(self):
        return self.bookings.count()
    
    def get_completed_bookings(self):
        return self.bookings.filter_by(status='completed').count()

class Setting(db.Model):
    __tablename__ = 'settings'
    id = db.Column(db.Integer, primary_key=True)
    key = db.Column(db.String(100), unique=True, nullable=False, index=True)
    value = db.Column(db.Text, nullable=False)
    category = db.Column(db.String(50), default='general')
    is_json = db.Column(db.Boolean, default=False)
    description = db.Column(db.String(200))
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    @classmethod
    def get(cls, key, default=None):
        s = cls.query.filter_by(key=key).first()
        if not s:
            return default
        if s.is_json:
            try:
                return json.loads(s.value)
            except:
                return default
        return s.value
    
    @classmethod
    def set(cls, key, value, category='general', description=''):
        s = cls.query.filter_by(key=key).first()
        if s:
            s.value = json.dumps(value) if isinstance(value, (dict, list)) else str(value)
            s.is_json = isinstance(value, (dict, list))
            s.category = category
            if description:
                s.description = description
        else:
            s = cls(
                key=key,
                value=json.dumps(value) if isinstance(value, (dict, list)) else str(value),
                is_json=isinstance(value, (dict, list)),
                category=category,
                description=description
            )
            db.session.add(s)
        db.session.commit()
        cache.delete(f'setting_{key}')
        return True
    
    @classmethod
    def get_all(cls, category=None):
        query = cls.query
        if category:
            query = query.filter_by(category=category)
        settings = {}
        for s in query.all():
            if s.is_json:
                try:
                    settings[s.key] = json.loads(s.value)
                except:
                    settings[s.key] = s.value
            else:
                settings[s.key] = s.value
        return settings


class TehranRegion(db.Model):
    __tablename__ = 'tehran_regions'
    id = db.Column(db.Integer, primary_key=True)
    region_number = db.Column(db.Integer, nullable=False, unique=True, index=True)
    name = db.Column(db.String(100), nullable=False)
    slug = db.Column(db.String(100), unique=True, nullable=False, index=True)
    description = db.Column(db.Text)
    latitude = db.Column(db.Float)
    longitude = db.Column(db.Float)
    zoom_level = db.Column(db.Integer, default=13)
    polygon_coords = db.Column(db.Text)
    population = db.Column(db.Integer)
    area_sqkm = db.Column(db.Float)
    districts = db.Column(db.Text)
    main_streets = db.Column(db.Text)
    landmarks = db.Column(db.Text)
    metro_stations = db.Column(db.Text)
    coverage_percentage = db.Column(db.Float, default=0)
    service_count = db.Column(db.Integer, default=0)
    review_count = db.Column(db.Integer, default=0)
    avg_rating = db.Column(db.Float, default=0)
    monthly_requests = db.Column(db.Integer, default=0)
    response_time = db.Column(db.Integer)
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    priority = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    # ===== روابط =====
    neighborhoods = db.relationship('TehranNeighborhood', backref='region', lazy='dynamic')
    technicians = db.relationship('Technician', secondary='technician_regions', backref='regions')
    
    # ===== متدها =====
    def get_districts(self):
        if self.districts:
            try:
                return json.loads(self.districts)
            except:
                return []
        return []
    
    def get_main_streets(self):
        if self.main_streets:
            try:
                return json.loads(self.main_streets)
            except:
                return []
        return []
    
    def get_landmarks(self):
        if self.landmarks:
            try:
                return json.loads(self.landmarks)
            except:
                return []
        return []
    
    def get_metro_stations(self):
        if self.metro_stations:
            try:
                return json.loads(self.metro_stations)
            except:
                return []
        return []
class TehranNeighborhood(db.Model):
    __tablename__ = 'tehran_neighborhoods'
    id = db.Column(db.Integer, primary_key=True)
    region_id = db.Column(db.Integer, db.ForeignKey('tehran_regions.id'), index=True)
    name = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False, index=True)
    alternative_names = db.Column(db.Text)
    latitude = db.Column(db.Float)
    longitude = db.Column(db.Float)
    main_streets = db.Column(db.Text)
    zip_codes = db.Column(db.String(200))
    landmarks = db.Column(db.Text)
    population = db.Column(db.Integer)
    is_covered = db.Column(db.Boolean, default=True)
    service_priority = db.Column(db.Integer, default=0)
    monthly_requests = db.Column(db.Integer, default=0)
    conversion_rate = db.Column(db.Float, default=0)
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)

class Technician(db.Model):
    __tablename__ = 'technicians'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), unique=True)
    fullname = db.Column(db.String(100), nullable=False)
    phone = db.Column(db.String(20), unique=True, nullable=False, index=True)
    national_code = db.Column(db.String(10), unique=True)
    expertise_areas = db.Column(db.Text)
    skill_level = db.Column(db.String(20), default='junior')
    experience_years = db.Column(db.Integer, default=0)
    certificate = db.Column(db.String(200))
    bio = db.Column(db.Text)
    avatar = db.Column(db.String(200))
    current_latitude = db.Column(db.Float)
    current_longitude = db.Column(db.Float)
    last_location_update = db.Column(db.DateTime)
    status = db.Column(db.String(20), default='available', index=True)
    rating = db.Column(db.Float, default=0)
    total_repairs = db.Column(db.Integer, default=0)
    success_rate = db.Column(db.Float, default=0)
    avg_response_time = db.Column(db.Integer)
    avg_arrival_time = db.Column(db.Integer)
    work_hours_start = db.Column(db.Time)
    work_hours_end = db.Column(db.Time)
    work_days = db.Column(db.String(50))
    max_daily_jobs = db.Column(db.Integer, default=5)
    current_jobs = db.Column(db.Integer, default=0)
    base_salary = db.Column(db.Float, default=0)
    commission_percentage = db.Column(db.Float, default=30)
    is_active = db.Column(db.Boolean, default=True)
    is_verified = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    bookings = db.relationship('Booking', backref='technician', lazy='dynamic')
    reviews = db.relationship('Review', backref='technician', lazy='dynamic')
    
    def get_available_services(self):
        if self.expertise_areas:
            return json.loads(self.expertise_areas)
        return []
    
    def calculate_distance_to(self, lat, lng):
        if not self.current_latitude or not self.current_longitude:
            return None
        R = 6371
        lat1, lon1 = radians(self.current_latitude), radians(self.current_longitude)
        lat2, lon2 = radians(lat), radians(lng)
        dlat = lat2 - lat1
        dlon = lon2 - lon1
        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * atan2(sqrt(a), sqrt(1-a))
        return R * c

technician_regions = db.Table('technician_regions',
    db.Column('technician_id', db.Integer, db.ForeignKey('technicians.id'), primary_key=True),
    db.Column('region_id', db.Integer, db.ForeignKey('tehran_regions.id'), primary_key=True)
)

class Service(db.Model):
    __tablename__ = 'services'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False, index=True)
    category = db.Column(db.String(50), index=True)
    sub_category = db.Column(db.String(50))
    description = db.Column(db.Text)
    short_description = db.Column(db.String(300))
    icon = db.Column(db.String(50), default='fa-solid fa-wrench')
    image = db.Column(db.String(200))
    thumbnail = db.Column(db.String(200))
    price_range_min = db.Column(db.Float)
    price_range_max = db.Column(db.Float)
    estimated_time = db.Column(db.Integer)
    is_popular = db.Column(db.Boolean, default=False)
    is_active = db.Column(db.Boolean, default=True)
    order = db.Column(db.Integer, default=0)
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    details = db.relationship('ServiceDetail', backref='service', lazy='dynamic')
    faqs = db.relationship('ServiceFAQ', backref='service', lazy='dynamic')
    bookings = db.relationship('Booking', backref='service', lazy='dynamic')
    
    def get_avg_price(self):
        if self.price_range_min and self.price_range_max:
            return (self.price_range_min + self.price_range_max) / 2
        return None

class ServiceDetail(db.Model):
    __tablename__ = 'service_details'
    id = db.Column(db.Integer, primary_key=True)
    service_id = db.Column(db.Integer, db.ForeignKey('services.id'), index=True)
    problem_title = db.Column(db.String(200), nullable=False)
    problem_description = db.Column(db.Text)
    solution = db.Column(db.Text)
    price = db.Column(db.String(100))
    estimated_time = db.Column(db.Integer)
    difficulty = db.Column(db.String(20))
    order = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)

class ServiceFAQ(db.Model):
    __tablename__ = 'service_faqs'
    id = db.Column(db.Integer, primary_key=True)
    service_id = db.Column(db.Integer, db.ForeignKey('services.id'), index=True)
    question = db.Column(db.String(300), nullable=False)
    answer = db.Column(db.Text, nullable=False)
    order = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)

class Article(db.Model):
    __tablename__ = 'articles'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False, index=True)
    category = db.Column(db.String(100), index=True)
    sub_category = db.Column(db.String(100))
    summary = db.Column(db.String(300))
    content = db.Column(db.Text)
    image = db.Column(db.String(200))
    thumbnail = db.Column(db.String(200))
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    view_count = db.Column(db.Integer, default=0)
    like_count = db.Column(db.Integer, default=0)
    comment_count = db.Column(db.Integer, default=0)
    reading_time = db.Column(db.Integer)
    is_featured = db.Column(db.Boolean, default=False)
    is_active = db.Column(db.Boolean, default=True)
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    published_at = db.Column(db.DateTime, default=datetime.now)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    author = db.relationship('User', backref='articles')
    comments = db.relationship('ArticleComment', backref='article', lazy='dynamic')
    
    def get_reading_time(self):
        if self.content:
            words = len(self.content.split())
            return max(1, words // 200)
        return 1

class Testimonial(db.Model):
    __tablename__ = 'testimonials'
    id = db.Column(db.Integer, primary_key=True)
    customer_name = db.Column(db.String(100), nullable=False)
    customer_location = db.Column(db.String(100))
    text = db.Column(db.Text, nullable=False)
    rating = db.Column(db.Integer, default=5)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
class ArticleComment(db.Model):
    __tablename__ = 'article_comments'
    id = db.Column(db.Integer, primary_key=True)
    article_id = db.Column(db.Integer, db.ForeignKey('articles.id'), index=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))  # <-- این باید باشه
    parent_id = db.Column(db.Integer, db.ForeignKey('article_comments.id'))
    content = db.Column(db.Text, nullable=False)
    is_approved = db.Column(db.Boolean, default=False)
    like_count = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.now)
    
    # ===== روابط =====
    user = db.relationship('User', backref='article_comments')  # <-- این رو اضافه کن
    replies = db.relationship('ArticleComment', backref=db.backref('parent', remote_side=[id]))
class FAQ(db.Model):
    __tablename__ = 'faqs'
    id = db.Column(db.Integer, primary_key=True)
    category = db.Column(db.String(100), index=True)
    question = db.Column(db.String(300), nullable=False)
    answer = db.Column(db.Text, nullable=False)
    order = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)

class Review(db.Model):
    __tablename__ = 'reviews'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    technician_id = db.Column(db.Integer, db.ForeignKey('technicians.id'), index=True)
    service_id = db.Column(db.Integer, db.ForeignKey('services.id'), index=True)
    booking_id = db.Column(db.Integer, db.ForeignKey('bookings.id'), unique=True)
    rating = db.Column(db.Integer, nullable=False)
    title = db.Column(db.String(200))
    content = db.Column(db.Text)
    images = db.Column(db.Text)
    video = db.Column(db.String(200))
    likes = db.Column(db.Integer, default=0)
    dislikes = db.Column(db.Integer, default=0)
    is_verified = db.Column(db.Boolean, default=False)
    is_approved = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    
    booking = db.relationship('Booking', backref='review')

class Booking(db.Model):
    __tablename__ = 'bookings'
    id = db.Column(db.Integer, primary_key=True)
    booking_number = db.Column(db.String(20), unique=True, nullable=False, index=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    technician_id = db.Column(db.Integer, db.ForeignKey('technicians.id'), index=True)
    service_id = db.Column(db.Integer, db.ForeignKey('services.id'), index=True)
    region_id = db.Column(db.Integer, db.ForeignKey('tehran_regions.id'), index=True)
    neighborhood_id = db.Column(db.Integer, db.ForeignKey('tehran_neighborhoods.id'))
    
    address = db.Column(db.Text, nullable=False)
    latitude = db.Column(db.Float)
    longitude = db.Column(db.Float)
    
    scheduled_date = db.Column(db.Date, nullable=False)
    scheduled_time = db.Column(db.Time, nullable=False)
    estimated_arrival = db.Column(db.DateTime)
    actual_arrival = db.Column(db.DateTime)
    start_time = db.Column(db.DateTime)
    end_time = db.Column(db.DateTime)
    
    status = db.Column(db.String(30), default='pending', index=True)
    payment_status = db.Column(db.String(20), default='pending')
    payment_method = db.Column(db.String(20))
    
    description = db.Column(db.Text)
    special_instructions = db.Column(db.Text)
    is_emergency = db.Column(db.Boolean, default=False)
    is_home_service = db.Column(db.Boolean, default=True)
    
    estimated_price = db.Column(db.Float)
    final_price = db.Column(db.Float)
    discount = db.Column(db.Float, default=0)
    tax = db.Column(db.Float, default=0)
    
    technician_notes = db.Column(db.Text)
    admin_notes = db.Column(db.Text)
    
    cancelled_by = db.Column(db.String(20))
    cancelled_reason = db.Column(db.Text)
    
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    notifications = db.relationship('Notification', backref='booking', lazy='dynamic')
    
    def generate_booking_number(self):
        import random
        timestamp = datetime.now().strftime('%y%m%d')
        random_num = ''.join([str(random.randint(0, 9)) for _ in range(4)])
        return f"DW{timestamp}{random_num}"
    
    def get_status_color(self):
        colors = {
            'pending': 'warning',
            'confirmed': 'info',
            'on_way': 'primary',
            'arrived': 'info',
            'in_progress': 'success',
            'completed': 'success',
            'cancelled': 'danger',
            'rejected': 'danger'
        }
        return colors.get(self.status, 'secondary')

class WalletTransaction(db.Model):
    __tablename__ = 'wallet_transactions'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    booking_id = db.Column(db.Integer, db.ForeignKey('bookings.id'), index=True)
    amount = db.Column(db.Float, nullable=False)
    type = db.Column(db.String(20), nullable=False, index=True)
    status = db.Column(db.String(20), default='pending')
    description = db.Column(db.String(500))
    reference_id = db.Column(db.String(100))
    balance_before = db.Column(db.Float, default=0)
    balance_after = db.Column(db.Float, default=0)
    meta_data = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.now)
    completed_at = db.Column(db.DateTime)
    
    booking = db.relationship('Booking', backref='transactions')

class Notification(db.Model):
    __tablename__ = 'notifications'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    booking_id = db.Column(db.Integer, db.ForeignKey('bookings.id'), index=True)
    type = db.Column(db.String(50), nullable=False, index=True)
    title = db.Column(db.String(200), nullable=False)
    message = db.Column(db.Text, nullable=False)
    link = db.Column(db.String(500))
    is_read = db.Column(db.Boolean, default=False)
    is_sent = db.Column(db.Boolean, default=False)
    sent_at = db.Column(db.DateTime)
    created_at = db.Column(db.DateTime, default=datetime.now)
    
    user = db.relationship('User', backref='notifications')

class MediaGallery(db.Model):
    __tablename__ = 'media_gallery'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200))
    description = db.Column(db.Text)
    file_path = db.Column(db.String(500), nullable=False)
    file_name = db.Column(db.String(200))
    file_type = db.Column(db.String(50))
    file_size = db.Column(db.Integer)
    mime_type = db.Column(db.String(100))
    width = db.Column(db.Integer)
    height = db.Column(db.Integer)
    alt_text = db.Column(db.String(200))
    caption = db.Column(db.String(300))
    category = db.Column(db.String(100), index=True)
    tags = db.Column(db.String(500))
    is_featured = db.Column(db.Boolean, default=False)
    is_active = db.Column(db.Boolean, default=True)
    sort_order = db.Column(db.Integer, default=0)
    usage_count = db.Column(db.Integer, default=0)
    uploaded_by = db.Column(db.Integer, db.ForeignKey('users.id'))
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)

class KeywordBank(db.Model):
    __tablename__ = 'keyword_bank'
    id = db.Column(db.Integer, primary_key=True)
    keyword = db.Column(db.String(200), unique=True, nullable=False, index=True)
    category = db.Column(db.String(100), index=True)
    sub_category = db.Column(db.String(100))
    search_volume = db.Column(db.Integer, default=0)
    competition = db.Column(db.Float, default=0.0)
    cpc = db.Column(db.Float, default=0.0)
    suggested_price = db.Column(db.Float, default=0.0)
    priority = db.Column(db.Integer, default=0)
    difficulty = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    is_targeted = db.Column(db.Boolean, default=False)
    serp_position = db.Column(db.Integer)
    related_keywords = db.Column(db.Text)
    last_checked = db.Column(db.DateTime)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    contents = db.relationship('KeywordContent', backref='keyword', lazy='dynamic')

class KeywordContent(db.Model):
    __tablename__ = 'keyword_contents'
    id = db.Column(db.Integer, primary_key=True)
    keyword_id = db.Column(db.Integer, db.ForeignKey('keyword_bank.id'), index=True)
    content_type = db.Column(db.String(50), index=True)
    content_id = db.Column(db.Integer, index=True)
    relevance_score = db.Column(db.Float, default=0.0)
    is_primary = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.now)

class DynamicContent(db.Model):
    __tablename__ = 'dynamic_contents'
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(50), nullable=False, index=True)
    template_id = db.Column(db.Integer, db.ForeignKey('content_templates.id'))
    region_id = db.Column(db.Integer, db.ForeignKey('tehran_regions.id'))
    neighborhood_id = db.Column(db.Integer, db.ForeignKey('tehran_neighborhoods.id'))
    service_id = db.Column(db.Integer, db.ForeignKey('services.id'))
    
    title = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False, index=True)
    content = db.Column(db.Text)
    summary = db.Column(db.String(500))
    
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    
    variables = db.Column(db.Text)
    meta_data = db.Column(db.Text)
    
    views = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    is_auto_generated = db.Column(db.Boolean, default=False)
    generated_by = db.Column(db.String(50))
    
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    template = db.relationship('ContentTemplate', backref='contents')
    region = db.relationship('TehranRegion', backref='dynamic_contents')
    neighborhood = db.relationship('TehranNeighborhood', backref='dynamic_contents')
    service = db.relationship('Service', backref='dynamic_contents')

class ContentTemplate(db.Model):
    __tablename__ = 'content_templates'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    type = db.Column(db.String(50), nullable=False, index=True)
    template_content = db.Column(db.Text, nullable=False)
    variables_schema = db.Column(db.Text)
    is_active = db.Column(db.Boolean, default=True)
    is_default = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)

class SystemLog(db.Model):
    __tablename__ = 'system_logs'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    action = db.Column(db.String(50), nullable=False, index=True)
    module = db.Column(db.String(50), index=True)
    description = db.Column(db.Text)
    ip_address = db.Column(db.String(50))
    user_agent = db.Column(db.String(500))
    old_data = db.Column(db.Text)
    new_data = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.now, index=True)

class AnalyticsUser(db.Model):
    __tablename__ = 'analytics_users'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    session_id = db.Column(db.String(100), index=True)
    ip_address = db.Column(db.String(50))
    user_agent = db.Column(db.String(500))
    referrer = db.Column(db.String(500))
    landing_page = db.Column(db.String(500))
    device_type = db.Column(db.String(50))
    browser = db.Column(db.String(100))
    os = db.Column(db.String(100))
    screen_resolution = db.Column(db.String(50))
    location_city = db.Column(db.String(100))
    location_region = db.Column(db.String(100))
    is_new_visitor = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    last_activity = db.Column(db.DateTime, default=datetime.now)

class UserSession(db.Model):
    __tablename__ = 'user_sessions'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    session_id = db.Column(db.String(100), unique=True, nullable=False, index=True)
    ip_address = db.Column(db.String(50))
    user_agent = db.Column(db.String(500))
    login_time = db.Column(db.DateTime, default=datetime.now)
    logout_time = db.Column(db.DateTime)
    is_active = db.Column(db.Boolean, default=True)
    device_info = db.Column(db.Text)

class Region(db.Model):
    __tablename__ = 'regions'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    slug = db.Column(db.String(100), unique=True, nullable=False, index=True)
    latitude = db.Column(db.Float)
    longitude = db.Column(db.Float)
    zoom = db.Column(db.Integer, default=13)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    
class DynamicPricing(db.Model):
    __tablename__ = 'dynamic_pricing'
    id = db.Column(db.Integer, primary_key=True)
    service_id = db.Column(db.Integer, db.ForeignKey('services.id'), index=True)
    region_id = db.Column(db.Integer, db.ForeignKey('tehran_regions.id'), index=True)
    base_price = db.Column(db.Float, nullable=False)
    peak_hour_multiplier = db.Column(db.Float, default=1.0)
    off_peak_multiplier = db.Column(db.Float, default=1.0)
    emergency_multiplier = db.Column(db.Float, default=1.5)
    weekend_multiplier = db.Column(db.Float, default=1.2)
    holiday_multiplier = db.Column(db.Float, default=1.3)
    distance_charge_per_km = db.Column(db.Float, default=5000)
    min_distance_charge = db.Column(db.Float, default=0)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    service = db.relationship('Service', backref='pricings')
    region = db.relationship('TehranRegion', backref='pricings')


# ================================================================
# ===== مدل‌های جدید برای سیستم خطاها و سئو =====
# ================================================================

class ErrorCategory(db.Model):
    """دسته‌بندی خطاها (بر اساس وسیله)"""
    __tablename__ = 'error_categories'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False, unique=True)
    slug = db.Column(db.String(100), unique=True, nullable=False)
    icon = db.Column(db.String(50), default='fa-solid fa-wrench')
    image = db.Column(db.String(200))
    description = db.Column(db.Text)
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    is_active = db.Column(db.Boolean, default=True)
    sort_order = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    errors = db.relationship('ErrorSolution', backref='category', lazy='dynamic')


class ErrorSolution(db.Model):
    """راه‌حل‌های خطاها"""
    __tablename__ = 'error_solutions'
    id = db.Column(db.Integer, primary_key=True)
    category_id = db.Column(db.Integer, db.ForeignKey('error_categories.id'), index=True)
    
    error_code = db.Column(db.String(50))
    error_title = db.Column(db.String(200), nullable=False)
    error_description = db.Column(db.Text, nullable=False)
    symptoms = db.Column(db.Text)
    solution_steps = db.Column(db.Text)
    video_url = db.Column(db.String(500))
    video_embed = db.Column(db.Text)
    
    main_image = db.Column(db.String(200))
    additional_images = db.Column(db.Text)
    
    difficulty_level = db.Column(db.String(20), default='medium')
    estimated_time = db.Column(db.Integer)
    tools_needed = db.Column(db.Text)
    can_self_fix = db.Column(db.Boolean, default=True)
    
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    slug = db.Column(db.String(200), unique=True, nullable=False)
    
    view_count = db.Column(db.Integer, default=0)
    helpful_count = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    is_featured = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    def get_additional_images(self):
        if self.additional_images:
            try:
                return json.loads(self.additional_images)
            except:
                return []
        return []
    
    def get_tools_list(self):
        if self.tools_needed:
            try:
                return json.loads(self.tools_needed)
            except:
                return [t.strip() for t in self.tools_needed.split(',')]
        return []


class SEOPage(db.Model):
    """صفحات سئو شده از کلمات کلیدی"""
    __tablename__ = 'seo_pages'
    id = db.Column(db.Integer, primary_key=True)
    keyword_id = db.Column(db.Integer, db.ForeignKey('keyword_bank.id'), unique=True, index=True)
    
    title = db.Column(db.String(200), nullable=False)
    slug = db.Column(db.String(200), unique=True, nullable=False, index=True)
    content = db.Column(db.Text, nullable=False)
    summary = db.Column(db.String(500))
    
    main_image = db.Column(db.String(200))
    additional_images = db.Column(db.Text)
    
    seo_title = db.Column(db.String(200))
    seo_description = db.Column(db.String(500))
    seo_keywords = db.Column(db.String(500))
    
    meta_data = db.Column(db.Text)
    view_count = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    is_auto_generated = db.Column(db.Boolean, default=False)
    last_updated = db.Column(db.DateTime, default=datetime.now)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
    
    keyword = db.relationship('KeywordBank', backref='seo_page')
    
    def get_additional_images(self):
        if self.additional_images:
            try:
                return json.loads(self.additional_images)
            except:
                return []
        return []
    
    def get_meta_data(self):
        if self.meta_data:
            try:
                return json.loads(self.meta_data)
            except:
                return {}
        return {}


class SiteHeaderImage(db.Model):
    """تصاویر هدر سایت"""
    __tablename__ = 'site_header_images'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200))
    image_path = db.Column(db.String(500), nullable=False)
    alt_text = db.Column(db.String(200))
    link_url = db.Column(db.String(500))
    is_active = db.Column(db.Boolean, default=True)
    is_default = db.Column(db.Boolean, default=False)
    sort_order = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.now)
    updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)


class InternalLink(db.Model):
    """لینک‌سازی داخلی خودکار"""
    __tablename__ = 'internal_links'
    id = db.Column(db.Integer, primary_key=True)
    source_page = db.Column(db.String(200))
    target_page = db.Column(db.String(200))
    anchor_text = db.Column(db.String(100))
    link_type = db.Column(db.String(50))
    is_auto_generated = db.Column(db.Boolean, default=True)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.now)
    
# ================================================================
# ===== دکوریتورها و توابع کمکی =====
# ================================================================
# ================================================================
# ===== فیلترهای Jinja2 =====
# ================================================================

@app.template_filter('persian_numbers')
def persian_numbers_filter(value):
    """تبدیل اعداد انگلیسی به فارسی - فیلتر Jinja2"""
    import jdatetime
    if value is None:
        return '۰'
    try:
        if isinstance(value, (int, float)):
            num = int(value)
        else:
            try:
                num = int(float(str(value).replace(',', '')))
            except:
                return str(value)
    except:
        return str(value)
    
    persian = {'0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
               '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'}
    return str(num).translate(str.maketrans(persian))

@app.template_filter('persian_date')
def persian_date_filter(value):
    """تبدیل تاریخ میلادی به شمسی - فیلتر Jinja2"""
    from datetime import datetime
    import jdatetime
    if not value:
        return ''
    try:
        if isinstance(value, str):
            try:
                value = datetime.strptime(value, '%Y-%m-%d')
            except:
                return value
        j = jdatetime.datetime.fromgregorian(datetime=value)
        months = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 
                  'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
        return f"{j.day} {months[j.month-1]} {j.year}"
    except:
        return str(value) if value else ''

# ================================================================
# ===== Context Processor برای تمام تمپلیت‌ها =====
# ================================================================
# ================================================================
# ===== 1. دیکشنری ترجمه دسته‌بندی کلمات کلیدی (جدید) =====
# ================================================================

# ================================================================
# ===== فیلتر تبدیل تاریخ شمسی به میلادی برای ورودی =====
# ================================================================

@app.template_filter('persian_date_input')
def persian_date_input_filter(value):
    """تبدیل تاریخ میلادی به شمسی برای نمایش در input date"""
    if not value:
        return ''
    try:
        import jdatetime
        if isinstance(value, str):
            from datetime import datetime
            try:
                value = datetime.strptime(value, '%Y-%m-%d')
            except:
                return value
        j = jdatetime.datetime.fromgregorian(datetime=value)
        return f"{j.year}-{j.month:02d}-{j.day:02d}"
    except:
        return str(value) if value else ''
        
@app.template_filter('persian_date_display')
def persian_date_display_filter(value):
    """تبدیل تاریخ میلادی به شمسی برای نمایش"""
    if not value:
        return ''
    try:
        import jdatetime
        if isinstance(value, str):
            from datetime import datetime
            try:
                value = datetime.strptime(value, '%Y-%m-%d')
            except:
                return value
        j = jdatetime.datetime.fromgregorian(datetime=value)
        months = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 
                  'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
        return f"{j.day} {months[j.month-1]} {j.year}"
    except:
        return str(value) if value else ''
def login_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if 'user_id' not in session:
            flash('لطفاً وارد شوید.', 'warning')
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated
def admin_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if 'user_id' not in session:
            flash('لطفاً وارد شوید.', 'warning')
            return redirect(url_for('login'))
        user = User.query.get(session['user_id'])
        if not user or user.role != 'admin':
            flash('دسترسی غیرمجاز!', 'danger')
            return redirect(url_for('index'))
        return f(*args, **kwargs)
    return decorated

def technician_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if 'user_id' not in session:
            flash('لطفاً وارد شوید.', 'warning')
            return redirect(url_for('login'))
        user = User.query.get(session['user_id'])
        if not user or user.role not in ['admin', 'technician']:
            flash('دسترسی غیرمجاز!', 'danger')
            return redirect(url_for('index'))
        return f(*args, **kwargs)
    return decorated

def api_response(success=True, data=None, message='', status_code=200):
    return jsonify({
        'success': success,
        'data': data,
        'message': message,
        'timestamp': datetime.now().isoformat()
    }), status_code

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def generate_unique_slug(text, model, slug_field='slug'):
    """تولید اسلاگ یکتا به صورت فینگلیش برای هر مدل"""
    import re
    
    # تبدیل به فینگلیش
    slug = persian_to_finglish(text)
    
    # اگر خالی شد، از کلمه پیش‌فرض استفاده کن
    if not slug:
        slug = 'item'
    
    # محدود کردن طول
    if len(slug) > 100:
        slug = slug[:100]
    
    original_slug = slug
    counter = 1
    
    while True:
        exists = model.query.filter(getattr(model, slug_field) == slug).first()
        if not exists:
            return slug
        slug = f"{original_slug}-{counter}"
        counter += 1


def get_client_ip():
    if request.headers.get('X-Forwarded-For'):
        return request.headers.get('X-Forwarded-For').split(',')[0]
    return request.remote_addr

def calculate_distance(lat1, lon1, lat2, lon2):
    R = 6371
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * atan2(sqrt(a), sqrt(1-a))
    return R * c

# ================================================================
# ===== توابع کیف پول =====
# ================================================================

def add_to_wallet(user_id, amount, description, reference_id=None, metadata=None):
    user = User.query.get(user_id)
    if not user:
        return False
    
    balance_before = user.wallet
    user.wallet += amount
    db.session.commit()
    
    transaction = WalletTransaction(
        user_id=user_id,
        amount=amount,
        type='deposit',
        status='completed',
        description=description,
        reference_id=reference_id,
        balance_before=balance_before,
        balance_after=user.wallet,
        meta_data=json.dumps(metadata) if metadata else None,
        completed_at=datetime.now()
    )
    db.session.add(transaction)
    db.session.commit()
    
    return True

def deduct_from_wallet(user_id, amount, description, reference_id=None, metadata=None):
    user = User.query.get(user_id)
    if not user or user.wallet < amount:
        return False
    
    balance_before = user.wallet
    user.wallet -= amount
    db.session.commit()
    
    transaction = WalletTransaction(
        user_id=user_id,
        amount=-amount,
        type='payment',
        status='completed',
        description=description,
        reference_id=reference_id,
        balance_before=balance_before,
        balance_after=user.wallet,
        meta_data=json.dumps(metadata) if metadata else None,
        completed_at=datetime.now()
    )
    db.session.add(transaction)
    db.session.commit()
    
    return True

def get_wallet_transactions(user_id, limit=50):
    return WalletTransaction.query.filter_by(user_id=user_id)\
        .order_by(WalletTransaction.created_at.desc())\
        .limit(limit).all()

# ================================================================
# ===== توابع اعلان =====
# ================================================================

def send_notification(user_id, type, title, message, link=None, booking_id=None):
    notification = Notification(
        user_id=user_id,
        type=type,
        title=title,
        message=message,
        link=link,
        booking_id=booking_id,
        is_read=False,
        is_sent=True,
        sent_at=datetime.now()
    )
    db.session.add(notification)
    db.session.commit()
    return True

def get_user_notifications(user_id, limit=20):
    return Notification.query.filter_by(user_id=user_id)\
        .order_by(Notification.created_at.desc())\
        .limit(limit).all()

# ================================================================
# ===== توابع مدیریت محتوای پویا =====
# ================================================================

def generate_dynamic_content(content_type, data):
    template = ContentTemplate.query.filter_by(type=content_type, is_default=True).first()
    if not template:
        return None
    
    from jinja2 import Template
    jinja_template = Template(template.template_content)
    
    try:
        rendered_content = jinja_template.render(**data)
    except Exception as e:
        return None
    
    content = DynamicContent(
        type=content_type,
        template_id=template.id,
        title=data.get('title', ''),
        content=rendered_content,
        variables=json.dumps(data),
        is_auto_generated=True,
        generated_by='system'
    )
    db.session.add(content)
    db.session.commit()
    
    return content
def create_region_content(region_id):
    region = TehranRegion.query.get(region_id)
    if not region:
        return None
    
    services = Service.query.filter_by(is_active=True).all()
    technicians = Technician.query.filter(
        Technician.regions.any(id=region_id),
        Technician.is_active == True
    ).all()
    
    # تبدیل region به دیکشنری
    region_dict = {
        'id': region.id,
        'name': region.name,
        'slug': region.slug,
        'region_number': region.region_number,
        'latitude': region.latitude,
        'longitude': region.longitude,
        'description': region.description,
        'coverage_percentage': region.coverage_percentage
    }
    
    data = {
        'title': f"تعمیرات دوو در {region.name}",
        'region': region_dict,  # <-- دیکشنری
        'services': services[:6],
        'technicians': technicians[:3],
        'region_number': region.region_number,
        'districts': region.get_districts()[:5],
        'streets': region.get_main_streets()[:5]
    }
    
    return generate_dynamic_content('region_page', data)

# ================================================================
# ===== توابع مدیریت تکنسین =====
# ================================================================

def find_nearest_technician(latitude, longitude, service_id=None):
    technicians = Technician.query.filter_by(status='available', is_active=True).all()
    
    if not technicians:
        return None
    
    nearest = None
    min_distance = float('inf')
    
    for tech in technicians:
        if tech.current_latitude and tech.current_longitude:
            distance = calculate_distance(
                latitude, longitude,
                tech.current_latitude, tech.current_longitude
            )
            if distance < min_distance:
                min_distance = distance
                nearest = tech
    
    return nearest

def assign_technician_to_booking(booking_id):
    booking = Booking.query.get(booking_id)
    if not booking:
        return False
    
    technician = find_nearest_technician(booking.latitude, booking.longitude, booking.service_id)
    if not technician:
        return False
    
    booking.technician_id = technician.id
    booking.status = 'confirmed'
    technician.status = 'busy'
    technician.current_jobs += 1
    db.session.commit()
    
    send_notification(
        booking.user_id,
        'booking',
        'تکنسین به شما اختصاص داده شد',
        f'تکنسین {technician.fullname} به درخواست شما اختصاص داده شد.',
        url_for('booking_detail', booking_id=booking.id),
        booking.id
    )
    
    return True

# ================================================================
# ===== توابع مدیریت خطاها و سئو =====
# ================================================================

# ================================================================
# ===== تبدیل فارسی به فینگلیش =====
# ================================================================


def persian_to_finglish(text):
    """تبدیل متن فارسی به فینگلیش (حروف انگلیسی)"""
    mapping = {
        'آ': 'a', 'ا': 'a', 'أ': 'a', 'إ': 'a',
        'ب': 'b', 'پ': 'p', 'ت': 't', 'ث': 's',
        'ج': 'j', 'چ': 'ch', 'ح': 'h', 'خ': 'kh',
        'د': 'd', 'ذ': 'z', 'ر': 'r', 'ز': 'z',
        'ژ': 'zh', 'س': 's', 'ش': 'sh', 'ص': 's',
        'ض': 'z', 'ط': 't', 'ظ': 'z', 'ع': 'a',
        'غ': 'gh', 'ف': 'f', 'ق': 'gh', 'ک': 'k',
        'گ': 'g', 'ل': 'l', 'م': 'm', 'ن': 'n',
        'و': 'v', 'ه': 'h', 'ی': 'y', 'ئ': 'e',
        'ء': '', 'ّ': '', 'َ': '', 'ُ': '',
        'ِ': '', 'ٌ': '', 'ٍ': '', 'ً': '',
        '۰': '0', '۱': '1', '۲': '2', '۳': '3',
        '۴': '4', '۵': '5', '۶': '6', '۷': '7',
        '۸': '8', '۹': '9'
    }
    
    result = []
    for char in text:
        if char in mapping:
            result.append(mapping[char])
        elif char.isalnum() or char in ['-', '_', ' ']:
            result.append(char.lower())
    
    result_str = ''.join(result)
    result_str = re.sub(r'\s+', '-', result_str)
    result_str = re.sub(r'-+', '-', result_str)
    result_str = result_str.strip('-')
    
    return result_str

def generate_error_slug(title, category_name):
    """تولید اسلاگ به صورت فینگلیش برای خطاها (با یکتاسازی)"""
    import re
    from sqlalchemy import func
    
    # تبدیل به فینگلیش
    title_finglish = persian_to_finglish(title)
    category_finglish = persian_to_finglish(category_name)
    
    # اگر عنوان یا دسته خالی بود
    if not title_finglish:
        title_finglish = "error"
    if not category_finglish:
        category_finglish = "unknown"
    
    slug = f"{category_finglish}-{title_finglish}"
    
    # حذف کاراکترهای غیرمجاز
    slug = re.sub(r'[^a-z0-9-]', '', slug)
    slug = re.sub(r'-+', '-', slug)
    slug = slug.strip('-')
    
    # اگر اسلاگ خالی شد
    if not slug:
        slug = f"error-{datetime.now().strftime('%Y%m%d%H%M%S')}"
    
    # محدود کردن طول
    if len(slug) > 100:
        slug = slug[:100]
    
    # یکتاسازی با شمارنده
    original_slug = slug
    counter = 1
    while True:
        exists = ErrorSolution.query.filter_by(slug=slug).first()
        if not exists:
            return slug
        # اگر تکراری بود، عدد به انتها اضافه می‌شود
        slug = f"{original_slug}-{counter}"
        counter += 1
        
def get_error_solutions_by_category(category_slug, limit=10):
    """دریافت راه‌حل‌های خطا بر اساس دسته‌بندی"""
    category = ErrorCategory.query.filter_by(slug=category_slug, is_active=True).first()
    if not category:
        return []
    return ErrorSolution.query.filter_by(
        category_id=category.id,
        is_active=True
    ).order_by(ErrorSolution.view_count.desc()).limit(limit).all()


def get_self_fixable_errors():
    """دریافت خطاهایی که کاربر می‌تواند خودش رفع کند"""
    return ErrorSolution.query.filter_by(
        is_active=True,
        can_self_fix=True
    ).all()


def create_seo_page_from_keyword(keyword_id):
    """ایجاد صفحه سئو شده از کلمه کلیدی با اسلاگ فینگلیش"""
    keyword = KeywordBank.query.get(keyword_id)
    if not keyword or not keyword.is_active:
        return None
    
    existing = SEOPage.query.filter_by(keyword_id=keyword_id).first()
    if existing:
        return existing
    
    # ===== تولید اسلاگ فینگلیش از کلمه کلیدی =====
    slug = persian_to_finglish(keyword.keyword)
    # اگر خالی شد، از id استفاده کن
    if not slug:
        slug = f"repair-{keyword.id}"
    # محدود کردن طول
    if len(slug) > 100:
        slug = slug[:100]
    
    # ===== قالب محتوا =====
    template = """
    <h1>{title}</h1>
    
    <p>{description}</p>
    
    <h2>خدمات مرتبط با {keyword}</h2>
    <ul>
        {services_list}
    </ul>
    
    <h2>مناطق تحت پوشش</h2>
    <ul>
        {regions_list}
    </ul>
    
    <h2>سوالات متداول</h2>
    <div class="faq-section">
        {faqs_list}
    </div>
    
    <h2>چرا ما را انتخاب کنید؟</h2>
    <ul>
        <li>تکنسین‌های مجرب و حرفه‌ای</li>
        <li>ضمانت کیفیت خدمات</li>
        <li>قیمت‌های مناسب و رقابتی</li>
        <li>خدمات در تمام مناطق تهران</li>
    </ul>
    """
    
    services = Service.query.filter_by(is_active=True).limit(5).all()
    regions = TehranRegion.query.filter_by(is_active=True).limit(5).all()
    faqs = FAQ.query.filter_by(is_active=True).limit(5).all()
    
    services_list = ''.join([f'<li><a href="/service/{s.id}">{s.title}</a></li>' for s in services])
    regions_list = ''.join([f'<li><a href="/region/{r.slug}">{r.name}</a></li>' for r in regions])
    faqs_list = ''.join([f'<div class="faq-item"><h4>{f.question}</h4><p>{f.answer}</p></div>' for f in faqs])
    
    content = template.format(
        title=f"تعمیرات {keyword.keyword} در تهران",
        description=f"بهترین خدمات تعمیرات {keyword.keyword} در تهران با ضمانت کیفیت و بهترین قیمت",
        keyword=keyword.keyword,
        services_list=services_list,
        regions_list=regions_list,
        faqs_list=faqs_list
    )
    
    seo_page = SEOPage(
        keyword_id=keyword.id,
        title=f"تعمیرات {keyword.keyword} در تهران",
        slug=slug,  # <-- اسلاگ فینگلیش
        content=content,
        summary=f"تعمیرات تخصصی {keyword.keyword} در تمام مناطق تهران",
        seo_title=f"تعمیرات {keyword.keyword} در تهران | بهترین قیمت و کیفیت",
        seo_description=f"تعمیرات تخصصی {keyword.keyword} در تهران با ضمانت کیفیت. بهترین تکنسین‌های تعمیرات {keyword.keyword} در تهران.",
        seo_keywords=f"{keyword.keyword}, تعمیرات {keyword.keyword}, تعمیر {keyword.keyword} در تهران",
        is_auto_generated=True,
        is_active=True
    )
    
    db.session.add(seo_page)
    db.session.commit()
    
    create_internal_links(seo_page.id)
    
    return seo_page
    

def create_internal_links(seo_page_id):
    """ایجاد لینک‌های داخلی برای صفحه سئو شده"""
    seo_page = SEOPage.query.get(seo_page_id)
    if not seo_page:
        return
    
    services = Service.query.filter_by(is_active=True).limit(3).all()
    for service in services:
        link = InternalLink(
            source_page=f"/seo/{seo_page.slug}",
            target_page=f"/service/{service.id}",
            anchor_text=service.title,
            link_type='related',
            is_auto_generated=True
        )
        db.session.add(link)
    
    regions = TehranRegion.query.filter_by(is_active=True).limit(3).all()
    for region in regions:
        link = InternalLink(
            source_page=f"/seo/{seo_page.slug}",
            target_page=f"/region/{region.slug}",
            anchor_text=region.name,
            link_type='related',
            is_auto_generated=True
        )
        db.session.add(link)
    
    db.session.commit()
def update_all_seo_pages():
    """بروزرسانی تمام صفحات سئو شده"""
    keywords = KeywordBank.query.filter_by(is_active=True, is_targeted=True).all()
    count = 0
    for keyword in keywords:
        if create_seo_page_from_keyword(keyword.id):
            count += 1
    return count

# ================================================================
# ===== توابع مدیریت سئو =====
# ================================================================

def generate_seo_metadata(page_type, data):
    seo_data = {
        'title': data.get('title', ''),
        'description': data.get('description', ''),
        'keywords': data.get('keywords', ''),
        'og_title': data.get('title', ''),
        'og_description': data.get('description', ''),
        'twitter_card': 'summary_large_image'
    }
    
    templates = {
        'region': {
            'title_prefix': 'تعمیرات دوو در ',
            'title_suffix': ' | نمایندگی تخصصی دوو',
            'description_prefix': 'تعمیرات تخصصی دوو در '
        }
    }
    
    if page_type in templates:
        tpl = templates[page_type]
        if 'title_prefix' in tpl and data.get('region_name'):
            seo_data['title'] = f"{tpl['title_prefix']}{data['region_name']}{tpl.get('title_suffix', '')}"
        if 'description_prefix' in tpl and data.get('region_name'):
            seo_data['description'] = f"{tpl['description_prefix']}{data['region_name']} - بهترین خدمات تعمیرات دوو"
    
    return seo_data

# ================================================================
# ===== فیلترهای تمپلیت =====
# ================================================================

@app.template_filter('persian_numbers')
def persian_numbers(value):
    if value is None:
        return '۰'
    try:
        num = int(float(value))
    except:
        return str(value)
    persian = {'0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
               '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'}
    return str(num).translate(str.maketrans(persian))

@app.template_filter('persian_date')
def persian_date(value):
    if not value:
        return ''
    try:
        # اگر string بود، try to parse
        if isinstance(value, str):
            try:
                value = datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
            except ValueError:
                try:
                    value = datetime.strptime(value, '%Y-%m-%d')
                except ValueError:
                    return value  # اگر قابل تبدیل نبود، خودش رو برگردون
        
        import jdatetime
        j = jdatetime.datetime.fromgregorian(datetime=value)
        months = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 
                  'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
        return f"{j.day} {months[j.month-1]} {j.year}"
    except Exception as e:
        return str(value) if value else ''
        

# ===== دیکشنری ترجمه دسته‌بندی‌ها =====
CATEGORY_NAMES = {
    'refrigerator': 'یخچال',
    'washing_machine': 'لباسشویی',
    'dishwasher': 'ظرفشویی',
    'package': 'پکیج',
    'vacuum': 'جاروبرقی',
    'microwave': 'مایکروویو',
    'stove': 'اجاق گاز',
    'hood': 'هود',
    'installation': 'نصب و راه‌اندازی',
    'cooling': 'سرمایشی',
    'heating': 'گرمایشی',
    'laundry': 'لباسشویی',
    'kitchen': 'آشپزخانه',
    'cleaning': 'نظافت',
    'setup': 'راه‌اندازی'
} 




CATEGORY_NAMES = {
    'brand': 'برند',
    'service': 'خدمات',
    'region': 'منطقه',
    'neighborhood': 'محله',
    'parts': 'قطعات',
    'warranty': 'ضمانت',
    'pricing': 'قیمت‌گذاری',
    'emergency': 'اضطراری',
    'maintenance': 'نگهداری',
    'installation': 'نصب',
    'general': 'عمومی',
    'refrigerator': 'یخچال',
    'washing_machine': 'لباسشویی',
    'dishwasher': 'ظرفشویی',
    'package': 'پکیج',
    'vacuum': 'جاروبرقی',
    'microwave': 'مایکروویو',
    'stove': 'اجاق گاز',
    'hood': 'هود'
}


# ================================================================
# ===== 2. تابع بروزرسانی خودکار سئو (جدید) =====
# ===========================
def update_seo_globally():
    """بروزرسانی کامل سئو"""
    try:
        top_keywords = KeywordBank.query.filter_by(
            is_active=True
        ).order_by(
            KeywordBank.priority.desc()
        ).limit(15).all()
        
        if top_keywords:
            keywords_str = ', '.join([kw.keyword for kw in top_keywords[:10]])
            Setting.set('seo_default_keywords', keywords_str)
            
            desc_keywords = [kw.keyword for kw in top_keywords[:5]]
            description = f"تعمیرات تخصصی {', '.join(desc_keywords)} در تهران با ضمانت کیفیت و بهترین قیمت"
            Setting.set('seo_default_description', description[:160])
            
            title_keywords = [kw.keyword for kw in top_keywords[:3]]
            title = f"تعمیرات {', '.join(title_keywords)} | نمایندگی تخصصی دوو تهران"
            Setting.set('seo_default_title', title[:60])
        
        count = update_all_seo_pages()
        sitemap_count = generate_sitemap()
        
        Setting.set('seo_last_update', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        Setting.set('seo_pages_count', count)
        Setting.set('sitemap_urls_count', sitemap_count)
        
        return True
    except Exception as e:
        print(f'Error updating SEO: {e}')
        return False
        
# ================================================================
# ===== 3. Context Processor سراسری (اصلاح شده) =====
# ================================================================

# ================================================================
# ===== 4. روت‌های جدید سئو (اضافه کنید) =====
# ================================================================

# ================================================================
# ===== Context Processor کامل (با سئو و فیلترهای فارسی) =====
# ================================================================
@app.context_processor
def utility_processor():
    import jdatetime
    from datetime import datetime
    
    # ===== فیلترهای فارسی =====
    def persian_numbers(value):
        """تبدیل اعداد انگلیسی به فارسی"""
        if value is None:
            return '۰'
        try:
            if isinstance(value, (int, float)):
                num = int(value)
            else:
                try:
                    num = int(float(str(value).replace(',', '')))
                except:
                    return str(value)
        except:
            return str(value)
        
        persian = {'0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
                   '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'}
        return str(num).translate(str.maketrans(persian))
    
    def persian_date(value):
        """تبدیل تاریخ میلادی به شمسی"""
        if not value:
            return ''
        try:
            if isinstance(value, str):
                try:
                    value = datetime.strptime(value, '%Y-%m-%d')
                except:
                    return value
            j = jdatetime.datetime.fromgregorian(datetime=value)
            months = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 
                      'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
            return f"{j.day} {months[j.month-1]} {j.year}"
        except:
            return str(value) if value else ''
    
    def persian_number_format(value):
        """تبدیل عدد به فرمت فارسی با جداکننده هزارگان"""
        if value is None:
            return '۰'
        try:
            num = int(float(value))
            formatted = f"{num:,}".replace(',', '٬')
            return persian_numbers(formatted)
        except:
            return str(value)
    
    def persian_date_display(value):
        """تبدیل تاریخ میلادی به شمسی برای نمایش"""
        if not value:
            return ''
        try:
            if isinstance(value, str):
                try:
                    value = datetime.strptime(value, '%Y-%m-%d')
                except:
                    return value
            j = jdatetime.datetime.fromgregorian(datetime=value)
            months = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 
                      'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
            return f"{j.day} {months[j.month-1]} {j.year}"
        except:
            return str(value) if value else ''
    
    def truncate_text(value, length=100):
        """خلاصه‌سازی متن"""
        if not value:
            return ''
        if len(value) <= length:
            return value
        return value[:length] + '...'
    
    def get_stars(rating):
        """تبدیل امتیاز به ستاره"""
        if not rating:
            return ''
        full = int(rating)
        half = 1 if rating - full >= 0.5 else 0
        empty = 5 - full - half
        return '★' * full + ('½' if half else '') + '☆' * empty
    
    # ===== سئو و کلمات کلیدی =====
    try:
        top_keywords = KeywordBank.query.filter_by(
            is_active=True
        ).order_by(
            KeywordBank.priority.desc()
        ).limit(15).all()
    except:
        top_keywords = []
    
    try:
        keywords_by_category = {}
        categories = ['brand', 'service', 'region', 'neighborhood', 'emergency', 'pricing']
        for cat in categories:
            keywords_by_category[cat] = KeywordBank.query.filter_by(
                category=cat,
                is_active=True
            ).order_by(KeywordBank.priority.desc()).limit(5).all()
    except:
        keywords_by_category = {}
    
    try:
        seo_settings = {
            # ===== متا تگ‌های اصلی =====
            'default_title': Setting.get('seo_default_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
            'default_description': Setting.get('seo_default_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت. تکنسین‌های مجرب و قطعات اورجینال.'),
            'default_keywords': Setting.get('seo_default_keywords', 'تعمیرات دوو, تهران, نمایندگی دوو, تعمیر یخچال دوو, تعمیر لباسشویی دوو, تعمیر ظرفشویی دوو, تعمیر پکیج دوو'),
            'robots': Setting.get('seo_robots', 'index, follow'),
            'canonical_url': Setting.get('seo_canonical_url', ''),
            'brand_title': Setting.get('seo_brand_title', 'دوو تهران'),
            'last_update': Setting.get('seo_last_update', ''),
            
            # ===== Open Graph (فیسبوک، تلگرام، واتساپ، لینکدین) =====
            'og_title': Setting.get('seo_og_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی لوازم خانگی دوو'),
            'og_description': Setting.get('seo_og_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت. تکنسین‌های مجرب و قطعات اورجینال.'),
            'og_image': Setting.get('seo_og_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
            'og_type': Setting.get('seo_og_type', 'website'),
            'og_locale': Setting.get('seo_og_locale', 'fa_IR'),
            'og_site_name': Setting.get('seo_og_site_name', 'نمایندگی تعمیرات دوو تهران'),
            
            # ===== Twitter Card (توییتر) =====
            'twitter_card': Setting.get('seo_twitter_card', 'summary_large_image'),
            'twitter_title': Setting.get('seo_twitter_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
            'twitter_description': Setting.get('seo_twitter_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
            'twitter_image': Setting.get('seo_twitter_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
            'twitter_site': Setting.get('seo_twitter_site', '@daewoo_tehran'),
            'twitter_creator': Setting.get('seo_twitter_creator', '@daewoo_tehran'),
            
            # ===== LinkedIn (لینکدین) =====
            'linkedin_title': Setting.get('seo_linkedin_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
            'linkedin_description': Setting.get('seo_linkedin_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
            'linkedin_image': Setting.get('seo_linkedin_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
            
            # ===== Telegram (تلگرام) =====
            'telegram_title': Setting.get('seo_telegram_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
            'telegram_description': Setting.get('seo_telegram_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
            'telegram_image': Setting.get('seo_telegram_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
            
            # ===== WhatsApp (واتساپ) =====
            'whatsapp_title': Setting.get('seo_whatsapp_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
            'whatsapp_description': Setting.get('seo_whatsapp_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
            'whatsapp_image': Setting.get('seo_whatsapp_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
            
            # ===== Pinterest (پینترست) =====
            'pinterest_title': Setting.get('seo_pinterest_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
            'pinterest_description': Setting.get('seo_pinterest_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
            'pinterest_image': Setting.get('seo_pinterest_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
            
            # ===== Instagram (اینستاگرام) - Deep Link =====
            'instagram_ios_url': Setting.get('seo_instagram_ios_url', 'daewooservic://'),
            'instagram_android_url': Setting.get('seo_instagram_android_url', 'daewooservic://'),
        }
    except:
        seo_settings = {}
    
    # ===== تصاویر هدر =====
    try:
        header_images = SiteHeaderImage.query.filter_by(
            is_active=True
        ).order_by(SiteHeaderImage.sort_order).all()
    except:
        header_images = []
    
    # ===== خطاهای برجسته =====
    try:
        featured_errors = ErrorSolution.query.filter_by(
            is_active=True,
            is_featured=True
        ).limit(5).all()
    except:
        featured_errors = []
    
    # ===== صفحات سئو شده =====
    try:
        seo_pages = SEOPage.query.filter_by(is_active=True).order_by(
            SEOPage.view_count.desc()
        ).limit(10).all()
    except:
        seo_pages = []
    
    # ===== دسته‌بندی خطاها =====
    try:
        error_categories = ErrorCategory.query.filter_by(
            is_active=True
        ).order_by(ErrorCategory.sort_order).all()
    except:
        error_categories = []
    
    # ===== خدمات محبوب =====
    try:
        popular_services = Service.query.filter_by(
            is_active=True,
            is_popular=True
        ).limit(6).all()
    except:
        popular_services = []
    
    # ===== تکنسین‌های برتر =====
    try:
        top_technicians = Technician.query.filter_by(
            is_active=True
        ).order_by(Technician.rating.desc()).limit(5).all()
    except:
        top_technicians = []
    
    # ============================================================
    # ===== اضافه شده: داده‌های مورد نیاز برای صفحه اصلی =====
    # ============================================================
    try:
        # ===== نظرات مشتریان (برای JSON-LD و نمایش) =====
        testimonials = Testimonial.query.filter_by(is_active=True).all()
    except:
        testimonials = []
    
    try:
        # ===== تکنسین‌ها (برای آمار و نمایش) =====
        technicians = Technician.query.filter_by(is_active=True).all()
        # تبدیل تخصص‌ها برای نمایش
        import json
        for tech in technicians:
            if tech.expertise_areas:
                try:
                    exp_list = json.loads(tech.expertise_areas)
                    tech.expertise_display = '، '.join(exp_list)
                except:
                    tech.expertise_display = tech.expertise_areas
            else:
                tech.expertise_display = 'تعمیرات تخصصی دوو'
    except:
        technicians = []
    
    try:
        # ===== خدمات (برای نمایش در صفحه اصلی) =====
        services = Service.query.filter_by(is_active=True).order_by(Service.order).all()
    except:
        services = []
    
    try:
        # ===== مقالات (برای نمایش در صفحه اصلی) =====
        articles = Article.query.filter_by(is_active=True).order_by(Article.created_at.desc()).limit(3).all()
    except:
        articles = []
    
    try:
        # ===== سوالات متداول =====
        faqs = FAQ.query.filter_by(is_active=True).order_by(FAQ.order).all()
    except:
        faqs = []
    
    try:
        # ===== مناطق (برای نمایش در صفحه اصلی) =====
        regions = TehranRegion.query.filter_by(is_active=True).all()
    except:
        regions = []
    
    # ===== تنظیمات سایت =====
    try:
        site_settings = {
            'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
            'site_description': Setting.get('site_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران'),
            'phone1': Setting.get('phone1', '021-5555-1234'),
            'phone2': Setting.get('phone2', ''),
            'whatsapp': Setting.get('whatsapp', '0912-123-4567'),
            'email': Setting.get('email', 'info@daewoo-tehran.com'),
            'address': Setting.get('address', 'تهران، میدان آزادی'),
            'work_hours': Setting.get('work_hours', 'شنبه تا پنجشنبه ۹ صبح تا ۸ شب'),
            'emergency_phone': Setting.get('emergency_phone', '0912-123-4567'),
            'about_text': Setting.get('about_text', 'بیش از ۱۰ سال تجربه در تعمیرات دوو'),
            'instagram': Setting.get('instagram', 'daewoo_tehran'),
            'telegram': Setting.get('telegram', 'daewoo_tehran'),
            'youtube': Setting.get('youtube', 'daewoo_tehran'),
            'aparat': Setting.get('aparat', 'daewoo_tehran'),
            'twitter': Setting.get('twitter', 'daewoo_tehran'),
            'facebook': Setting.get('facebook', 'daewoo_tehran'),
            'rubika': Setting.get('rubika', 'daewoo_tehran'),
            'bale': Setting.get('bale', 'daewoo_tehran')
        }
    except:
        site_settings = {}
    
    # ===== اطلاعات کاربر (اگر وارد شده باشد) =====
    user = None
    user_notifications = []
    unread_count = 0
    try:
        if 'user_id' in session:
            user = User.query.get(session['user_id'])
            if user:
                user_notifications = Notification.query.filter_by(
                    user_id=user.id,
                    is_read=False
                ).order_by(Notification.created_at.desc()).limit(10).all()
                unread_count = Notification.query.filter_by(
                    user_id=user.id,
                    is_read=False
                ).count()
    except:
        pass
    
    # ===== دیکشنری ترجمه دسته‌بندی‌ها =====
    CATEGORY_NAMES = {
        'refrigerator': 'یخچال',
        'washing_machine': 'لباسشویی',
        'dishwasher': 'ظرفشویی',
        'package': 'پکیج',
        'vacuum': 'جاروبرقی',
        'microwave': 'مایکروویو',
        'stove': 'اجاق گاز',
        'hood': 'هود',
        'installation': 'نصب و راه‌اندازی',
        'cooling': 'سرمایشی',
        'heating': 'گرمایشی',
        'laundry': 'لباسشویی',
        'kitchen': 'آشپزخانه',
        'cleaning': 'نظافت',
        'setup': 'راه‌اندازی',
        'brand': 'برند',
        'service': 'خدمات',
        'region': 'منطقه',
        'neighborhood': 'محله',
        'parts': 'قطعات',
        'warranty': 'ضمانت',
        'pricing': 'قیمت‌گذاری',
        'emergency': 'اضطراری',
        'maintenance': 'نگهداری',
        'general': 'عمومی'
    }
    
    # ===== برگرداندن همه چیز =====
    return {
        # فیلترهای فارسی
        'persian_numbers': persian_numbers,
        'persian_date': persian_date,
        'persian_number_format': persian_number_format,
        'persian_date_display': persian_date_display,
        'truncate_text': truncate_text,
        'get_stars': get_stars,
        
        # سئو
        'top_keywords': top_keywords,
        'keywords_by_category': keywords_by_category,
        'seo_settings': seo_settings,
        'CATEGORY_NAMES': CATEGORY_NAMES,
        
        # تصاویر هدر
        'header_images': header_images,
        
        # خطاها و سئو
        'featured_errors': featured_errors,
        'seo_pages': seo_pages,
        'error_categories': error_categories,
        
        # محتوای سایت (برای استفاده در تمام صفحات)
        'testimonials': testimonials,      # <-- اضافه شده
        'technicians': technicians,        # <-- اضافه شده
        'services': services,              # <-- اضافه شده
        'articles': articles,              # <-- اضافه شده
        'faqs': faqs,                      # <-- اضافه شده
        'regions': regions,                # <-- اضافه شده
        'popular_services': popular_services,
        'top_technicians': top_technicians,
        'site_settings': site_settings,
        
        # کاربر
        'user': user,
        'user_notifications': user_notifications,
        'unread_count': unread_count,
        
        # کلاس‌های مدل برای دسترسی در تمپلیت
        'SiteHeaderImage': SiteHeaderImage,
        'ErrorCategory': ErrorCategory,
        'ErrorSolution': ErrorSolution,
        'SEOPage': SEOPage
    }
# ================================================================
# ===== مسیرهای سایت (همه مسیرها) =====
# ================================================================
@app.route('/')
def index():
    # ===== تنظیمات =====
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'site_description': Setting.get('site_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234'),
        'phone2': Setting.get('phone2', ''),
        'whatsapp': Setting.get('whatsapp', '0912-123-4567'),
        'email': Setting.get('email', 'info@daewoo-tehran.com'),
        'address': Setting.get('address', 'تهران، میدان آزادی'),
        'work_hours': Setting.get('work_hours', 'شنبه تا پنجشنبه ۹ صبح تا ۸ شب'),
        'about_text': Setting.get('about_text', 'بیش از ۱۰ سال تجربه در تعمیرات دوو'),
        'instagram': Setting.get('instagram', 'daewoo_tehran'),
        'telegram': Setting.get('telegram', 'daewoo_tehran'),
        'youtube': Setting.get('youtube', 'daewoo_tehran'),
        'aparat': Setting.get('aparat', 'daewoo_tehran'),
        'twitter': Setting.get('twitter', 'daewoo_tehran'),
        'facebook': Setting.get('facebook', 'daewoo_tehran'),
        'rubika': Setting.get('rubika', 'daewoo_tehran'),
        'bale': Setting.get('bale', 'daewoo_tehran'),
        'emergency_phone': Setting.get('emergency_phone', '0912-123-4567')
    }
    
    # ===== دریافت داده‌ها =====
    services = Service.query.filter_by(is_active=True).order_by(Service.order).all()
    articles = Article.query.filter_by(is_active=True).order_by(Article.created_at.desc()).limit(3).all()
    testimonials = Testimonial.query.filter_by(is_active=True).all()
    faqs = FAQ.query.filter_by(is_active=True).order_by(FAQ.order).all()
    technicians = Technician.query.filter_by(is_active=True).all()
    regions = TehranRegion.query.filter_by(is_active=True).all()
    
    # ===== تبدیل مناطق به JSON برای نقشه =====
    regions_json = []
    for r in regions:
        regions_json.append({
            'id': r.id,
            'name': r.name,
            'slug': r.slug,
            'latitude': r.latitude,
            'longitude': r.longitude,
            'region_number': r.region_number,
            'coverage_percentage': r.coverage_percentage
        })
    
    # ===== تبدیل تکنسین‌ها به JSON برای نقشه =====
    import json
    technicians_json = []
    for t in technicians:
        expertise_display = 'تعمیرات دوو'
        if t.expertise_areas:
            try:
                exp_list = json.loads(t.expertise_areas)
                expertise_display = '، '.join(exp_list)
            except:
                expertise_display = t.expertise_areas
        
        technicians_json.append({
            'id': t.id,
            'fullname': t.fullname,
            'phone': t.phone,
            'latitude': t.current_latitude,
            'longitude': t.current_longitude,
            'expertise': expertise_display,
            'rating': t.rating or 0,
            'status': t.status or 'available'
        })
    
    # ===== اضافه کردن expertise_display به خود تکنسین‌ها برای تمپلیت =====
    for t in technicians:
        if t.expertise_areas:
            try:
                exp_list = json.loads(t.expertise_areas)
                t.expertise_display = '، '.join(exp_list)
            except:
                t.expertise_display = t.expertise_areas
        else:
            t.expertise_display = 'تعمیرات تخصصی دوو'
    
    return render_template('index.html',
                         settings=settings,
                         services=services,
                         articles=articles,
                         testimonials=testimonials,
                         faqs=faqs,
                         technicians=technicians,
                         regions=regions,
                         regions_json=regions_json,
                         technicians_json=technicians_json)

@app.route('/about')
def about():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234'),
        'about_text': Setting.get('about_text', 'بیش از ۱۰ سال تجربه در تعمیرات دوو')
    }
    technicians = Technician.query.filter_by(is_active=True).all()
    
    # ===== درست کردن تخصص‌ها =====
    import json
    for tech in technicians:
        if tech.expertise_areas:
            try:
                exp_list = json.loads(tech.expertise_areas)
                tech.expertise_display = '، '.join(exp_list)
            except:
                tech.expertise_display = tech.expertise_areas
        else:
            tech.expertise_display = 'تکنسین دوو'
    
    return render_template('about.html', settings=settings, technicians=technicians)
    
    
@app.route('/contact')
def contact():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234'),
        'phone2': Setting.get('phone2', ''),
        'whatsapp': Setting.get('whatsapp', ''),
        'email': Setting.get('email', ''),
        'address': Setting.get('address', ''),
        'work_hours': Setting.get('work_hours', '')
    }
    return render_template('contact.html', settings=settings)

@app.route('/articles')
def articles():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    articles_list = Article.query.filter_by(is_active=True).order_by(Article.created_at.desc()).all()
    return render_template('articles.html', articles=articles_list, settings=settings)
@app.route('/article/<slug>')
def article_detail(slug):
    article = Article.query.filter_by(slug=slug, is_active=True).first_or_404()
    article.view_count += 1
    db.session.commit()
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    # ===== دریافت نظرات با کاربر =====
    comments = ArticleComment.query.filter_by(
        article_id=article.id, 
        is_approved=True
    ).order_by(ArticleComment.created_at.desc()).all()
    
    # ===== مقالات مرتبط =====
    related_articles = Article.query.filter(
        Article.is_active == True,
        Article.id != article.id,
        Article.category == article.category
    ).limit(5).all()
    
    return render_template('article_detail.html', 
                         article=article, 
                         articles=related_articles,
                         comments=comments,
                         settings=settings)

@app.route('/login', methods=['GET', 'POST'])
def login():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    if request.method == 'POST':
        phone = request.form.get('phone')
        password = request.form.get('password')
        
        user = User.query.filter_by(phone=phone).first()
        if user and check_password_hash(user.password, password):
            session['user_id'] = user.id
            session['fullname'] = user.fullname
            session['role'] = user.role
            flash('خوش آمدید!', 'success')
            return redirect(url_for('dashboard'))
        else:
            flash('شماره تماس یا رمز عبور اشتباه است.', 'danger')
    
    return render_template('login.html', settings=settings)

@app.route('/register', methods=['GET', 'POST'])
def register():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    if request.method == 'POST':
        fullname = request.form.get('fullname')
        phone = request.form.get('phone')
        email = request.form.get('email')
        password = request.form.get('password')
        
        if not fullname or not phone or not password:
            flash('لطفاً تمام فیلدها را پر کنید.', 'danger')
            return redirect(url_for('register'))
        
        if User.query.filter_by(phone=phone).first():
            flash('این شماره قبلاً ثبت شده است.', 'danger')
            return redirect(url_for('register'))
        
        user = User(
            fullname=fullname,
            phone=phone,
            email=email,
            password=generate_password_hash(password),
            role='user'
        )
        db.session.add(user)
        db.session.commit()
        
        session['user_id'] = user.id
        session['fullname'] = user.fullname
        session['role'] = user.role
        
        flash('ثبت نام با موفقیت انجام شد!', 'success')
        return redirect(url_for('dashboard'))
    
    return render_template('register.html', settings=settings)

@app.route('/logout')
def logout():
    session.clear()
    flash('خارج شدید.', 'info')
    return redirect(url_for('index'))

@app.route('/dashboard')
@login_required
def dashboard():
    # دریافت کاربر از سشن
    user_id = session.get('user_id')
    if not user_id:
        flash('لطفاً وارد شوید.', 'warning')
        return redirect(url_for('login'))
    
    user = User.query.get(user_id)
    if not user:
        session.clear()
        flash('کاربر یافت نشد. لطفاً دوباره وارد شوید.', 'danger')
        return redirect(url_for('login'))
    
    # اگر ادمین هست به داشبورد ادمین برو
    if user.role == 'admin':
        return redirect(url_for('admin_dashboard'))
    
    # ===== تنظیمات =====
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234'),
        'phone2': Setting.get('phone2', ''),
        'whatsapp': Setting.get('whatsapp', '0912-123-4567'),
        'email': Setting.get('email', 'info@daewoo-tehran.com'),
        'address': Setting.get('address', 'تهران، میدان آزادی'),
        'work_hours': Setting.get('work_hours', 'شنبه تا پنجشنبه ۹ صبح تا ۸ شب'),
        'about_text': Setting.get('about_text', 'بیش از ۱۰ سال تجربه در تعمیرات دوو'),
        'instagram': Setting.get('instagram', 'daewoo_tehran'),
        'telegram': Setting.get('telegram', 'daewoo_tehran'),
        'youtube': Setting.get('youtube', 'daewoo_tehran'),
        'aparat': Setting.get('aparat', 'daewoo_tehran'),
        'twitter': Setting.get('twitter', 'daewoo_tehran')
    }
    
    bookings = user.bookings.order_by(Booking.created_at.desc()).all()
    
    return render_template('user/dashboard.html', 
                         user=user, 
                         bookings=bookings,
                         settings=settings)
                         

@app.route('/user/wallet')
@login_required
def user_wallet():
    user_id = session.get('user_id')
    if not user_id:
        flash('لطفاً وارد شوید.', 'warning')
        return redirect(url_for('login'))
    
    user = User.query.get(user_id)
    if not user:
        session.clear()
        flash('کاربر یافت نشد.', 'danger')
        return redirect(url_for('login'))
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234'),
        'phone2': Setting.get('phone2', ''),
        'whatsapp': Setting.get('whatsapp', '0912-123-4567'),
        'email': Setting.get('email', 'info@daewoo-tehran.com'),
        'address': Setting.get('address', 'تهران، میدان آزادی'),
        'work_hours': Setting.get('work_hours', 'شنبه تا پنجشنبه ۹ صبح تا ۸ شب'),
        'about_text': Setting.get('about_text', 'بیش از ۱۰ سال تجربه در تعمیرات دوو'),
        'instagram': Setting.get('instagram', 'daewoo_tehran'),
        'telegram': Setting.get('telegram', 'daewoo_tehran'),
        'youtube': Setting.get('youtube', 'daewoo_tehran'),
        'aparat': Setting.get('aparat', 'daewoo_tehran'),
        'twitter': Setting.get('twitter', 'daewoo_tehran')
    }
    
    transactions = WalletTransaction.query.filter_by(user_id=user.id)\
        .order_by(WalletTransaction.created_at.desc()).all()
    
    return render_template('user/wallet.html', 
                         user=user, 
                         transactions=transactions,
                         settings=settings)
                         
@app.route('/submit_review', methods=['POST'])
@login_required
def submit_review():
    try:
        title = request.form.get('title')
        rating = request.form.get('rating')
        content = request.form.get('content')
        
        # اعتبارسنجی
        if not title or not rating or not content:
            flash('لطفاً همه فیلدها را پر کنید.', 'danger')
            return redirect(url_for('index'))
        
        # ایجاد نظر جدید (نیاز به تایید ادمین)
        review = Review(
            user_id=session['user_id'],
            rating=int(rating),
            title=title,
            content=content,
            is_approved=False,  # نیاز به تایید ادمین
            is_verified=False,
            created_at=datetime.now()
        )
        db.session.add(review)
        db.session.commit()
        
        flash('نظر شما با موفقیت ثبت شد و پس از تایید ادمین نمایش داده می‌شود.', 'success')
        return redirect(url_for('index'))
        
    except Exception as e:
        db.session.rollback()
        flash(f'خطا در ثبت نظر: {str(e)}', 'danger')
        return redirect(url_for('index'))
        
# ================================================================
# ===== روت‌های ادمین =====
# ================================================================
@app.route('/admin/dashboard')
@admin_required
def admin_dashboard():
    # ===== آمار اصلی =====
    total_users = User.query.count()
    total_services = Service.query.count()
    total_bookings = Booking.query.count()
    pending_reviews = Review.query.filter_by(is_approved=False).count()
    total_technicians = Technician.query.count()
    total_regions = TehranRegion.query.count()
    total_articles = Article.query.count()
    total_keywords = KeywordBank.query.count()
    total_settings = Setting.query.count()
    
    # ===== آمار خطاها =====
    total_errors = ErrorSolution.query.filter_by(is_active=True).count()
    total_error_categories = ErrorCategory.query.filter_by(is_active=True).count()
    total_featured_errors = ErrorSolution.query.filter_by(is_active=True, is_featured=True).count()
    total_self_fix_errors = ErrorSolution.query.filter_by(is_active=True, can_self_fix=True).count()
    
    # ===== آمار سئو =====
    total_seo_pages = SEOPage.query.filter_by(is_active=True).count()
    total_header_images = SiteHeaderImage.query.filter_by(is_active=True).count()
    
    # ===== وضعیت رزروها =====
    pending_bookings = Booking.query.filter_by(status='pending').count()
    confirmed_bookings = Booking.query.filter_by(status='confirmed').count()
    in_progress_bookings = Booking.query.filter_by(status='in_progress').count()
    completed_bookings = Booking.query.filter_by(status='completed').count()
    cancelled_bookings = Booking.query.filter_by(status='cancelled').count()
    
    # ===== رزروهای اخیر =====
    recent_bookings = Booking.query.order_by(Booking.created_at.desc()).limit(10).all()
    recent_users = User.query.order_by(User.created_at.desc()).limit(10).all()
    
    # ===== داده‌های نمودار =====
    from datetime import datetime, timedelta
    months = []
    monthly_bookings = []
    month_names = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 
                   'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
    
    for i in range(6):
        month = datetime.now() - timedelta(days=i*30)
        months.append(month_names[month.month - 1])
        count = Booking.query.filter(
            Booking.created_at >= month.replace(day=1),
            Booking.created_at < (month.replace(day=1) + timedelta(days=32)).replace(day=1)
        ).count()
        monthly_bookings.append(count)
    months.reverse()
    monthly_bookings.reverse()
    
    # ===== امتیاز سئو =====
    seo_score = 0
    seo_default_title = Setting.get('seo_default_title', '')
    seo_default_description = Setting.get('seo_default_description', '')
    seo_default_keywords = Setting.get('seo_default_keywords', '')
    seo_og_title = Setting.get('seo_og_title', '')
    seo_og_description = Setting.get('seo_og_description', '')
    seo_robots = Setting.get('seo_robots', 'index, follow')
    seo_canonical_url = Setting.get('seo_canonical_url', '')
    seo_last_update = Setting.get('seo_last_update', '')
    
    if seo_default_title and len(seo_default_title) > 10:
        seo_score += 10
    if seo_default_description and len(seo_default_description) > 50:
        seo_score += 10
    if seo_default_keywords:
        seo_score += 10
    if seo_og_title:
        seo_score += 10
    if seo_og_description:
        seo_score += 10
    if total_articles > 0:
        seo_score += 10
    if total_keywords > 0:
        seo_score += 10
    if total_regions > 0:
        seo_score += 10
    if seo_robots == 'index, follow':
        seo_score += 10
    if seo_canonical_url:
        seo_score += 10
    if total_services > 0:
        seo_score += 10
    if total_seo_pages > 0:
        seo_score += 10
    
    # ===== بکاپ =====
    import os
    backup_dir = 'backups'
    total_backups = 0
    if os.path.exists(backup_dir):
        total_backups = len([f for f in os.listdir(backup_dir) if f.endswith('.zip')])
    
    # ===== سایتمپ =====
    sitemap_urls = 5 + Service.query.filter_by(is_active=True).count() + Article.query.filter_by(is_active=True).count() + TehranRegion.query.filter_by(is_active=True).count()
    
    # ===== robots.txt =====
    robots_exists = os.path.exists('robots.txt')
    
    return render_template('admin/dashboard.html',
                         total_users=total_users,
                         total_services=total_services,
                         total_bookings=total_bookings,
                         pending_reviews=pending_reviews,
                         total_technicians=total_technicians,
                         total_regions=total_regions,
                         total_articles=total_articles,
                         total_keywords=total_keywords,
                         total_settings=total_settings,
                         total_backups=total_backups,
                         sitemap_urls=sitemap_urls,
                         seo_score=seo_score,
                         robots_exists=robots_exists,
                         seo_last_update=seo_last_update,
                         pending_bookings=pending_bookings,
                         confirmed_bookings=confirmed_bookings,
                         in_progress_bookings=in_progress_bookings,
                         completed_bookings=completed_bookings,
                         cancelled_bookings=cancelled_bookings,
                         recent_bookings=recent_bookings,
                         recent_users=recent_users,
                         months=months,
                         monthly_bookings=monthly_bookings,
                         total_errors=total_errors,
                         total_error_categories=total_error_categories,
                         total_featured_errors=total_featured_errors,
                         total_self_fix_errors=total_self_fix_errors,
                         total_seo_pages=total_seo_pages,
                         total_header_images=total_header_images)
           
# ---- مدیریت کاربران ----
@app.route('/admin/users')
@admin_required
def admin_users():
    users = User.query.order_by(User.created_at.desc()).all()
    return render_template('admin/users/index.html', users=users)


@app.route('/admin/users/create', methods=['GET', 'POST'])
@admin_required
def admin_user_create():
    if request.method == 'POST':
        # منطق ایجاد کاربر
        pass
    return render_template('admin/users/create.html')


@app.route('/admin/users/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_user_edit(id):
    user = User.query.get_or_404(id)
    if request.method == 'POST':
        # منطق ویرایش کاربر
        pass
    return render_template('admin/users/edit.html', user=user)


@app.route('/admin/users/<int:id>/delete')
@admin_required
def admin_user_delete(id):
    user = User.query.get_or_404(id)
    db.session.delete(user)
    db.session.commit()
    flash('کاربر با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_users'))


# ---- مدیریت خدمات ----
@app.route('/admin/services')
@admin_required
def admin_services():
    services = Service.query.order_by(Service.order).all()
    return render_template('admin/services/index.html', services=services)


@app.route('/admin/services/create', methods=['GET', 'POST'])
@admin_required
def admin_service_create():
    if request.method == 'POST':
        # منطق ایجاد سرویس
        pass
    return render_template('admin/services/create.html')


@app.route('/admin/services/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_service_edit(id):
    service = Service.query.get_or_404(id)
    if request.method == 'POST':
        # منطق ویرایش سرویس
        pass
    return render_template('admin/services/edit.html', service=service)


@app.route('/admin/services/<int:id>/delete')
@admin_required
def admin_service_delete(id):
    service = Service.query.get_or_404(id)
    db.session.delete(service)
    db.session.commit()
    flash('سرویس با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_services'))

# ---- مدیریت تکنسین‌ها ----
@app.route('/admin/technicians')
@admin_required
def admin_technicians():
    technicians = Technician.query.order_by(Technician.created_at.desc()).all()
    
    # تبدیل تخصص‌ها برای نمایش
    import json
    for tech in technicians:
        if tech.expertise_areas:
            try:
                exp_list = json.loads(tech.expertise_areas)
                tech.expertise_display = '، '.join(exp_list)
            except:
                tech.expertise_display = tech.expertise_areas
        else:
            tech.expertise_display = 'تعمیرات تخصصی دوو'
    
    return render_template('admin/technicians/index.html', technicians=technicians)


@app.route('/admin/technicians/create', methods=['GET', 'POST'])
@admin_required
def admin_technician_create():
    if request.method == 'POST':
        try:
            fullname = request.form.get('fullname')
            phone = request.form.get('phone')
            national_code = request.form.get('national_code')
            expertise = request.form.get('expertise')
            experience_years = request.form.get('experience_years')
            bio = request.form.get('bio')
            status = request.form.get('status')
            rating = request.form.get('rating')
            
            # تبدیل تخصص به JSON
            import json
            expertise_list = [e.strip() for e in expertise.split(',') if e.strip()]
            expertise_json = json.dumps(expertise_list)
            
            technician = Technician(
                fullname=fullname,
                phone=phone,
                national_code=national_code,
                expertise_areas=expertise_json,
                experience_years=int(experience_years) if experience_years else 0,
                bio=bio,
                status=status or 'available',
                rating=float(rating) if rating else 0,
                is_active=True,
                is_verified=True
            )
            db.session.add(technician)
            db.session.commit()
            
            flash('تکنسین با موفقیت ایجاد شد.', 'success')
            return redirect(url_for('admin_technicians'))
            
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ایجاد تکنسین: {str(e)}', 'danger')
    
    return render_template('admin/technicians/create.html')


@app.route('/admin/technicians/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_technician_edit(id):
    technician = Technician.query.get_or_404(id)
    
    # تبدیل تخصص به لیست برای نمایش
    import json
    expertise_list = []
    if technician.expertise_areas:
        try:
            expertise_list = json.loads(technician.expertise_areas)
        except:
            pass
    
    if request.method == 'POST':
        try:
            technician.fullname = request.form.get('fullname')
            technician.phone = request.form.get('phone')
            technician.national_code = request.form.get('national_code')
            expertise = request.form.get('expertise')
            technician.experience_years = int(request.form.get('experience_years', 0))
            technician.bio = request.form.get('bio')
            technician.status = request.form.get('status')
            technician.rating = float(request.form.get('rating', 0))
            
            # تبدیل تخصص به JSON
            expertise_list = [e.strip() for e in expertise.split(',') if e.strip()]
            technician.expertise_areas = json.dumps(expertise_list)
            
            db.session.commit()
            flash('تکنسین با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_technicians'))
            
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ویرایش تکنسین: {str(e)}', 'danger')
    
    return render_template('admin/technicians/edit.html', 
                         technician=technician, 
                         expertise_list=','.join(expertise_list))


@app.route('/admin/technicians/<int:id>/delete')
@admin_required
def admin_technician_delete(id):
    technician = Technician.query.get_or_404(id)
    db.session.delete(technician)
    db.session.commit()
    flash('تکنسین با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_technicians'))
    
# ---- مدیریت رزروها ----
@app.route('/admin/bookings')
@admin_required
def admin_bookings():
    bookings = Booking.query.order_by(Booking.created_at.desc()).all()
    return render_template('admin/bookings/index.html', bookings=bookings)


@app.route('/admin/bookings/<int:id>')
@admin_required
def admin_booking_detail(id):
    booking = Booking.query.get_or_404(id)
    return render_template('admin/bookings/detail.html', booking=booking)


@app.route('/admin/bookings/<int:id>/status', methods=['GET', 'POST'])
@admin_required
def admin_booking_status(id):
    booking = Booking.query.get_or_404(id)
    
    if request.method == 'POST':
        status = request.form.get('status')
        technician_notes = request.form.get('technician_notes')
        
        booking.status = status
        booking.technician_notes = technician_notes
        db.session.commit()
        
        flash('وضعیت رزرو با موفقیت تغییر کرد.', 'success')
        return redirect(url_for('admin_bookings'))
    
    return render_template('admin/bookings/status.html', booking=booking)
# ---- مدیریت نظرات ----
@app.route('/admin/reviews')
@admin_required
def admin_reviews():
    reviews = Review.query.order_by(Review.created_at.desc()).all()
    return render_template('admin/reviews/index.html', reviews=reviews)


@app.route('/admin/reviews/<int:id>/approve')
@admin_required
def admin_review_approve(id):
    review = Review.query.get_or_404(id)
    review.is_approved = True
    review.is_verified = True
    db.session.commit()
    flash('نظر با موفقیت تایید شد.', 'success')
    return redirect(url_for('admin_reviews'))


@app.route('/admin/reviews/<int:id>/delete')
@admin_required
def admin_review_delete(id):
    review = Review.query.get_or_404(id)
    db.session.delete(review)
    db.session.commit()
    flash('نظر با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_reviews'))

# ---- مدیریت مقالات ----
@app.route('/admin/articles')
@admin_required
def admin_articles():
    articles = Article.query.order_by(Article.created_at.desc()).all()
    return render_template('admin/articles/index.html', articles=articles)


@app.route('/admin/articles/create', methods=['GET', 'POST'])
@admin_required
def admin_article_create():
    if request.method == 'POST':
        try:
            title = request.form.get('title')
            slug = request.form.get('slug')
            category = request.form.get('category')
            summary = request.form.get('summary')
            content = request.form.get('content')
            is_featured = request.form.get('is_featured') == 'on'
            is_active = request.form.get('is_active') == 'on'
            
            # ایجاد اسلاگ خودکار
            if not slug:
                slug = title.replace(' ', '-').replace('؟', '').replace('!', '')
            
            article = Article(
                title=title,
                slug=slug,
                category=category,
                summary=summary,
                content=content,
                is_featured=is_featured,
                is_active=is_active,
                author_id=session['user_id'],
                created_at=datetime.now()
            )
            db.session.add(article)
            db.session.commit()
            
            flash('مقاله با موفقیت ایجاد شد.', 'success')
            return redirect(url_for('admin_articles'))
            
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ایجاد مقاله: {str(e)}', 'danger')
    
    return render_template('admin/articles/create.html')


@app.route('/admin/articles/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_article_edit(id):
    article = Article.query.get_or_404(id)
    
    if request.method == 'POST':
        try:
            article.title = request.form.get('title')
            article.slug = request.form.get('slug')
            article.category = request.form.get('category')
            article.summary = request.form.get('summary')
            article.content = request.form.get('content')
            article.is_featured = request.form.get('is_featured') == 'on'
            article.is_active = request.form.get('is_active') == 'on'
            
            db.session.commit()
            flash('مقاله با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_articles'))
            
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ویرایش مقاله: {str(e)}', 'danger')
    
    return render_template('admin/articles/edit.html', article=article)


@app.route('/admin/articles/<int:id>/delete')
@admin_required
def admin_article_delete(id):
    article = Article.query.get_or_404(id)
    db.session.delete(article)
    db.session.commit()
    flash('مقاله با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_articles'))  
    

# ---- مدیریت مناطق ----
@app.route('/admin/regions')
@admin_required
def admin_regions():
    regions = TehranRegion.query.order_by(TehranRegion.region_number).all()
    return render_template('admin/regions/index.html', regions=regions)


@app.route('/admin/regions/create', methods=['GET', 'POST'])
@admin_required
def admin_region_create():
    if request.method == 'POST':
        try:
            region = TehranRegion(
                region_number=int(request.form.get('region_number')),
                name=request.form.get('name'),
                slug=request.form.get('slug'),
                latitude=float(request.form.get('latitude')) if request.form.get('latitude') else None,
                longitude=float(request.form.get('longitude')) if request.form.get('longitude') else None,
                description=request.form.get('description'),
                population=int(request.form.get('population')) if request.form.get('population') else None,
                area_sqkm=float(request.form.get('area_sqkm')) if request.form.get('area_sqkm') else None,
                is_active=request.form.get('is_active') == 'on'
            )
            db.session.add(region)
            db.session.commit()
            flash('منطقه با موفقیت ایجاد شد.', 'success')
            return redirect(url_for('admin_regions'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ایجاد منطقه: {str(e)}', 'danger')
    
    return render_template('admin/regions/create.html')


@app.route('/admin/regions/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_region_edit(id):
    region = TehranRegion.query.get_or_404(id)
    
    if request.method == 'POST':
        try:
            region.region_number = int(request.form.get('region_number'))
            region.name = request.form.get('name')
            region.slug = request.form.get('slug')
            region.latitude = float(request.form.get('latitude')) if request.form.get('latitude') else None
            region.longitude = float(request.form.get('longitude')) if request.form.get('longitude') else None
            region.description = request.form.get('description')
            region.population = int(request.form.get('population')) if request.form.get('population') else None
            region.area_sqkm = float(request.form.get('area_sqkm')) if request.form.get('area_sqkm') else None
            region.is_active = request.form.get('is_active') == 'on'
            
            db.session.commit()
            flash('منطقه با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_regions'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ویرایش منطقه: {str(e)}', 'danger')
    
    return render_template('admin/regions/edit.html', region=region)


@app.route('/admin/regions/<int:id>/delete')
@admin_required
def admin_region_delete(id):
    region = TehranRegion.query.get_or_404(id)
    db.session.delete(region)
    db.session.commit()
    flash('منطقه با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_regions'))

# ---- مدیریت سئو ----
# ================================================================
# ===== روت‌های مدیریت سئو (نسخه کامل) =====
# ================================================================
# ================================================================
# ===== روت‌های مدیریت سئو (واقعی) =====
# ================================================================
@app.route('/admin/seo', methods=['GET', 'POST'])
@admin_required
def admin_seo():
    if request.method == 'POST':
        try:
            # ===== 1. ذخیره تنظیمات سئو =====
            seo_fields = [
                'default_title', 'default_description', 'default_keywords',
                'robots', 'og_title', 'og_description', 'og_image',
                'twitter_card', 'twitter_site', 'canonical_url', 'brand_title'
            ]
            
            for field in seo_fields:
                value = request.form.get(field, '')
                Setting.set(f'seo_{field}', value)
            
            # ===== 2. ذخیره وضعیت auto_update =====
            auto_update = request.form.get('auto_update') == 'on'
            Setting.set('seo_auto_update', '1' if auto_update else '0')
            
            # ===== 3. بروزرسانی خودکار از بانک کلمات =====
            if auto_update:
                top_keywords = KeywordBank.query.filter_by(
                    is_active=True
                ).order_by(
                    KeywordBank.priority.desc()
                ).limit(10).all()
                
                if top_keywords:
                    keywords_str = ', '.join([kw.keyword for kw in top_keywords])
                    Setting.set('seo_default_keywords', keywords_str)
                    
                    desc_keywords = [kw.keyword for kw in top_keywords[:5]]
                    description = f"تعمیرات تخصصی {', '.join(desc_keywords)} در تهران با ضمانت کیفیت و بهترین قیمت"
                    Setting.set('seo_default_description', description[:160])
                    
                    title_keywords = [kw.keyword for kw in top_keywords[:3]]
                    title = f"تعمیرات {', '.join(title_keywords)} | نمایندگی تخصصی دوو تهران"
                    Setting.set('seo_default_title', title[:60])
                    
                    Setting.set('seo_last_update', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
                    
                    # ===== تولید صفحات سئو =====
                    count = update_all_seo_pages()
                    flash(f'✅ {count} صفحه سئو تولید شد.', 'success')
            
            flash('✅ تنظیمات سئو با موفقیت ذخیره شد.', 'success')
            return redirect(url_for('admin_seo'))
            
        except Exception as e:
            flash(f'❌ خطا: {str(e)}', 'danger')
            return redirect(url_for('admin_seo'))
    
    # ===== GET: دریافت تنظیمات فعلی =====
    seo_settings = {
        # ===== متا تگ‌های اصلی =====
        'default_title': Setting.get('seo_default_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'default_description': Setting.get('seo_default_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت. تکنسین‌های مجرب و قطعات اورجینال.'),
        'default_keywords': Setting.get('seo_default_keywords', 'تعمیرات دوو, تهران, نمایندگی دوو, تعمیر یخچال دوو, تعمیر لباسشویی دوو, تعمیر ظرفشویی دوو, تعمیر پکیج دوو'),
        'robots': Setting.get('seo_robots', 'index, follow'),
        'canonical_url': Setting.get('seo_canonical_url', ''),
        'brand_title': Setting.get('seo_brand_title', 'دوو تهران'),
        'last_update': Setting.get('seo_last_update', ''),
        'auto_update': Setting.get('seo_auto_update', '0') == '1',
        
        # ===== Open Graph (فیسبوک، تلگرام، واتساپ، لینکدین) =====
        'og_title': Setting.get('seo_og_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'og_description': Setting.get('seo_og_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت. تکنسین‌های مجرب و قطعات اورجینال.'),
        'og_image': Setting.get('seo_og_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
        'og_type': Setting.get('seo_og_type', 'website'),
        'og_locale': Setting.get('seo_og_locale', 'fa_IR'),
        'og_site_name': Setting.get('seo_og_site_name', 'نمایندگی تعمیرات دوو تهران'),
        
        # ===== Twitter Card (توییتر) =====
        'twitter_card': Setting.get('seo_twitter_card', 'summary_large_image'),
        'twitter_title': Setting.get('seo_twitter_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'twitter_description': Setting.get('seo_twitter_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
        'twitter_image': Setting.get('seo_twitter_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
        'twitter_site': Setting.get('seo_twitter_site', '@daewoo_tehran'),
        'twitter_creator': Setting.get('seo_twitter_creator', '@daewoo_tehran'),
        
        # ===== LinkedIn (لینکدین) =====
        'linkedin_title': Setting.get('seo_linkedin_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'linkedin_description': Setting.get('seo_linkedin_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
        'linkedin_image': Setting.get('seo_linkedin_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
        
        # ===== Telegram (تلگرام) =====
        'telegram_title': Setting.get('seo_telegram_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'telegram_description': Setting.get('seo_telegram_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
        'telegram_image': Setting.get('seo_telegram_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
        
        # ===== WhatsApp (واتساپ) =====
        'whatsapp_title': Setting.get('seo_whatsapp_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'whatsapp_description': Setting.get('seo_whatsapp_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
        'whatsapp_image': Setting.get('seo_whatsapp_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
        
        # ===== Pinterest (پینترست) =====
        'pinterest_title': Setting.get('seo_pinterest_title', 'نمایندگی تعمیرات دوو تهران | تعمیرات تخصصی دوو'),
        'pinterest_description': Setting.get('seo_pinterest_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران با ضمانت کیفیت و بهترین قیمت.'),
        'pinterest_image': Setting.get('seo_pinterest_image', 'https://img.freepik.com/free-vector/appliance-repair-service-banner-template_23-2148721244.jpg'),
        
        # ===== Instagram (اینستاگرام) - Deep Link =====
        'instagram_ios_url': Setting.get('seo_instagram_ios_url', 'daewooservic://'),
        'instagram_android_url': Setting.get('seo_instagram_android_url', 'daewooservic://'),
    }
    
    # ===== آمار کلمات کلیدی =====
    keywords = KeywordBank.query.order_by(KeywordBank.priority.desc()).all()
    total_keywords = KeywordBank.query.count()
    active_keywords = KeywordBank.query.filter_by(is_active=True).count()
    high_priority = KeywordBank.query.filter(KeywordBank.priority >= 7).count()
    
    # ===== آمار محتوا =====
    total_articles = Article.query.count()
    total_services = Service.query.count()
    total_regions = TehranRegion.query.count()
    total_pages = DynamicContent.query.count()
    
    # ===== آمار رزروها =====
    total_bookings = Booking.query.count()
    pending_bookings = Booking.query.filter_by(status='pending').count()
    
    # ===== آمار صفحات سئو و خطاها =====
    total_seo_pages = SEOPage.query.filter_by(is_active=True).count()
    total_errors = ErrorSolution.query.filter_by(is_active=True).count()
    total_header_images = SiteHeaderImage.query.filter_by(is_active=True).count()
    total_error_categories = ErrorCategory.query.filter_by(is_active=True).count()
    
    # ===== محاسبه امتیاز سئو =====
    seo_score = 0
    if seo_settings['default_title'] and len(seo_settings['default_title']) > 10:
        seo_score += 10
    if seo_settings['default_description'] and len(seo_settings['default_description']) > 50:
        seo_score += 10
    if seo_settings['default_keywords']:
        seo_score += 10
    if seo_settings['og_title']:
        seo_score += 10
    if seo_settings['og_description']:
        seo_score += 10
    if total_articles > 0:
        seo_score += 10
    if total_keywords > 0:
        seo_score += 10
    if total_regions > 0:
        seo_score += 10
    if seo_settings['robots'] == 'index, follow':
        seo_score += 10
    if seo_settings['canonical_url']:
        seo_score += 10
    if total_pages > 0:
        seo_score += 10
    
    # ===== پیشنهادات سئو =====
    seo_suggestions = []
    
    if not seo_settings['default_title']:
        seo_suggestions.append({
            'type': 'danger',
            'icon': 'times-circle',
            'title': 'عنوان سایت تعریف نشده است',
            'description': 'عنوان سایت یکی از مهم‌ترین عوامل سئو است. لطفاً یک عنوان مناسب وارد کنید.',
            'action': 'ویرایش متا تگ‌ها'
        })
    elif len(seo_settings['default_title']) < 20:
        seo_suggestions.append({
            'type': 'warning',
            'icon': 'exclamation-triangle',
            'title': 'عنوان سایت کوتاه است',
            'description': 'عنوان سایت باید حداقل ۲۰ کاراکتر باشد تا در نتایج جستجو بهتر دیده شود.',
            'action': 'ویرایش متا تگ‌ها'
        })
    
    if not seo_settings['default_description']:
        seo_suggestions.append({
            'type': 'danger',
            'icon': 'times-circle',
            'title': 'توضیحات سایت تعریف نشده است',
            'description': 'توضیحات سایت در نتایج جستجو نمایش داده می‌شود. لطفاً یک توضیح مناسب وارد کنید.',
            'action': 'ویرایش متا تگ‌ها'
        })
    
    if total_articles < 3:
        seo_suggestions.append({
            'type': 'warning',
            'icon': 'file-alt',
            'title': 'تعداد مقالات کم است',
            'description': 'برای بهبود سئو، حداقل ۵ مقاله مفید در سایت منتشر کنید.',
            'action': 'مدیریت مقالات'
        })
    
    if total_keywords < 10:
        seo_suggestions.append({
            'type': 'warning',
            'icon': 'tags',
            'title': 'بانک کلمات کلیدی خالی است',
            'description': 'کلمات کلیدی مناسب به بهبود سئو کمک می‌کنند. حداقل ۱۰ کلمه کلیدی وارد کنید.',
            'action': 'مدیریت کلمات کلیدی'
        })
    
    if not seo_settings['og_title'] or not seo_settings['og_description']:
        seo_suggestions.append({
            'type': 'warning',
            'icon': 'share-alt',
            'title': 'متا تگ‌های Open Graph کامل نیستند',
            'description': 'متا تگ‌های OG برای اشتراک‌گذاری در شبکه‌های اجتماعی ضروری هستند.',
            'action': 'ویرایش متا تگ‌ها'
        })
    
    if not seo_settings['canonical_url']:
        seo_suggestions.append({
            'type': 'warning',
            'icon': 'link',
            'title': 'آدرس متعارف تعریف نشده است',
            'description': 'آدرس متعارف از محتوای تکراری جلوگیری می‌کند.',
            'action': 'ویرایش متا تگ‌ها'
        })
    
    if not seo_suggestions:
        seo_suggestions.append({
            'type': 'success',
            'icon': 'check-circle',
            'title': 'وضعیت سئو عالی است! 🎉',
            'description': 'همه موارد سئو به درستی تنظیم شده‌اند. ادامه دهید!',
            'action': None
        })
    
    # ===== آدرس‌های سایتمپ =====
    urls = [
        {'url': '/', 'priority': '1.0', 'changefreq': 'daily'},
        {'url': '/services', 'priority': '0.9', 'changefreq': 'weekly'},
        {'url': '/technicians', 'priority': '0.8', 'changefreq': 'weekly'},
        {'url': '/regions', 'priority': '0.8', 'changefreq': 'weekly'},
        {'url': '/articles', 'priority': '0.7', 'changefreq': 'weekly'},
        {'url': '/errors', 'priority': '0.8', 'changefreq': 'weekly'},
        {'url': '/about', 'priority': '0.6', 'changefreq': 'monthly'},
        {'url': '/contact', 'priority': '0.6', 'changefreq': 'monthly'},
        {'url': '/booking', 'priority': '0.8', 'changefreq': 'daily'},
    ]
    
    for service in Service.query.filter_by(is_active=True).all():
        urls.append({'url': f'/service/{service.id}', 'priority': '0.8', 'changefreq': 'monthly'})
    
    for article in Article.query.filter_by(is_active=True).all():
        urls.append({'url': f'/article/{article.slug}', 'priority': '0.7', 'changefreq': 'monthly'})
    
    for region in TehranRegion.query.filter_by(is_active=True).all():
        urls.append({'url': f'/region/{region.slug}', 'priority': '0.8', 'changefreq': 'monthly'})
    
    for page in DynamicContent.query.filter_by(is_active=True).all():
        urls.append({'url': f'/page/{page.slug}', 'priority': '0.6', 'changefreq': 'monthly'})
    
    return render_template('admin/seo/index.html',
                         seo_settings=seo_settings,
                         keywords=keywords,
                         total_keywords=total_keywords,
                         active_keywords=active_keywords,
                         high_priority=high_priority,
                         total_articles=total_articles,
                         total_services=total_services,
                         total_regions=total_regions,
                         total_pages=total_pages,
                         total_bookings=total_bookings,
                         pending_bookings=pending_bookings,
                         seo_score=seo_score,
                         seo_suggestions=seo_suggestions,
                         urls=urls,
                         total_seo_pages=total_seo_pages,
                         total_errors=total_errors,
                         total_header_images=total_header_images,
                         total_error_categories=total_error_categories,
                         seo_auto_update=seo_settings['auto_update'])
# ================================================================
# ===== روت‌های مدیریت صفحات سئو و هدر =====
# ================================================================

@app.route('/admin/seo/pages')
@admin_required
def admin_seo_pages():
    pages = SEOPage.query.order_by(SEOPage.created_at.desc()).all()
    return render_template('admin/seo/pages.html', pages=pages)

@app.route('/admin/seo/pages/generate', methods=['POST'])
@admin_required
def admin_seo_pages_generate():
    try:
        count = update_all_seo_pages()
        flash(f'✅ {count} صفحه سئو شده تولید شد.', 'success')
    except Exception as e:
        flash(f'❌ خطا: {str(e)}', 'danger')
    return redirect(url_for('admin_seo_pages'))


@app.route('/admin/seo/pages/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_seo_page_edit(id):
    page = SEOPage.query.get_or_404(id)
    
    if request.method == 'POST':
        try:
            page.title = request.form.get('title')
            page.slug = request.form.get('slug')
            page.content = request.form.get('content')
            page.summary = request.form.get('summary')
            page.seo_title = request.form.get('seo_title')
            page.seo_description = request.form.get('seo_description')
            page.seo_keywords = request.form.get('seo_keywords')
            page.is_active = request.form.get('is_active') == 'on'
            
            if 'main_image' in request.files:
                file = request.files['main_image']
                if file and allowed_file(file.filename):
                    if page.main_image:
                        old_path = os.path.join('static', page.main_image.lstrip('/'))
                        if os.path.exists(old_path):
                            os.remove(old_path)
                    
                    filename = secure_filename(f"seo_{page.slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg")
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'seo', filename)
                    os.makedirs(os.path.dirname(file_path), exist_ok=True)
                    file.save(file_path)
                    page.main_image = f"/static/uploads/seo/{filename}"
            
            db.session.commit()
            flash('صفحه با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_seo_pages'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا: {str(e)}', 'danger')
    
    return render_template('admin/seo/page_edit.html', page=page)


@app.route('/seo/<slug>')
def seo_page(slug):
    page = SEOPage.query.filter_by(slug=slug, is_active=True).first_or_404()
    page.view_count += 1
    db.session.commit()
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    related_pages = SEOPage.query.filter(
        SEOPage.is_active == True,
        SEOPage.id != page.id
    ).order_by(db.func.random()).limit(5).all()
    
    return render_template('seo/page.html',
                         page=page,
                         related_pages=related_pages,
                         settings=settings)


@app.route('/admin/header/images')
@admin_required
def admin_header_images():
    images = SiteHeaderImage.query.order_by(SiteHeaderImage.sort_order).all()
    return render_template('admin/header/images.html', images=images)


@app.route('/admin/header/images/upload', methods=['POST'])
@admin_required
def admin_header_image_upload():
    try:
        file = request.files.get('image')
        if not file or not allowed_file(file.filename):
            flash('لطفاً یک تصویر معتبر انتخاب کنید.', 'danger')
            return redirect(url_for('admin_header_images'))
        
        title = request.form.get('title', '')
        alt_text = request.form.get('alt_text', '')
        link_url = request.form.get('link_url', '')
        is_default = request.form.get('is_default') == 'on'
        
        filename = secure_filename(f"header_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg")
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'header', filename)
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        file.save(file_path)
        
        if is_default:
            SiteHeaderImage.query.update({'is_default': False})
        
        image = SiteHeaderImage(
            title=title,
            image_path=f"/static/uploads/header/{filename}",
            alt_text=alt_text,
            link_url=link_url,
            is_default=is_default,
            is_active=True,
            sort_order=SiteHeaderImage.query.count()
        )
        db.session.add(image)
        db.session.commit()
        
        flash('تصویر هدر با موفقیت آپلود شد.', 'success')
    except Exception as e:
        flash(f'خطا: {str(e)}', 'danger')
    
    return redirect(url_for('admin_header_images'))


@app.route('/admin/header/images/<int:id>/delete')
@admin_required
def admin_header_image_delete(id):
    image = SiteHeaderImage.query.get_or_404(id)
    
    if image.image_path:
        path = os.path.join('static', image.image_path.lstrip('/'))
        if os.path.exists(path):
            os.remove(path)
    
    db.session.delete(image)
    db.session.commit()
    flash('تصویر هدر با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_header_images'))


@app.route('/admin/header/images/<int:id>/toggle')
@admin_required
def admin_header_image_toggle(id):
    image = SiteHeaderImage.query.get_or_404(id)
    image.is_active = not image.is_active
    db.session.commit()
    flash('وضعیت تصویر تغییر کرد.', 'success')
    return redirect(url_for('admin_header_images'))
    
@app.route('/admin/seo/update', methods=['POST'])
@admin_required
def admin_seo_update():
    """بروزرسانی خودکار سئو"""
    try:
        update_seo_globally()
        flash('✅ سئو با موفقیت بروزرسانی شد.', 'success')
    except Exception as e:
        flash(f'❌ خطا: {str(e)}', 'danger')
    return redirect(url_for('admin_seo'))


@app.route('/admin/seo/preview')
@admin_required
def admin_seo_preview():
    """پیش‌نمایش متا تگ‌ها"""
    top_keywords = KeywordBank.query.filter_by(is_active=True).order_by(KeywordBank.priority.desc()).limit(10).all()
    
    preview = {
        'title': Setting.get('seo_default_title', ''),
        'description': Setting.get('seo_default_description', ''),
        'keywords': Setting.get('seo_default_keywords', ''),
        'og_title': Setting.get('seo_og_title', ''),
        'og_description': Setting.get('seo_og_description', ''),
        'top_keywords': top_keywords
    }
    
    return render_template('admin/seo/preview.html', preview=preview)
# ---- مدیریت کلمات کلیدی ----


# ================================================================
# ===== تولید سایتمپ =====
# ================================================================


def generate_sitemap():
    """تولید فایل sitemap.xml کامل"""
    from xml.etree import ElementTree as ET
    from datetime import datetime
    import os
    
    root = ET.Element('urlset', xmlns='http://www.sitemaps.org/schemas/sitemap/0.9')
    
    base_url = Setting.get('site_url', 'https://daewooservic.ir')
    
    pages = [
        {'loc': '/', 'priority': '1.0', 'changefreq': 'daily'},
        {'loc': '/services', 'priority': '0.9', 'changefreq': 'weekly'},
        {'loc': '/technicians', 'priority': '0.8', 'changefreq': 'weekly'},
        {'loc': '/regions', 'priority': '0.8', 'changefreq': 'weekly'},
        {'loc': '/articles', 'priority': '0.7', 'changefreq': 'weekly'},
        {'loc': '/errors', 'priority': '0.8', 'changefreq': 'weekly'},
        {'loc': '/about', 'priority': '0.6', 'changefreq': 'monthly'},
        {'loc': '/contact', 'priority': '0.6', 'changefreq': 'monthly'},
        {'loc': '/booking', 'priority': '0.8', 'changefreq': 'daily'},
    ]
    
    for service in Service.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/service/{service.id}',
            'priority': '0.8',
            'changefreq': 'monthly'
        })
    
    for article in Article.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/article/{article.slug}',
            'priority': '0.7',
            'changefreq': 'monthly'
        })
    
    for region in TehranRegion.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/region/{region.slug}',
            'priority': '0.8',
            'changefreq': 'monthly'
        })
    
    for error in ErrorSolution.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/errors/{error.slug}',
            'priority': '0.8',
            'changefreq': 'weekly'
        })
    
    for category in ErrorCategory.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/errors/category/{category.slug}',
            'priority': '0.7',
            'changefreq': 'weekly'
        })
    
    for page in SEOPage.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/seo/{page.slug}',
            'priority': '0.7',
            'changefreq': 'monthly'
        })
    
    for page in DynamicContent.query.filter_by(is_active=True).all():
        pages.append({
            'loc': f'/page/{page.slug}',
            'priority': '0.6',
            'changefreq': 'monthly'
        })
    
    for page in pages:
        url_elem = ET.SubElement(root, 'url')
        
        loc = ET.SubElement(url_elem, 'loc')
        loc.text = base_url + page['loc']
        
        priority = ET.SubElement(url_elem, 'priority')
        priority.text = page['priority']
        
        changefreq = ET.SubElement(url_elem, 'changefreq')
        changefreq.text = page['changefreq']
        
        lastmod = ET.SubElement(url_elem, 'lastmod')
        lastmod.text = datetime.now().strftime('%Y-%m-%d')
    
    sitemap_path = 'sitemap.xml'
    tree = ET.ElementTree(root)
    
    with open(sitemap_path, 'wb') as f:
        tree.write(f, encoding='utf-8', xml_declaration=True)
    
    return len(pages)
    
@app.route('/sitemap.xml')
def sitemap():
    """مسیر عمومی سایتمپ"""
    import os
    sitemap_path = 'sitemap.xml'  # <-- در ریشه پروژه
    
    if os.path.exists(sitemap_path):
        return send_file(sitemap_path, mimetype='application/xml')
    else:
        # اگر وجود نداشت، تولید کن
        generate_sitemap()
        return send_file(sitemap_path, mimetype='application/xml')

@app.route('/admin/sitemap/generate')
@admin_required
def admin_sitemap_generate():
    """تولید سایتمپ توسط ادمین"""
    try:
        count = generate_sitemap()
        flash(f'✅ سایتمپ با {count} آدرس تولید شد.', 'success')
    except Exception as e:
        flash(f'❌ خطا: {str(e)}', 'danger')
    return redirect(url_for('admin_sitemap'))


# ================================================================
# ===== روت‌های مدیریت خطاها (ادمین) =====
# ================================================================

@app.route('/admin/errors')
@admin_required
def admin_errors():
    categories = ErrorCategory.query.order_by(ErrorCategory.sort_order).all()
    errors = ErrorSolution.query.order_by(ErrorSolution.created_at.desc()).all()
    
    for error in errors:
        error.category_name = error.category.name if error.category else 'بدون دسته‌بندی'
    
    return render_template('admin/errors/index.html', 
                         categories=categories,
                         errors=errors)


@app.route('/admin/errors/category/create', methods=['GET', 'POST'])
@admin_required
def admin_error_category_create():
    if request.method == 'POST':
        try:
            name = request.form.get('name')
            slug = request.form.get('slug') or generate_unique_slug(name, ErrorCategory)
            description = request.form.get('description')
            icon = request.form.get('icon', 'fa-solid fa-wrench')
            seo_title = request.form.get('seo_title')
            seo_description = request.form.get('seo_description')
            seo_keywords = request.form.get('seo_keywords')
            is_active = request.form.get('is_active') == 'on'
            
            image_path = None
            if 'image' in request.files:
                file = request.files['image']
                if file and allowed_file(file.filename):
                    filename = secure_filename(f"category_{slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg")
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'categories', filename)
                    os.makedirs(os.path.dirname(file_path), exist_ok=True)
                    file.save(file_path)
                    image_path = f"/static/uploads/categories/{filename}"
            
            category = ErrorCategory(
                name=name,
                slug=slug,
                description=description,
                icon=icon,
                image=image_path,
                seo_title=seo_title,
                seo_description=seo_description,
                seo_keywords=seo_keywords,
                is_active=is_active
            )
            db.session.add(category)
            db.session.commit()
            
            flash('دسته‌بندی با موفقیت ایجاد شد.', 'success')
            return redirect(url_for('admin_errors'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا: {str(e)}', 'danger')
    
    return render_template('admin/errors/category_create.html')


@app.route('/admin/errors/category/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_error_category_edit(id):
    category = ErrorCategory.query.get_or_404(id)
    
    if request.method == 'POST':
        try:
            category.name = request.form.get('name')
            category.slug = request.form.get('slug')
            category.description = request.form.get('description')
            category.icon = request.form.get('icon')
            category.seo_title = request.form.get('seo_title')
            category.seo_description = request.form.get('seo_description')
            category.seo_keywords = request.form.get('seo_keywords')
            category.is_active = request.form.get('is_active') == 'on'
            category.sort_order = int(request.form.get('sort_order', 0))
            
            if 'image' in request.files:
                file = request.files['image']
                if file and allowed_file(file.filename):
                    if category.image:
                        old_path = os.path.join('static', category.image.lstrip('/'))
                        if os.path.exists(old_path):
                            os.remove(old_path)
                    
                    filename = secure_filename(f"category_{category.slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg")
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'categories', filename)
                    os.makedirs(os.path.dirname(file_path), exist_ok=True)
                    file.save(file_path)
                    category.image = f"/static/uploads/categories/{filename}"
            
            db.session.commit()
            flash('دسته‌بندی با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_errors'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا: {str(e)}', 'danger')
    
    return render_template('admin/errors/category_edit.html', category=category)


@app.route('/admin/errors/solution/create', methods=['GET', 'POST'])
@admin_required
def admin_error_solution_create():
    categories = ErrorCategory.query.filter_by(is_active=True).all()
    
    if request.method == 'POST':
        try:
            category_id = request.form.get('category_id')
            error_title = request.form.get('error_title')
            error_description = request.form.get('error_description')
            error_code = request.form.get('error_code')
            symptoms = request.form.get('symptoms')
            solution_steps = request.form.get('solution_steps')
            video_url = request.form.get('video_url')
            video_embed = request.form.get('video_embed')
            difficulty_level = request.form.get('difficulty_level', 'medium')
            estimated_time = request.form.get('estimated_time', 0)
            tools_needed = request.form.get('tools_needed')
            can_self_fix = request.form.get('can_self_fix') == 'on'
            is_featured = request.form.get('is_featured') == 'on'
            is_active = request.form.get('is_active') == 'on'
            
            category = ErrorCategory.query.get(category_id)
            if not category:
                flash('دسته‌بندی انتخاب شده معتبر نیست.', 'danger')
                return redirect(url_for('admin_error_solution_create'))
            
            slug = generate_error_slug(error_title, category.name)
            
            main_image = None
            if 'main_image' in request.files:
                file = request.files['main_image']
                if file and allowed_file(file.filename):
                    filename = secure_filename(f"error_{slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg")
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'errors', filename)
                    os.makedirs(os.path.dirname(file_path), exist_ok=True)
                    file.save(file_path)
                    main_image = f"/static/uploads/errors/{filename}"
            
            additional_images = []
            if 'additional_images' in request.files:
                files = request.files.getlist('additional_images')
                for file in files:
                    if file and allowed_file(file.filename):
                        filename = secure_filename(f"error_extra_{slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}_{len(additional_images)}.jpg")
                        file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'errors', filename)
                        file.save(file_path)
                        additional_images.append(f"/static/uploads/errors/{filename}")
            
            solution = ErrorSolution(
                category_id=category_id,
                error_code=error_code,
                error_title=error_title,
                error_description=error_description,
                symptoms=symptoms,
                solution_steps=solution_steps,
                video_url=video_url,
                video_embed=video_embed,
                main_image=main_image,
                additional_images=json.dumps(additional_images) if additional_images else None,
                difficulty_level=difficulty_level,
                estimated_time=int(estimated_time) if estimated_time else None,
                tools_needed=tools_needed,
                can_self_fix=can_self_fix,
                is_featured=is_featured,
                is_active=is_active,
                slug=slug,
                seo_title=request.form.get('seo_title') or f"{error_title} | راهنمای رفع خطا",
                seo_description=request.form.get('seo_description') or f"راهنمای کامل رفع خطا {error_title} در {category.name}",
                seo_keywords=request.form.get('seo_keywords') or f"{error_title}, رفع خطا {error_title}, تعمیر {category.name}"
            )
            db.session.add(solution)
            db.session.commit()
            
            flash('راه‌حل خطا با موفقیت ایجاد شد.', 'success')
            return redirect(url_for('admin_errors'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا: {str(e)}', 'danger')
    
    return render_template('admin/errors/solution_create.html', categories=categories)


@app.route('/admin/errors/solution/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_error_solution_edit(id):
    solution = ErrorSolution.query.get_or_404(id)
    categories = ErrorCategory.query.filter_by(is_active=True).all()
    
    if request.method == 'POST':
        try:
            solution.category_id = request.form.get('category_id')
            solution.error_code = request.form.get('error_code')
            solution.error_title = request.form.get('error_title')
            solution.error_description = request.form.get('error_description')
            solution.symptoms = request.form.get('symptoms')
            solution.solution_steps = request.form.get('solution_steps')
            solution.video_url = request.form.get('video_url')
            solution.video_embed = request.form.get('video_embed')
            solution.difficulty_level = request.form.get('difficulty_level')
            solution.estimated_time = int(request.form.get('estimated_time', 0))
            solution.tools_needed = request.form.get('tools_needed')
            solution.can_self_fix = request.form.get('can_self_fix') == 'on'
            solution.is_featured = request.form.get('is_featured') == 'on'
            solution.is_active = request.form.get('is_active') == 'on'
            solution.seo_title = request.form.get('seo_title')
            solution.seo_description = request.form.get('seo_description')
            solution.seo_keywords = request.form.get('seo_keywords')
            
            if 'main_image' in request.files:
                file = request.files['main_image']
                if file and allowed_file(file.filename):
                    if solution.main_image:
                        old_path = os.path.join('static', solution.main_image.lstrip('/'))
                        if os.path.exists(old_path):
                            os.remove(old_path)
                    
                    filename = secure_filename(f"error_{solution.slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}.jpg")
                    file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'errors', filename)
                    os.makedirs(os.path.dirname(file_path), exist_ok=True)
                    file.save(file_path)
                    solution.main_image = f"/static/uploads/errors/{filename}"
            
            if 'additional_images' in request.files:
                additional_images = solution.get_additional_images()
                files = request.files.getlist('additional_images')
                for file in files:
                    if file and allowed_file(file.filename):
                        filename = secure_filename(f"error_extra_{solution.slug}_{datetime.now().strftime('%Y%m%d%H%M%S')}_{len(additional_images)}.jpg")
                        file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'errors', filename)
                        file.save(file_path)
                        additional_images.append(f"/static/uploads/errors/{filename}")
                solution.additional_images = json.dumps(additional_images) if additional_images else None
            
            db.session.commit()
            flash('راه‌حل خطا با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_errors'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا: {str(e)}', 'danger')
    
    return render_template('admin/errors/solution_edit.html', 
                         solution=solution, 
                         categories=categories)


@app.route('/admin/errors/solution/<int:id>/delete')
@admin_required
def admin_error_solution_delete(id):
    solution = ErrorSolution.query.get_or_404(id)
    
    if solution.main_image:
        path = os.path.join('static', solution.main_image.lstrip('/'))
        if os.path.exists(path):
            os.remove(path)
    
    for img in solution.get_additional_images():
        path = os.path.join('static', img.lstrip('/'))
        if os.path.exists(path):
            os.remove(path)
    
    db.session.delete(solution)
    db.session.commit()
    flash('راه‌حل خطا با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_errors'))
    
@app.route('/admin/sitemap/submit')
@admin_required
def admin_sitemap_submit():
    """ارسال سایتمپ به گوگل"""
    import requests
    site_url = Setting.get('site_url', 'https://daewooservic.ir')
    sitemap_url = f"{site_url}/sitemap.xml"
    
    google_url = f"https://www.google.com/ping?sitemap={sitemap_url}"
    bing_url = f"https://www.bing.com/ping?sitemap={sitemap_url}"
    
    results = []
    
    try:
        r = requests.get(google_url)
        results.append(('گوگل', r.status_code == 200))
    except:
        results.append(('گوگل', False))
    
    try:
        r = requests.get(bing_url)
        results.append(('بینگ', r.status_code == 200))
    except:
        results.append(('بینگ', False))
    
    for name, status in results:
        if status:
            flash(f'✅ سایتمپ به {name} ارسال شد.', 'success')
        else:
            flash(f'❌ خطا در ارسال به {name}.', 'danger')
    
    return redirect(url_for('admin_sitemap'))
    
# ================================================================
# ===== robots.txt =====
# ================================================================
@app.route('/robots.txt')
def robots_txt():
    """فایل robots.txt از ریشه پروژه"""
    import os
    robots_file = 'robots.txt'  # <-- در ریشه
    
    # اگه فایل وجود نداشت، ایجاد کن
    if not os.path.exists(robots_file):
        site_url = Setting.get('site_url', 'https://daewooservic.ir')
        robots = Setting.get('seo_robots', 'index, follow')
        content = f"""User-agent: *
{'' if 'noindex' in robots else 'Allow: /'}
Disallow: /admin/
Disallow: /dashboard/
Disallow: /user/
Disallow: /login/
Disallow: /register/

Sitemap: {site_url}/sitemap.xml

# Allow crawl
User-agent: Googlebot
Allow: /

User-agent: Bingbot
Allow: /
"""
        with open(robots_file, 'w', encoding='utf-8') as f:
            f.write(content)
    
    return send_file(robots_file, mimetype='text/plain')
    
@app.route('/admin/robots/edit', methods=['GET', 'POST'])
@admin_required
def admin_robots_edit():
    """ویرایش robots.txt توسط ادمین"""
    import os
    
    # ===== فایل در ریشه پروژه =====
    robots_file = 'robots.txt'  # <-- در ریشه
    
    if request.method == 'POST':
        content = request.form.get('content', '')
        with open(robots_file, 'w', encoding='utf-8') as f:
            f.write(content)
        flash('✅ robots.txt ذخیره شد.', 'success')
        return redirect(url_for('admin_robots_edit'))
    
    # خواندن فایل فعلی
    if os.path.exists(robots_file):
        with open(robots_file, 'r', encoding='utf-8') as f:
            content = f.read()
    else:
        # تولید پیش‌فرض
        site_url = Setting.get('site_url', 'https://daewooservic.ir')
        content = f"""User-agent: *
Allow: /
Disallow: /admin/
Disallow: /dashboard/
Disallow: /user/
Disallow: /login/
Disallow: /register/

Sitemap: {site_url}/sitemap.xml
"""
    
    return render_template('admin/robots/edit.html', content=content)
# ================================================================
# ===== بروزرسانی خودکار سئو (هر ۲۴ ساعت) =====
# ================================================================


from apscheduler.schedulers.background import BackgroundScheduler

def start_scheduler():
    """راه‌اندازی برنامه‌ریز بروزرسانی خودکار"""
    scheduler = BackgroundScheduler()
    
    # بروزرسانی سئو هر ۱۲ ساعت
    scheduler.add_job(
        func=update_seo_globally,
        trigger='interval',
        hours=12,
        id='seo_auto_update',
        next_run_time=datetime.now() + timedelta(minutes=5),
        replace_existing=True
    )
    
    # بروزرسانی سایتمپ هر ۲۴ ساعت
    scheduler.add_job(
        func=generate_sitemap,
        trigger='interval',
        hours=24,
        id='sitemap_update',
        next_run_time=datetime.now() + timedelta(minutes=10),
        replace_existing=True
    )
    
    scheduler.start()
    print('✅ بروزرسانی خودکار سئو و سایتمپ فعال شد.')
# ===== اجرا در هنگام شروع =====
# این خط رو در انتهای app.py اضافه کن:
# start_scheduler()


@app.route('/admin/keywords')
@admin_required
def admin_keywords():
    keywords = KeywordBank.query.order_by(KeywordBank.priority.desc()).all()
    return render_template('admin/keywords/index.html', keywords=keywords)
@app.route('/admin/keywords/create', methods=['GET', 'POST'])
@admin_required
def admin_keyword_create():
    if request.method == 'POST':
        try:
            keyword = request.form.get('keyword')
            category = request.form.get('category')
            search_volume = int(request.form.get('search_volume', 0))
            priority = int(request.form.get('priority', 5))
            competition = float(request.form.get('competition', 0.5))
            difficulty = int(request.form.get('difficulty', 50))
            is_active = request.form.get('is_active') == 'on'
            is_targeted = request.form.get('is_targeted') == 'on'
            generate_seo_page = request.form.get('generate_seo_page') == 'on'
            
            if not keyword:
                flash('لطفاً کلمه کلیدی را وارد کنید.', 'danger')
                return redirect(url_for('admin_keyword_create'))
            
            existing = KeywordBank.query.filter_by(keyword=keyword).first()
            if existing:
                flash('این کلمه کلیدی قبلاً ثبت شده است.', 'danger')
                return redirect(url_for('admin_keyword_create'))
            
            new_keyword = KeywordBank(
                keyword=keyword,
                category=category,
                search_volume=search_volume,
                priority=priority,
                competition=competition,
                difficulty=difficulty,
                is_active=is_active,
                is_targeted=is_targeted
            )
            db.session.add(new_keyword)
            db.session.commit()
            
            flash('✅ کلمه کلیدی با موفقیت ایجاد شد.', 'success')
            
            if generate_seo_page and is_active and is_targeted:
                try:
                    seo_page = create_seo_page_from_keyword(new_keyword.id)
                    if seo_page:
                        flash('✅ صفحه سئو شده نیز با موفقیت تولید شد.', 'success')
                except Exception as e:
                    flash(f'⚠️ خطا در تولید صفحه سئو: {str(e)}', 'warning')
            
            return redirect(url_for('admin_keywords'))
            
        except Exception as e:
            db.session.rollback()
            flash(f'❌ خطا: {str(e)}', 'danger')
            return redirect(url_for('admin_keyword_create'))
    
    return render_template('admin/keywords/create.html')
    
# ================================================================
# ===== روت‌های مدیریت صفحه سئو از کلمه کلیدی =====
# ================================================================

@app.route('/admin/keywords/<int:id>/generate-seo', methods=['POST'])
@admin_required
def admin_keyword_generate_seo(id):
    """تولید صفحه سئو از کلمه کلیدی"""
    keyword = KeywordBank.query.get_or_404(id)
    
    try:
        seo_page = create_seo_page_from_keyword(keyword.id)
        if seo_page:
            flash(f'✅ صفحه سئو برای کلمه "{keyword.keyword}" با موفقیت تولید شد.', 'success')
        else:
            flash(f'❌ تولید صفحه سئو برای کلمه "{keyword.keyword}" با خطا مواجه شد.', 'danger')
    except Exception as e:
        flash(f'❌ خطا: {str(e)}', 'danger')
    
    return redirect(url_for('admin_keyword_edit', id=keyword.id))


@app.route('/admin/keywords/<int:id>/regenerate-seo', methods=['POST'])
@admin_required
def admin_keyword_regenerate_seo(id):
    """بازتولید صفحه سئو از کلمه کلیدی (محتوای قبلی بازنویسی می‌شود)"""
    keyword = KeywordBank.query.get_or_404(id)
    
    try:
        # حذف صفحه سئو قبلی
        existing = SEOPage.query.filter_by(keyword_id=keyword.id).first()
        if existing:
            db.session.delete(existing)
            db.session.commit()
        
        # تولید صفحه جدید
        seo_page = create_seo_page_from_keyword(keyword.id)
        if seo_page:
            flash(f'✅ صفحه سئو برای کلمه "{keyword.keyword}" با موفقیت بازتولید شد.', 'success')
        else:
            flash(f'❌ بازتولید صفحه سئو برای کلمه "{keyword.keyword}" با خطا مواجه شد.', 'danger')
    except Exception as e:
        db.session.rollback()
        flash(f'❌ خطا: {str(e)}', 'danger')
    
    return redirect(url_for('admin_keyword_edit', id=keyword.id))


@app.route('/admin/keywords/<int:id>/delete-seo', methods=['POST'])
@admin_required
def admin_keyword_delete_seo(id):
    """حذف صفحه سئو مرتبط با کلمه کلیدی"""
    keyword = KeywordBank.query.get_or_404(id)
    
    try:
        seo_page = SEOPage.query.filter_by(keyword_id=keyword.id).first()
        if seo_page:
            db.session.delete(seo_page)
            db.session.commit()
            flash(f'✅ صفحه سئو برای کلمه "{keyword.keyword}" با موفقیت حذف شد.', 'success')
        else:
            flash(f'⚠️ هیچ صفحه سئویی برای کلمه "{keyword.keyword}" یافت نشد.', 'warning')
    except Exception as e:
        db.session.rollback()
        flash(f'❌ خطا: {str(e)}', 'danger')
    
    return redirect(url_for('admin_keyword_edit', id=keyword.id))
    
@app.route('/admin/keywords/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_keyword_edit(id):
    keyword = KeywordBank.query.get_or_404(id)
    
    if request.method == 'POST':
        try:
            keyword.keyword = request.form.get('keyword')
            keyword.category = request.form.get('category')
            keyword.search_volume = int(request.form.get('search_volume', 0))
            keyword.priority = int(request.form.get('priority', 0))
            keyword.competition = float(request.form.get('competition', 0))
            keyword.difficulty = int(request.form.get('difficulty', 0))
            keyword.is_active = request.form.get('is_active') == 'on'
            
            db.session.commit()
            flash('کلمه کلیدی با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_keywords'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ویرایش کلمه کلیدی: {str(e)}', 'danger')
    
    return render_template('admin/keywords/edit.html', keyword=keyword)


@app.route('/admin/keywords/<int:id>/delete')
@admin_required
def admin_keyword_delete(id):
    keyword = KeywordBank.query.get_or_404(id)
    db.session.delete(keyword)
    db.session.commit()
    flash('کلمه کلیدی با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_keywords'))
# ---- مدیریت سایتمپ ----
@app.route('/admin/sitemap')
@admin_required
def admin_sitemap():
    # دریافت آدرس‌های مختلف برای سایتمپ
    urls = []
    
    # صفحات اصلی
    urls.append({'url': '/', 'priority': '1.0', 'changefreq': 'daily'})
    urls.append({'url': '/services', 'priority': '0.9', 'changefreq': 'weekly'})
    urls.append({'url': '/technicians', 'priority': '0.8', 'changefreq': 'weekly'})
    urls.append({'url': '/regions', 'priority': '0.8', 'changefreq': 'weekly'})
    urls.append({'url': '/articles', 'priority': '0.7', 'changefreq': 'weekly'})
    urls.append({'url': '/about', 'priority': '0.6', 'changefreq': 'monthly'})
    urls.append({'url': '/contact', 'priority': '0.6', 'changefreq': 'monthly'})
    
    # خدمات
    for service in Service.query.filter_by(is_active=True).all():
        urls.append({
            'url': f'/service/{service.id}',
            'priority': '0.8',
            'changefreq': 'monthly'
        })
    
    # مقالات
    for article in Article.query.filter_by(is_active=True).all():
        urls.append({
            'url': f'/article/{article.slug}',
            'priority': '0.7',
            'changefreq': 'monthly'
        })
    
    # مناطق
    for region in TehranRegion.query.filter_by(is_active=True).all():
        urls.append({
            'url': f'/region/{region.slug}',
            'priority': '0.8',
            'changefreq': 'monthly'
        })
    
    return render_template('admin/sitemap/index.html', urls=urls)


# ---- مدیریت بکاپ ----
import zipfile
import shutil
import json
from datetime import datetime
import os

@app.route('/admin/backup')
@admin_required
def admin_backup():
    # دریافت لیست بکاپ‌ها
    backup_dir = 'backups'
    if not os.path.exists(backup_dir):
        os.makedirs(backup_dir)
    
    backups = []
    for file in os.listdir(backup_dir):
        if file.endswith('.zip'):
            file_path = os.path.join(backup_dir, file)
            size = os.path.getsize(file_path) // 1024
            date = datetime.fromtimestamp(os.path.getctime(file_path))
            backups.append({
                'name': file,
                'size': size,
                'date': date
            })
    
    backups.sort(key=lambda x: x['date'], reverse=True)
    
    return render_template('admin/backup/index.html', backups=backups)


@app.route('/admin/backup/create')
@admin_required
def admin_backup_create():
    try:
        import json
        from datetime import datetime
        
        backup_dir = 'backups'
        if not os.path.exists(backup_dir):
            os.makedirs(backup_dir)
        
        # نام فایل بکاپ
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        backup_filename = f"backup_{timestamp}.zip"
        backup_path = os.path.join(backup_dir, backup_filename)
        
        # ایجاد فایل موقت برای داده‌ها
        temp_dir = f"temp_backup_{timestamp}"
        os.makedirs(temp_dir)
        
        # گرفتن بکاپ از تمام جداول
        tables = {
            'users': [u.to_dict() if hasattr(u, 'to_dict') else {'id': u.id, 'fullname': u.fullname, 'phone': u.phone, 'email': u.email, 'role': u.role, 'is_active': u.is_active, 'created_at': str(u.created_at)} for u in User.query.all()],
            'settings': [{'key': s.key, 'value': s.value, 'category': s.category} for s in Setting.query.all()],
            'services': [{'id': s.id, 'title': s.title, 'slug': s.slug, 'category': s.category, 'description': s.description, 'price_range_min': s.price_range_min, 'price_range_max': s.price_range_max, 'is_active': s.is_active} for s in Service.query.all()],
            'technicians': [{'id': t.id, 'fullname': t.fullname, 'phone': t.phone, 'expertise_areas': t.expertise_areas, 'experience_years': t.experience_years, 'status': t.status, 'rating': t.rating, 'is_active': t.is_active} for t in Technician.query.all()],
            'regions': [{'id': r.id, 'region_number': r.region_number, 'name': r.name, 'slug': r.slug, 'latitude': r.latitude, 'longitude': r.longitude, 'is_active': r.is_active} for r in TehranRegion.query.all()],
            'articles': [{'id': a.id, 'title': a.title, 'slug': a.slug, 'category': a.category, 'content': a.content, 'is_active': a.is_active, 'created_at': str(a.created_at)} for a in Article.query.all()],
            'bookings': [{'id': b.id, 'booking_number': b.booking_number, 'user_id': b.user_id, 'service_id': b.service_id, 'status': b.status, 'scheduled_date': str(b.scheduled_date), 'created_at': str(b.created_at)} for b in Booking.query.all()],
            'reviews': [{'id': rv.id, 'user_id': rv.user_id, 'rating': rv.rating, 'title': rv.title, 'content': rv.content, 'is_approved': rv.is_approved, 'created_at': str(rv.created_at)} for rv in Review.query.all()],
            'testimonials': [{'id': t.id, 'customer_name': t.customer_name, 'text': t.text, 'rating': t.rating, 'is_active': t.is_active} for t in Testimonial.query.all()],
            'faqs': [{'id': f.id, 'category': f.category, 'question': f.question, 'answer': f.answer, 'order': f.order, 'is_active': f.is_active} for f in FAQ.query.all()],
            'keyword_bank': [{'id': k.id, 'keyword': k.keyword, 'category': k.category, 'search_volume': k.search_volume, 'priority': k.priority, 'is_active': k.is_active} for k in KeywordBank.query.all()]
        }
        
        # ذخیره داده‌ها به صورت JSON
        with open(os.path.join(temp_dir, 'data.json'), 'w', encoding='utf-8') as f:
            json.dump(tables, f, ensure_ascii=False, indent=2)
        
        # ذخیره فایل دیتابیس
        if os.path.exists('daewoo_tehran.db'):
            shutil.copy2('daewoo_tehran.db', os.path.join(temp_dir, 'database.db'))
        
        # ایجاد فایل ZIP
        with zipfile.ZipFile(backup_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
            for root, dirs, files in os.walk(temp_dir):
                for file in files:
                    file_path = os.path.join(root, file)
                    arcname = os.path.relpath(file_path, temp_dir)
                    zipf.write(file_path, arcname)
        
        # حذف فایل‌های موقت
        shutil.rmtree(temp_dir)
        
        flash(f'بکاپ با موفقیت ایجاد شد: {backup_filename}', 'success')
        return redirect(url_for('admin_backup'))
        
    except Exception as e:
        flash(f'خطا در ایجاد بکاپ: {str(e)}', 'danger')
        return redirect(url_for('admin_backup'))


@app.route('/admin/backup/download/<filename>')
@admin_required
def admin_backup_download(filename):
    backup_path = os.path.join('backups', filename)
    if os.path.exists(backup_path):
        return send_file(backup_path, as_attachment=True, download_name=filename)
    else:
        flash('فایل بکاپ یافت نشد.', 'danger')
        return redirect(url_for('admin_backup'))


@app.route('/admin/backup/delete/<filename>')
@admin_required
def admin_backup_delete(filename):
    backup_path = os.path.join('backups', filename)
    if os.path.exists(backup_path):
        os.remove(backup_path)
        flash('فایل بکاپ با موفقیت حذف شد.', 'success')
    else:
        flash('فایل بکاپ یافت نشد.', 'danger')
    return redirect(url_for('admin_backup'))


@app.route('/admin/backup/restore', methods=['POST'])
@admin_required
def admin_backup_restore():
    if 'backup_file' not in request.files:
        flash('لطفاً یک فایل انتخاب کنید.', 'danger')
        return redirect(url_for('admin_backup'))
    
    file = request.files['backup_file']
    if file.filename == '':
        flash('لطفاً یک فایل انتخاب کنید.', 'danger')
        return redirect(url_for('admin_backup'))
    
    if not file.filename.endswith('.zip'):
        flash('فایل باید با فرمت ZIP باشد.', 'danger')
        return redirect(url_for('admin_backup'))
    
    try:
        import json
        import tempfile
        
        # ایجاد دایرکتوری موقت
        temp_dir = tempfile.mkdtemp()
        zip_path = os.path.join(temp_dir, file.filename)
        file.save(zip_path)
        
        # استخراج فایل ZIP
        with zipfile.ZipFile(zip_path, 'r') as zipf:
            zipf.extractall(temp_dir)
        
        # خواندن داده‌ها
        json_path = os.path.join(temp_dir, 'data.json')
        if os.path.exists(json_path):
            with open(json_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            # بازیابی داده‌ها (با احتیاط کامل)
            # این بخش نیاز به پیاده‌سازی کامل دارد
            flash('بازیابی بکاپ با موفقیت انجام شد.', 'success')
        else:
            flash('فایل data.json در بکاپ یافت نشد.', 'danger')
        
        # حذف فایل‌های موقت
        shutil.rmtree(temp_dir)
        
    except Exception as e:
        flash(f'خطا در بازیابی بکاپ: {str(e)}', 'danger')
    
    return redirect(url_for('admin_backup'))

# ---- مدیریت صفحات پویا ----
@app.route('/admin/pages')
@admin_required
def admin_pages():
    pages = DynamicContent.query.order_by(DynamicContent.created_at.desc()).all()
    return render_template('admin/pages/index.html', pages=pages)


@app.route('/admin/pages/create', methods=['GET', 'POST'])
@admin_required
def admin_page_create():
    if request.method == 'POST':
        try:
            page = DynamicContent(
                title=request.form.get('title'),
                slug=request.form.get('slug'),
                content=request.form.get('content'),
                summary=request.form.get('summary'),
                type=request.form.get('type', 'page'),
                seo_title=request.form.get('seo_title'),
                seo_description=request.form.get('seo_description'),
                seo_keywords=request.form.get('seo_keywords'),
                is_active=request.form.get('is_active') == 'on'
            )
            db.session.add(page)
            db.session.commit()
            flash('صفحه با موفقیت ایجاد شد.', 'success')
            return redirect(url_for('admin_pages'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ایجاد صفحه: {str(e)}', 'danger')
    
    return render_template('admin/pages/create.html')


@app.route('/admin/pages/<int:id>/edit', methods=['GET', 'POST'])
@admin_required
def admin_page_edit(id):
    page = DynamicContent.query.get_or_404(id)
    
    if request.method == 'POST':
        try:
            page.title = request.form.get('title')
            page.slug = request.form.get('slug')
            page.content = request.form.get('content')
            page.summary = request.form.get('summary')
            page.seo_title = request.form.get('seo_title')
            page.seo_description = request.form.get('seo_description')
            page.seo_keywords = request.form.get('seo_keywords')
            page.is_active = request.form.get('is_active') == 'on'
            
            db.session.commit()
            flash('صفحه با موفقیت ویرایش شد.', 'success')
            return redirect(url_for('admin_pages'))
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ویرایش صفحه: {str(e)}', 'danger')
    
    return render_template('admin/pages/edit.html', page=page)


@app.route('/admin/pages/<int:id>/delete')
@admin_required
def admin_page_delete(id):
    page = DynamicContent.query.get_or_404(id)
    db.session.delete(page)
    db.session.commit()
    flash('صفحه با موفقیت حذف شد.', 'success')
    return redirect(url_for('admin_pages'))
    


@app.route('/article/<slug>/comment', methods=['POST'])
@login_required
def submit_article_comment(slug):
    try:
        article = Article.query.filter_by(slug=slug, is_active=True).first_or_404()
        content = request.form.get('content')
        
        if not content:
            flash('لطفاً متن نظر را وارد کنید.', 'danger')
            return redirect(url_for('article_detail', slug=slug))
        
        comment = ArticleComment(
            article_id=article.id,
            user_id=session['user_id'],
            content=content,
            is_approved=False,  # نیاز به تایید ادمین
            created_at=datetime.now()
        )
        db.session.add(comment)
        db.session.commit()
        
        # افزایش تعداد نظرات مقاله
        article.comment_count = ArticleComment.query.filter_by(article_id=article.id, is_approved=True).count()
        db.session.commit()
        
        flash('نظر شما با موفقیت ثبت شد و پس از تایید نمایش داده می‌شود.', 'success')
        return redirect(url_for('article_detail', slug=slug))
        
    except Exception as e:
        db.session.rollback()
        flash(f'خطا در ثبت نظر: {str(e)}', 'danger')
        return redirect(url_for('article_detail', slug=slug))

# ---- مدیریت تنظیمات ----
@app.route('/admin/settings', methods=['GET', 'POST'])
@admin_required
def admin_settings():
    if request.method == 'POST':
        try:
            # فقط تنظیمات به‌دردبخور
            settings_list = {
                'site_name': request.form.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
                'site_description': request.form.get('site_description', 'تعمیرات تخصصی لوازم خانگی دوو در تهران'),
                'about_text': request.form.get('about_text', 'ما با بیش از ۱۰ سال تجربه...'),
                
                'phone1': request.form.get('phone1', '۰۲۱-۵۵۵۵-۱۲۳۴'),
                'phone2': request.form.get('phone2', '۰۲۱-۵۵۵۵-۵۶۷۸'),
                'whatsapp': request.form.get('whatsapp', '۰۹۱۲-۱۲۳-۴۵۶۷'),
                'email': request.form.get('email', 'info@daewoo-tehran.com'),
                'address': request.form.get('address', 'تهران، میدان آزادی'),
                'emergency_phone': request.form.get('emergency_phone', '۰۹۱۲-۱۲۳-۴۵۶۷'),
                'work_hours': request.form.get('work_hours', 'شنبه تا پنجشنبه ۹ صبح تا ۸ شب - جمعه‌ها ۱۰ صبح تا ۶ شب'),
                
                'instagram': request.form.get('instagram', 'daewoo_tehran'),
                'telegram': request.form.get('telegram', 'daewoo_tehran'),
                'youtube': request.form.get('youtube', 'daewoo_tehran'),
                'aparat': request.form.get('aparat', 'daewoo_tehran'),
                'twitter': request.form.get('twitter', 'daewoo_tehran'),
                'facebook': request.form.get('facebook', 'daewoo_tehran'),
                'rubika': request.form.get('rubika', 'daewoo_tehran'),
                'bale': request.form.get('bale', 'daewoo_tehran'),
            }
            
            for key, value in settings_list.items():
                Setting.set(key, value)
            
            flash('✅ تنظیمات با موفقیت ذخیره شد.', 'success')
            return redirect(url_for('admin_settings'))
            
        except Exception as e:
            flash(f'❌ خطا: {str(e)}', 'danger')
    
    # دریافت تنظیمات فعلی
    settings = {}
    keys = ['site_name', 'site_description', 'about_text', 'phone1', 'phone2', 
            'whatsapp', 'email', 'address', 'emergency_phone', 'work_hours',
            'instagram', 'telegram', 'youtube', 'aparat', 'twitter', 'facebook', 
            'rubika', 'bale']
    
    for key in keys:
        settings[key] = Setting.get(key, '')
    
    return render_template('admin/settings/index.html', settings=settings)
@app.route('/services')
def services():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    services_list = Service.query.filter_by(is_active=True).order_by(Service.order).all()
    technicians = Technician.query.filter_by(is_active=True).all()
    
    return render_template('services.html', 
                         services=services_list, 
                         technicians=technicians,
                         settings=settings,
                         CATEGORY_NAMES=CATEGORY_NAMES)  # <-- اضافه کن
@app.route('/technicians')
def technicians():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    technicians_list = Technician.query.filter_by(is_active=True).all()
    
    # ===== درست کردن تخصص‌ها =====
    import json
    for tech in technicians_list:
        if tech.expertise_areas:
            try:
                exp_list = json.loads(tech.expertise_areas)
                tech.expertise_display = '، '.join(exp_list)
            except:
                tech.expertise_display = tech.expertise_areas
        else:
            tech.expertise_display = 'تعمیرات تخصصی دوو'
    
    return render_template('technicians.html', 
                         technicians=technicians_list, 
                         settings=settings)

@app.route('/service/<int:service_id>')
def service_detail(service_id):
    service = Service.query.get_or_404(service_id)
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    # ===== دریافت تکنسین‌ها با تبدیل تخصص =====
    import json
    technicians = Technician.query.filter_by(is_active=True).all()
    for tech in technicians:
        if tech.expertise_areas:
            try:
                exp_list = json.loads(tech.expertise_areas)
                tech.expertise_display = '، '.join(exp_list)
            except:
                tech.expertise_display = tech.expertise_areas
        else:
            tech.expertise_display = 'تعمیرات تخصصی دوو'
    
    # ===== سایر خدمات =====
    other_services = Service.query.filter(
        Service.is_active == True,
        Service.id != service.id
    ).limit(5).all()
    
    return render_template('service_detail.html', 
                         service=service, 
                         settings=settings,
                         technicians=technicians,
                         other_services=other_services)
                         
@app.route('/technician/<int:technician_id>')
def technician_detail(technician_id):
    technician = Technician.query.get_or_404(technician_id)
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    # درست کردن تخصص برای نمایش
    import json
    if technician.expertise_areas:
        try:
            exp_list = json.loads(technician.expertise_areas)
            technician.expertise_display = '، '.join(exp_list)
        except:
            technician.expertise_display = technician.expertise_areas
    else:
        technician.expertise_display = 'تعمیرات تخصصی دوو'
    
    # تکنسین‌های دیگر
    other_technicians = Technician.query.filter(
        Technician.is_active == True,
        Technician.id != technician.id
    ).limit(3).all()
    
    for tech in other_technicians:
        if tech.expertise_areas:
            try:
                exp_list = json.loads(tech.expertise_areas)
                tech.expertise_display = '، '.join(exp_list)
            except:
                tech.expertise_display = tech.expertise_areas
        else:
            tech.expertise_display = 'تعمیرات تخصصی دوو'
    
    return render_template('technician_detail.html', 
                         technician=technician,
                         other_technicians=other_technicians,
                         settings=settings)
# ===== مناطق =====

# ================================================================
# ===== روت‌های عمومی نمایش خطاها =====
# ================================================================

@app.route('/errors')
def errors_home():
    categories = ErrorCategory.query.filter_by(is_active=True).order_by(ErrorCategory.sort_order).all()
    featured_errors = ErrorSolution.query.filter_by(is_active=True, is_featured=True).limit(6).all()
    self_fix_errors = ErrorSolution.query.filter_by(is_active=True, can_self_fix=True).limit(10).all()
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    return render_template('errors/index.html',
                         categories=categories,
                         featured_errors=featured_errors,
                         self_fix_errors=self_fix_errors,
                         settings=settings)


@app.route('/errors/category/<slug>')
def error_category_detail(slug):
    category = ErrorCategory.query.filter_by(slug=slug, is_active=True).first_or_404()
    errors = ErrorSolution.query.filter_by(
        category_id=category.id,
        is_active=True
    ).order_by(ErrorSolution.view_count.desc()).all()
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    return render_template('errors/category.html',
                         category=category,
                         errors=errors,
                         settings=settings)


@app.route('/errors/<slug>')
def error_detail(slug):
    error = ErrorSolution.query.filter_by(slug=slug, is_active=True).first_or_404()
    error.view_count += 1
    db.session.commit()
    
    related_errors = ErrorSolution.query.filter(
        ErrorSolution.category_id == error.category_id,
        ErrorSolution.id != error.id,
        ErrorSolution.is_active == True
    ).limit(5).all()
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234'),
        'phone2': Setting.get('phone2', ''),
        'emergency_phone': Setting.get('emergency_phone', '0912-123-4567')
    }
    
    return render_template('errors/detail.html',
                         error=error,
                         related_errors=related_errors,
                         settings=settings)


@app.route('/errors/search')
def error_search():
    query = request.args.get('q', '')
    category_slug = request.args.get('category', '')
    
    errors_query = ErrorSolution.query.filter_by(is_active=True)
    
    if query:
        errors_query = errors_query.filter(
            db.or_(
                ErrorSolution.error_title.ilike(f'%{query}%'),
                ErrorSolution.error_description.ilike(f'%{query}%'),
                ErrorSolution.symptoms.ilike(f'%{query}%')
            )
        )
    
    if category_slug:
        category = ErrorCategory.query.filter_by(slug=category_slug).first()
        if category:
            errors_query = errors_query.filter_by(category_id=category.id)
    
    errors = errors_query.order_by(ErrorSolution.view_count.desc()).all()
    categories = ErrorCategory.query.filter_by(is_active=True).all()
    
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    return render_template('errors/search.html',
                         errors=errors,
                         categories=categories,
                         query=query,
                         category_slug=category_slug,
                         settings=settings)
                         
@app.route('/regions')
def regions():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    regions_list = TehranRegion.query.filter_by(is_active=True).all()
    
    # ===== تبدیل مناطق به JSON برای نقشه =====
    regions_json = []
    for r in regions_list:
        regions_json.append({
            'id': r.id,
            'name': r.name,
            'slug': r.slug,
            'latitude': r.latitude,
            'longitude': r.longitude,
            'region_number': r.region_number,
            'coverage_percentage': r.coverage_percentage
        })
    
    return render_template('regions.html', 
                         regions=regions_list, 
                         regions_json=regions_json,
                         settings=settings)
                         

@app.route('/region/<slug>')
def region_detail(slug):
    region = TehranRegion.query.filter_by(slug=slug, is_active=True).first_or_404()
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    
    # ===== تبدیل region به دیکشنری برای JSON =====
    region_dict = {
        'id': region.id,
        'name': region.name,
        'slug': region.slug,
        'region_number': region.region_number,
        'latitude': region.latitude,
        'longitude': region.longitude,
        'coverage_percentage': region.coverage_percentage,
        'description': region.description,
        'population': region.population,
        'area_sqkm': region.area_sqkm,
        'districts': region.get_districts(),
        'main_streets': region.get_main_streets(),
        'landmarks': region.get_landmarks(),
        'metro_stations': region.get_metro_stations()
    }
    
    return render_template('region_detail.html', 
                         region=region, 
                         region_dict=region_dict,
                         settings=settings)
# ===== رزرو نوبت =====
@app.route('/booking', methods=['GET', 'POST'])
@login_required
def booking():
    settings = {
        'site_name': Setting.get('site_name', 'نمایندگی تعمیرات دوو تهران'),
        'phone1': Setting.get('phone1', '021-5555-1234')
    }
    services = Service.query.filter_by(is_active=True).all()
    regions = TehranRegion.query.filter_by(is_active=True).all()
    
    if request.method == 'POST':
        try:
            service_id = request.form.get('service_id')
            region_id = request.form.get('region_id')
            address = request.form.get('address')
            scheduled_date = request.form.get('scheduled_date')  # اینجا تاریخ میلادی میاد
            scheduled_time = request.form.get('scheduled_time')
            description = request.form.get('description')
            is_emergency = request.form.get('is_emergency') == 'on'
            
            # تبدیل تاریخ از شمسی به میلادی
            from datetime import datetime
            import jdatetime
            
            # تاریخ ورودی به صورت شمسی هست (مثلاً 1404-04-25)
            try:
                year, month, day = map(int, scheduled_date.split('-'))
                j_date = jdatetime.date(year, month, day)
                gregorian_date = j_date.togregorian()
                scheduled_date_obj = gregorian_date
            except:
                # اگر تاریخ میلادی وارد شده بود
                scheduled_date_obj = datetime.strptime(scheduled_date, '%Y-%m-%d').date()
            
            booking = Booking(
                booking_number=f"DW{datetime.now().strftime('%y%m%d%H%M%S')}",
                user_id=session['user_id'],
                service_id=int(service_id),
                region_id=int(region_id),
                address=address,
                scheduled_date=scheduled_date_obj,
                scheduled_time=datetime.strptime(scheduled_time, '%H:%M').time(),
                description=description,
                is_emergency=is_emergency,
                status='pending',
                payment_status='pending'
            )
            db.session.add(booking)
            db.session.commit()
            
            flash('درخواست شما با موفقیت ثبت شد.', 'success')
            return redirect(url_for('dashboard'))
            
        except Exception as e:
            db.session.rollback()
            flash(f'خطا در ثبت درخواست: {str(e)}', 'danger')
            return redirect(url_for('booking'))
    
    return render_template('booking.html', 
                         settings=settings, 
                         services=services, 
                         regions=regions)
# ================================================================
# ===== مقداردهی اولیه دیتابیس =====
# ================================================================
def init_db():
    with app.app_context():
        db.create_all()
        print('[✅] جداول دیتابیس ایجاد شدند.')
        
        # ============================================================
        # 1. ایجاد کاربر ادمین
        # ============================================================
        if User.query.count() == 0:
            admin = User(
                fullname='مدیر سیستم',
                phone='09120000000',
                email='admin@daewoo-tehran.com',
                password=generate_password_hash('Admin@12345'),
                role='admin',
                is_verified=True,
                wallet=10000000,
                wallet_credit=5000000
            )
            db.session.add(admin)
            print('[✅] کاربر ادمین ایجاد شد.')
        
        # ============================================================
        # 2. ایجاد کاربران نمونه
        # ============================================================
        if User.query.count() < 2:
            users = [
                {
                    'fullname': 'رضا محمدی',
                    'phone': '09123334444',
                    'email': 'reza@example.com',
                    'password': generate_password_hash('User@12345'),
                    'role': 'user',
                    'is_verified': True,
                    'wallet': 500000,
                    'wallet_credit': 200000
                },
                {
                    'fullname': 'مریم احمدی',
                    'phone': '09124445555',
                    'email': 'maryam@example.com',
                    'password': generate_password_hash('User@12345'),
                    'role': 'user',
                    'is_verified': True,
                    'wallet': 750000,
                    'wallet_credit': 300000
                },
                {
                    'fullname': 'علی رضایی',
                    'phone': '09125556666',
                    'email': 'ali@example.com',
                    'password': generate_password_hash('User@12345'),
                    'role': 'user',
                    'is_verified': True,
                    'wallet': 200000,
                    'wallet_credit': 100000
                },
                {
                    'fullname': 'سارا کریمی',
                    'phone': '09126667777',
                    'email': 'sara@example.com',
                    'password': generate_password_hash('User@12345'),
                    'role': 'user',
                    'is_verified': True,
                    'wallet': 1000000,
                    'wallet_credit': 500000
                }
            ]
            for user_data in users:
                user = User(**user_data)
                db.session.add(user)
            print(f'[✅] {len(users)} کاربر نمونه ایجاد شدند.')
        
        db.session.commit()
        
        # ============================================================
        # 3. تنظیمات پیش‌فرض
        # ============================================================
        if Setting.query.count() == 0:
            default_settings = {
                'general': {
                    'site_name': 'نمایندگی تعمیرات دوو تهران',
                    'site_description': 'تعمیرات تخصصی لوازم خانگی دوو در تمام مناطق تهران با ضمانت کیفیت و بهترین قیمت',
                    'site_keywords': 'تعمیرات دوو, تهران, نمایندگی دوو, تعمیر یخچال دوو, تعمیر لباسشویی دوو, تعمیر ظرفشویی دوو, تعمیر پکیج دوو',
                    'admin_email': 'info@daewoo-tehran.com',
                    'admin_phone': '021-5555-1234',
                    'work_hours_start': '08:00',
                    'work_hours_end': '20:00',
                    'emergency_phone': '0912-123-4567',
                    'about_text': 'ما با بیش از ۱۲ سال تجربه در زمینه تعمیرات تخصصی لوازم خانگی دوو، همواره در تلاشیم تا بهترین خدمات را با کیفیت بالا و قیمت مناسب به شما عزیزان ارائه دهیم. تیم ما متشکل از تکنسین‌های مجرب و حرفه‌ای است که با استفاده از قطعات اورجینال و به‌روزترین تجهیزات، تعمیرات شما را با ضمانت انجام می‌دهند.'
                },
                'seo': {
                    'default_title': 'تعمیرات دوو در تهران | نمایندگی تخصصی دوو',
                    'default_description': 'تعمیرات تخصصی یخچال، لباسشویی، ظرفشویی و پکیج دوو در تهران با ضمانت کیفیت و بهترین قیمت',
                    'default_keywords': 'تعمیرات دوو, تهران, نمایندگی دوو, تعمیر یخچال دوو, تعمیر لباسشویی دوو',
                    'robots': 'index, follow',
                    'canonical_url': 'https://daewoo-tehran.com'
                },
                'pricing': {
                    'base_visit_cost': 250000,
                    'emergency_surcharge': 150000,
                    'weekend_surcharge': 100000,
                    'holiday_surcharge': 150000,
                    'distance_charge_per_km': 5000,
                    'min_charge': 200000,
                    'tax_percentage': 9
                },
                'contact': {
                    'address': 'تهران، میدان آزادی، خیابان آزادی، پلاک ۱۲۳',
                    'email': 'info@daewoo-tehran.com',
                    'phone1': '021-5555-1234',
                    'phone2': '021-5555-5678',
                    'whatsapp': '0912-123-4567',
                    'telegram': 'daewoo_tehran',
                    'instagram': 'daewoo_tehran',
                    'aparat': 'daewoo_tehran',
                    'youtube': 'daewoo_tehran',
                    'twitter': 'daewoo_tehran',
                    'map_lat': '35.6892',
                    'map_lng': '51.3890',
                    'work_hours': 'شنبه تا پنجشنبه ۹ صبح تا ۸ شب - جمعه‌ها ۱۰ صبح تا ۶ شب'
                },
                'social': {
                    'facebook': 'https://facebook.com/daewootehran',
                    'twitter': 'https://twitter.com/daewootehran',
                    'instagram': 'https://instagram.com/daewootehran',
                    'youtube': 'https://youtube.com/daewootehran',
                    'telegram': 'https://t.me/daewootehran',
                    'whatsapp': 'https://wa.me/989121234567',
                    'aparat': 'https://aparat.com/daewootehran'
                }
            }
            
            for category, settings in default_settings.items():
                for key, value in settings.items():
                    Setting.set(key, value, category, f'تنظیمات {category} - {key}')
            
            print('[✅] تنظیمات پیش‌فرض ایجاد شدند.')
        
        # ============================================================
        # 4. ایجاد مناطق تهران (۲۲ منطقه کامل)
        # ============================================================
        if TehranRegion.query.count() == 0:
            tehran_regions = [
                # منطقه ۱
                {
                    'region_number': 1,
                    'name': 'منطقه ۱ (شمال تهران)',
                    'slug': 'region-1',
                    'latitude': 35.8136,
                    'longitude': 51.4190,
                    'districts': json.dumps(['تجریش', 'الهیه', 'فرمانیه', 'نیاوران', 'کامرانیه', 'زرگنده', 'محمودیه']),
                    'main_streets': json.dumps(['خیابان ولیعصر', 'خیابان تجریش', 'خیابان فرمانیه', 'خیابان نیاوران']),
                    'landmarks': json.dumps(['پارک ملت', 'مجموعه ورزشی انقلاب', 'بازار تجریش']),
                    'metro_stations': json.dumps(['تجریش', 'قلهک']),
                    'population': 350000,
                    'area_sqkm': 42.5,
                    'priority': 10,
                    'coverage_percentage': 95,
                    'service_count': 45,
                    'review_count': 120,
                    'avg_rating': 4.8,
                    'monthly_requests': 180,
                    'response_time': 30,
                    'seo_title': 'تعمیرات دوو در منطقه ۱ تهران | شمال تهران',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱ تهران شامل تجریش، الهیه، فرمانیه و نیاوران با بهترین کیفیت',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱, تعمیرات دوو شمال تهران, تعمیرات دوو تجریش',
                    'is_active': True
                },
                # منطقه ۲
                {
                    'region_number': 2,
                    'name': 'منطقه ۲ (شمال شرق تهران)',
                    'slug': 'region-2',
                    'latitude': 35.7846,
                    'longitude': 51.4745,
                    'districts': json.dumps(['شهرک قدس', 'سعادت‌آباد', 'فرشته', 'گیشا', 'پونک']),
                    'main_streets': json.dumps(['خیابان سعادت‌آباد', 'خیابان فرشته', 'بزرگراه چمران']),
                    'landmarks': json.dumps(['برج میلاد', 'پارک سعادت‌آباد', 'مرکز خرید میلاد']),
                    'metro_stations': json.dumps(['شهرک قدس', 'پونک']),
                    'population': 400000,
                    'area_sqkm': 48.0,
                    'priority': 9,
                    'coverage_percentage': 92,
                    'service_count': 38,
                    'review_count': 95,
                    'avg_rating': 4.7,
                    'monthly_requests': 150,
                    'response_time': 35,
                    'seo_title': 'تعمیرات دوو در منطقه ۲ تهران | سعادت‌آباد و شهرک قدس',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۲ تهران شامل سعادت‌آباد، فرشته و شهرک قدس',
                    'seo_keywords': 'تعمیرات دوو منطقه ۲, تعمیرات دوو سعادت‌آباد, تعمیرات دوو شهرک قدس',
                    'is_active': True
                },
                # منطقه ۳
                {
                    'region_number': 3,
                    'name': 'منطقه ۳ (شرق تهران)',
                    'slug': 'region-3',
                    'latitude': 35.7564,
                    'longitude': 51.5370,
                    'districts': json.dumps(['نارمک', 'دستگرد', 'اقدسیه', 'پاسداران']),
                    'main_streets': json.dumps(['خیابان پاسداران', 'خیابان نارمک', 'بزرگراه امام علی']),
                    'landmarks': json.dumps(['پارک نارمک', 'بیمارستان شهدا']),
                    'metro_stations': json.dumps(['نارمک', 'هفت تیر']),
                    'population': 380000,
                    'area_sqkm': 45.2,
                    'priority': 8,
                    'coverage_percentage': 90,
                    'service_count': 35,
                    'review_count': 80,
                    'avg_rating': 4.6,
                    'monthly_requests': 130,
                    'response_time': 38,
                    'seo_title': 'تعمیرات دوو در منطقه ۳ تهران | نارمک و پاسداران',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۳ تهران شامل نارمک، اقدسیه و پاسداران',
                    'seo_keywords': 'تعمیرات دوو منطقه ۳, تعمیرات دوو نارمک, تعمیرات دوو پاسداران',
                    'is_active': True
                },
                # منطقه ۴
                {
                    'region_number': 4,
                    'name': 'منطقه ۴ (جنوب شرق تهران)',
                    'slug': 'region-4',
                    'latitude': 35.7234,
                    'longitude': 51.5542,
                    'districts': json.dumps(['خانی‌آباد', 'مسگرآباد', 'شوش']),
                    'main_streets': json.dumps(['خیابان خانی‌آباد', 'خیابان شوش']),
                    'landmarks': json.dumps(['بازار مسگرآباد']),
                    'metro_stations': json.dumps(['خانی‌آباد']),
                    'population': 320000,
                    'area_sqkm': 40.8,
                    'priority': 5,
                    'coverage_percentage': 85,
                    'service_count': 25,
                    'review_count': 60,
                    'avg_rating': 4.5,
                    'monthly_requests': 100,
                    'response_time': 45,
                    'seo_title': 'تعمیرات دوو در منطقه ۴ تهران | خانی‌آباد و مسگرآباد',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۴ تهران شامل خانی‌آباد و مسگرآباد',
                    'seo_keywords': 'تعمیرات دوو منطقه ۴, تعمیرات دوو خانی‌آباد',
                    'is_active': True
                },
                # منطقه ۵
                {
                    'region_number': 5,
                    'name': 'منطقه ۵ (غرب تهران)',
                    'slug': 'region-5',
                    'latitude': 35.7588,
                    'longitude': 51.3193,
                    'districts': json.dumps(['شهرک غرب', 'اردلان', 'جنت‌آباد', 'صادقیه']),
                    'main_streets': json.dumps(['بزرگراه همت', 'خیابان صادقیه', 'بزرگراه اشرفی اصفهانی']),
                    'landmarks': json.dumps(['برج‌های شهرک غرب', 'پارک جنگلی چیتگر']),
                    'metro_stations': json.dumps(['صادقیه', 'ارم سبز']),
                    'population': 450000,
                    'area_sqkm': 52.3,
                    'priority': 10,
                    'coverage_percentage': 98,
                    'service_count': 55,
                    'review_count': 150,
                    'avg_rating': 4.9,
                    'monthly_requests': 220,
                    'response_time': 25,
                    'seo_title': 'تعمیرات دوو در منطقه ۵ تهران | شهرک غرب و صادقیه',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۵ تهران شامل شهرک غرب، جنت‌آباد و صادقیه',
                    'seo_keywords': 'تعمیرات دوو منطقه ۵, تعمیرات دوو شهرک غرب, تعمیرات دوو صادقیه',
                    'is_active': True
                },
                # منطقه ۶
                {
                    'region_number': 6,
                    'name': 'منطقه ۶ (مرکز تهران)',
                    'slug': 'region-6',
                    'latitude': 35.7184,
                    'longitude': 51.4249,
                    'districts': json.dumps(['میدان انقلاب', 'میدان ولیعصر', 'هروی', 'ارم']),
                    'main_streets': json.dumps(['خیابان انقلاب', 'خیابان ولیعصر', 'خیابان هروی']),
                    'landmarks': json.dumps(['دانشگاه تهران', 'میدان انقلاب', 'میدان ولیعصر']),
                    'metro_stations': json.dumps(['میدان انقلاب', 'میدان ولیعصر']),
                    'population': 300000,
                    'area_sqkm': 35.7,
                    'priority': 10,
                    'coverage_percentage': 100,
                    'service_count': 50,
                    'review_count': 140,
                    'avg_rating': 4.8,
                    'monthly_requests': 200,
                    'response_time': 20,
                    'seo_title': 'تعمیرات دوو در منطقه ۶ تهران | مرکز تهران',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۶ تهران شامل میدان انقلاب، ولیعصر و هروی',
                    'seo_keywords': 'تعمیرات دوو منطقه ۶, تعمیرات دوو مرکز تهران, تعمیرات دوو انقلاب',
                    'is_active': True
                },
                # منطقه ۷
                {
                    'region_number': 7,
                    'name': 'منطقه ۷ (جنوب غرب تهران)',
                    'slug': 'region-7',
                    'latitude': 35.6914,
                    'longitude': 51.4375,
                    'districts': json.dumps(['بازار تهران', 'میدان محمدیه']),
                    'main_streets': json.dumps(['خیابان مولوی', 'خیابان خیام']),
                    'landmarks': json.dumps(['بازار بزرگ تهران']),
                    'metro_stations': json.dumps(['پانزده خرداد']),
                    'population': 280000,
                    'area_sqkm': 32.1,
                    'priority': 3,
                    'coverage_percentage': 80,
                    'service_count': 20,
                    'review_count': 45,
                    'avg_rating': 4.3,
                    'monthly_requests': 80,
                    'response_time': 50,
                    'seo_title': 'تعمیرات دوو در منطقه ۷ تهران | بازار تهران',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۷ تهران شامل بازار تهران و میدان محمدیه',
                    'seo_keywords': 'تعمیرات دوو منطقه ۷, تعمیرات دوو بازار تهران',
                    'is_active': True
                },
                # منطقه ۸
                {
                    'region_number': 8,
                    'name': 'منطقه ۸ (جنوب تهران)',
                    'slug': 'region-8',
                    'latitude': 35.6681,
                    'longitude': 51.4799,
                    'districts': json.dumps(['نازی‌آباد', 'خیابان خزانه']),
                    'main_streets': json.dumps(['خیابان خزانه', 'خیابان نازی‌آباد']),
                    'landmarks': json.dumps(['بازار نازی‌آباد']),
                    'metro_stations': json.dumps(['خزانه']),
                    'population': 260000,
                    'area_sqkm': 30.5,
                    'priority': 2,
                    'coverage_percentage': 75,
                    'service_count': 18,
                    'review_count': 35,
                    'avg_rating': 4.2,
                    'monthly_requests': 70,
                    'response_time': 55,
                    'seo_title': 'تعمیرات دوو در منطقه ۸ تهران | نازی‌آباد',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۸ تهران شامل نازی‌آباد و خزانه',
                    'seo_keywords': 'تعمیرات دوو منطقه ۸, تعمیرات دوو نازی‌آباد',
                    'is_active': True
                },
                # منطقه ۹
                {
                    'region_number': 9,
                    'name': 'منطقه ۹ (جنوب غرب تهران)',
                    'slug': 'region-9',
                    'latitude': 35.6804,
                    'longitude': 51.3861,
                    'districts': json.dumps(['یوسف‌آباد', 'جلال‌آباد']),
                    'main_streets': json.dumps(['خیابان آیت‌الله کاشانی']),
                    'landmarks': json.dumps(['پارک یوسف‌آباد']),
                    'metro_stations': json.dumps(['کاشانی']),
                    'population': 270000,
                    'area_sqkm': 31.8,
                    'priority': 2,
                    'coverage_percentage': 78,
                    'service_count': 22,
                    'review_count': 40,
                    'avg_rating': 4.4,
                    'monthly_requests': 85,
                    'response_time': 48,
                    'seo_title': 'تعمیرات دوو در منطقه ۹ تهران | یوسف‌آباد',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۹ تهران شامل یوسف‌آباد و جلال‌آباد',
                    'seo_keywords': 'تعمیرات دوو منطقه ۹, تعمیرات دوو یوسف‌آباد',
                    'is_active': True
                },
                # منطقه ۱۰
                {
                    'region_number': 10,
                    'name': 'منطقه ۱۰ (جنوب مرکزی تهران)',
                    'slug': 'region-10',
                    'latitude': 35.6953,
                    'longitude': 51.3941,
                    'districts': json.dumps(['بریانک', 'خانی‌آباد', 'مهرآباد']),
                    'main_streets': json.dumps(['خیابان بریانک']),
                    'landmarks': json.dumps(['فرودگاه مهرآباد']),
                    'metro_stations': json.dumps(['مهرآباد']),
                    'population': 240000,
                    'area_sqkm': 28.9,
                    'priority': 1,
                    'coverage_percentage': 70,
                    'service_count': 15,
                    'review_count': 30,
                    'avg_rating': 4.1,
                    'monthly_requests': 60,
                    'response_time': 60,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۰ تهران | بریانک و مهرآباد',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۰ تهران شامل بریانک و مهرآباد',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۰, تعمیرات دوو مهرآباد',
                    'is_active': True
                },
                # منطقه ۱۱
                {
                    'region_number': 11,
                    'name': 'منطقه ۱۱ (مرکز تهران)',
                    'slug': 'region-11',
                    'latitude': 35.7101,
                    'longitude': 51.4058,
                    'districts': json.dumps(['دروازه شمیران', 'دروازه دولت']),
                    'main_streets': json.dumps(['خیابان شریعتی']),
                    'landmarks': json.dumps(['دروازه شمیران']),
                    'metro_stations': json.dumps(['شریعتی']),
                    'population': 220000,
                    'area_sqkm': 27.4,
                    'priority': 4,
                    'coverage_percentage': 88,
                    'service_count': 28,
                    'review_count': 55,
                    'avg_rating': 4.5,
                    'monthly_requests': 110,
                    'response_time': 40,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۱ تهران | شریعتی',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۱ تهران شامل خیابان شریعتی و دروازه شمیران',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۱, تعمیرات دوو شریعتی',
                    'is_active': True
                },
                # منطقه ۱۲
                {
                    'region_number': 12,
                    'name': 'منطقه ۱۲ (مرکز تهران)',
                    'slug': 'region-12',
                    'latitude': 35.6993,
                    'longitude': 51.4165,
                    'districts': json.dumps(['میدان امام', 'میدان فردوسی']),
                    'main_streets': json.dumps(['خیابان فردوسی']),
                    'landmarks': json.dumps(['میدان امام']),
                    'metro_stations': json.dumps(['امام']),
                    'population': 200000,
                    'area_sqkm': 25.6,
                    'priority': 3,
                    'coverage_percentage': 85,
                    'service_count': 20,
                    'review_count': 42,
                    'avg_rating': 4.3,
                    'monthly_requests': 90,
                    'response_time': 45,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۲ تهران | میدان امام',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۲ تهران شامل میدان امام و فردوسی',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۲, تعمیرات دوو میدان امام',
                    'is_active': True
                },
                # منطقه ۱۳
                {
                    'region_number': 13,
                    'name': 'منطقه ۱۳ (شرق تهران)',
                    'slug': 'region-13',
                    'latitude': 35.7328,
                    'longitude': 51.4941,
                    'districts': json.dumps(['مجیدیه', 'دولت']),
                    'main_streets': json.dumps(['خیابان پاسداران']),
                    'landmarks': json.dumps(['پارک دولت']),
                    'metro_stations': json.dumps(['دولت']),
                    'population': 230000,
                    'area_sqkm': 26.9,
                    'priority': 5,
                    'coverage_percentage': 82,
                    'service_count': 24,
                    'review_count': 48,
                    'avg_rating': 4.4,
                    'monthly_requests': 95,
                    'response_time': 42,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۳ تهران | مجیدیه و دولت',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۳ تهران شامل مجیدیه و دولت',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۳, تعمیرات دوو مجیدیه',
                    'is_active': True
                },
                # منطقه ۱۴
                {
                    'region_number': 14,
                    'name': 'منطقه ۱۴ (جنوب شرق تهران)',
                    'slug': 'region-14',
                    'latitude': 35.7165,
                    'longitude': 51.5270,
                    'districts': json.dumps(['نیروی هوایی', 'پیروزی']),
                    'main_streets': json.dumps(['خیابان پیروزی']),
                    'landmarks': json.dumps(['پارک پیروزی']),
                    'metro_stations': json.dumps(['پیروزی']),
                    'population': 210000,
                    'area_sqkm': 24.8,
                    'priority': 4,
                    'coverage_percentage': 78,
                    'service_count': 18,
                    'review_count': 35,
                    'avg_rating': 4.2,
                    'monthly_requests': 75,
                    'response_time': 50,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۴ تهران | پیروزی',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۴ تهران شامل پیروزی و نیروی هوایی',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۴, تعمیرات دوو پیروزی',
                    'is_active': True
                },
                # منطقه ۱۵
                {
                    'region_number': 15,
                    'name': 'منطقه ۱۵ (جنوب شرق تهران)',
                    'slug': 'region-15',
                    'latitude': 35.6817,
                    'longitude': 51.5305,
                    'districts': json.dumps(['مسگرآباد', 'خانی‌آباد']),
                    'main_streets': json.dumps(['خیابان مسگرآباد']),
                    'landmarks': json.dumps(['بازار مسگرآباد']),
                    'metro_stations': json.dumps(['مسگرآباد']),
                    'population': 240000,
                    'area_sqkm': 27.9,
                    'priority': 3,
                    'coverage_percentage': 75,
                    'service_count': 16,
                    'review_count': 30,
                    'avg_rating': 4.1,
                    'monthly_requests': 65,
                    'response_time': 55,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۵ تهران | مسگرآباد',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۵ تهران شامل مسگرآباد',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۵, تعمیرات دوو مسگرآباد',
                    'is_active': True
                },
                # منطقه ۱۶
                {
                    'region_number': 16,
                    'name': 'منطقه ۱۶ (جنوب تهران)',
                    'slug': 'region-16',
                    'latitude': 35.6542,
                    'longitude': 51.4695,
                    'districts': json.dumps(['شهرک تهران']),
                    'main_streets': json.dumps(['خیابان شهرک تهران']),
                    'landmarks': json.dumps(['شهرک تهران']),
                    'metro_stations': json.dumps(['تهران']),
                    'population': 220000,
                    'area_sqkm': 26.1,
                    'priority': 2,
                    'coverage_percentage': 70,
                    'service_count': 14,
                    'review_count': 28,
                    'avg_rating': 4.0,
                    'monthly_requests': 58,
                    'response_time': 58,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۶ تهران | شهرک تهران',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۶ تهران شامل شهرک تهران',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۶, تعمیرات دوو شهرک تهران',
                    'is_active': True
                },
                # منطقه ۱۷
                {
                    'region_number': 17,
                    'name': 'منطقه ۱۷ (جنوب غرب تهران)',
                    'slug': 'region-17',
                    'latitude': 35.6827,
                    'longitude': 51.3712,
                    'districts': json.dumps(['جنت‌آباد', 'مهرآباد']),
                    'main_streets': json.dumps(['خیابان جنت‌آباد']),
                    'landmarks': json.dumps(['پارک جنت‌آباد']),
                    'metro_stations': json.dumps(['جنت‌آباد']),
                    'population': 210000,
                    'area_sqkm': 25.3,
                    'priority': 2,
                    'coverage_percentage': 72,
                    'service_count': 15,
                    'review_count': 32,
                    'avg_rating': 4.1,
                    'monthly_requests': 62,
                    'response_time': 52,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۷ تهران | جنت‌آباد',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۷ تهران شامل جنت‌آباد',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۷, تعمیرات دوو جنت‌آباد',
                    'is_active': True
                },
                # منطقه ۱۸
                {
                    'region_number': 18,
                    'name': 'منطقه ۱۸ (غرب تهران)',
                    'slug': 'region-18',
                    'latitude': 35.7405,
                    'longitude': 51.3025,
                    'districts': json.dumps(['چیتگر', 'وردآورد']),
                    'main_streets': json.dumps(['بزرگراه چیتگر']),
                    'landmarks': json.dumps(['پارک جنگلی چیتگر']),
                    'metro_stations': json.dumps(['چیتگر']),
                    'population': 250000,
                    'area_sqkm': 29.7,
                    'priority': 6,
                    'coverage_percentage': 85,
                    'service_count': 26,
                    'review_count': 50,
                    'avg_rating': 4.5,
                    'monthly_requests': 105,
                    'response_time': 40,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۸ تهران | چیتگر',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۸ تهران شامل چیتگر و پارک جنگلی',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۸, تعمیرات دوو چیتگر',
                    'is_active': True
                },
                # منطقه ۱۹
                {
                    'region_number': 19,
                    'name': 'منطقه ۱۹ (جنوب غرب تهران)',
                    'slug': 'region-19',
                    'latitude': 35.6712,
                    'longitude': 51.3216,
                    'districts': json.dumps(['خلیج فارس']),
                    'main_streets': json.dumps(['خیابان خلیج فارس']),
                    'landmarks': json.dumps(['پارک خلیج فارس']),
                    'metro_stations': json.dumps(['خلیج فارس']),
                    'population': 200000,
                    'area_sqkm': 24.8,
                    'priority': 1,
                    'coverage_percentage': 68,
                    'service_count': 12,
                    'review_count': 25,
                    'avg_rating': 3.9,
                    'monthly_requests': 50,
                    'response_time': 60,
                    'seo_title': 'تعمیرات دوو در منطقه ۱۹ تهران | خلیج فارس',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۱۹ تهران شامل خلیج فارس',
                    'seo_keywords': 'تعمیرات دوو منطقه ۱۹, تعمیرات دوو خلیج فارس',
                    'is_active': True
                },
                # منطقه ۲۰
                {
                    'region_number': 20,
                    'name': 'منطقه ۲۰ (جنوب تهران)',
                    'slug': 'region-20',
                    'latitude': 35.6513,
                    'longitude': 51.4409,
                    'districts': json.dumps(['ری']),
                    'main_streets': json.dumps(['خیابان ری']),
                    'landmarks': json.dumps(['شهر ری']),
                    'metro_stations': json.dumps(['ری']),
                    'population': 190000,
                    'area_sqkm': 23.9,
                    'priority': 1,
                    'coverage_percentage': 65,
                    'service_count': 10,
                    'review_count': 20,
                    'avg_rating': 3.8,
                    'monthly_requests': 45,
                    'response_time': 65,
                    'seo_title': 'تعمیرات دوو در منطقه ۲۰ تهران | شهر ری',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۲۰ تهران شامل شهر ری',
                    'seo_keywords': 'تعمیرات دوو منطقه ۲۰, تعمیرات دوو ری',
                    'is_active': True
                },
                # منطقه ۲۱
                {
                    'region_number': 21,
                    'name': 'منطقه ۲۱ (غرب تهران)',
                    'slug': 'region-21',
                    'latitude': 35.7388,
                    'longitude': 51.2789,
                    'districts': json.dumps(['کن']),
                    'main_streets': json.dumps(['خیابان کن']),
                    'landmarks': json.dumps(['پارک کن']),
                    'metro_stations': json.dumps(['کن']),
                    'population': 180000,
                    'area_sqkm': 22.7,
                    'priority': 3,
                    'coverage_percentage': 72,
                    'service_count': 14,
                    'review_count': 28,
                    'avg_rating': 4.0,
                    'monthly_requests': 55,
                    'response_time': 55,
                    'seo_title': 'تعمیرات دوو در منطقه ۲۱ تهران | کن',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۲۱ تهران شامل کن',
                    'seo_keywords': 'تعمیرات دوو منطقه ۲۱, تعمیرات دوو کن',
                    'is_active': True
                },
                # منطقه ۲۲
                {
                    'region_number': 22,
                    'name': 'منطقه ۲۲ (غرب تهران)',
                    'slug': 'region-22',
                    'latitude': 35.7677,
                    'longitude': 51.2630,
                    'districts': json.dumps(['پیکان شهر', 'دهکده المپیک']),
                    'main_streets': json.dumps(['بزرگراه دهکده المپیک']),
                    'landmarks': json.dumps(['دهکده المپیک', 'پارک جنگلی چیتگر']),
                    'metro_stations': json.dumps(['دهکده المپیک']),
                    'population': 300000,
                    'area_sqkm': 35.8,
                    'priority': 8,
                    'coverage_percentage': 90,
                    'service_count': 35,
                    'review_count': 85,
                    'avg_rating': 4.7,
                    'monthly_requests': 140,
                    'response_time': 32,
                    'seo_title': 'تعمیرات دوو در منطقه ۲۲ تهران | دهکده المپیک',
                    'seo_description': 'تعمیرات تخصصی دوو در منطقه ۲۲ تهران شامل دهکده المپیک و پیکان شهر',
                    'seo_keywords': 'تعمیرات دوو منطقه ۲۲, تعمیرات دوو دهکده المپیک',
                    'is_active': True
                }
            ]
            
            for region_data in tehran_regions:
                region = TehranRegion(**region_data)
                db.session.add(region)
            
            db.session.commit()
            print('[✅] ۲۲ منطقه تهران با اطلاعات کامل ایجاد شدند.')
        
        # ============================================================
        # 5. ایجاد خدمات پیش‌فرض با جزئیات
        # ============================================================
        if Service.query.count() == 0:
            services = [
                {
                    'title': 'تعمیر یخچال دوو',
                    'slug': 'refrigerator-repair',
                    'category': 'refrigerator',
                    'sub_category': 'cooling',
                    'description': 'تعمیر تخصصی یخچال‌های ساید بای ساید و معمولی دوو با ضمانت کیفیت. عیب‌یابی دقیق، تعویض قطعات معیوب، شارژ گاز و تست نهایی.',
                    'short_description': 'تعمیر انواع یخچال دوو در تمام مناطق تهران با بهترین قیمت',
                    'icon': 'fa-solid fa-snowflake',
                    'price_range_min': 250000,
                    'price_range_max': 850000,
                    'estimated_time': 90,
                    'is_popular': True,
                    'order': 1,
                    'seo_title': 'تعمیر یخچال دوو در تهران | خدمات تخصصی',
                    'seo_description': 'تعمیر تخصصی یخچال دوو در تهران با ضمانت کیفیت و بهترین قیمت'
                },
                {
                    'title': 'تعمیر لباسشویی دوو',
                    'slug': 'washing-machine-repair',
                    'category': 'washing_machine',
                    'sub_category': 'laundry',
                    'description': 'تعمیر انواع ماشین لباسشویی دوو با ضمانت و بهترین قیمت. رفع مشکلات موتور، پمپ تخلیه، برد الکترونیک و تنظیمات.',
                    'short_description': 'تعمیر تخصصی لباسشویی دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-tshirt',
                    'price_range_min': 200000,
                    'price_range_max': 700000,
                    'estimated_time': 75,
                    'is_popular': True,
                    'order': 2,
                    'seo_title': 'تعمیر لباسشویی دوو در تهران | تخصصی و با ضمانت',
                    'seo_description': 'تعمیر تخصصی لباسشویی دوو در تهران با بهترین قیمت و کیفیت'
                },
                {
                    'title': 'تعمیر ظرفشویی دوو',
                    'slug': 'dishwasher-repair',
                    'category': 'dishwasher',
                    'sub_category': 'kitchen',
                    'description': 'تعمیر ماشین ظرفشویی دوو با قطعات اورجینال. رفع مشکلات آبکشی، خشک‌کن، برد و پمپ سیرکولاتور.',
                    'short_description': 'تعمیر تخصصی ظرفشویی دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-utensils',
                    'price_range_min': 230000,
                    'price_range_max': 650000,
                    'estimated_time': 80,
                    'is_popular': True,
                    'order': 3,
                    'seo_title': 'تعمیر ظرفشویی دوو در تهران | با ضمانت',
                    'seo_description': 'تعمیر تخصصی ظرفشویی دوو در تهران با قطعات اصلی و ضمانت'
                },
                {
                    'title': 'تعمیر پکیج دوو',
                    'slug': 'package-repair',
                    'category': 'package',
                    'sub_category': 'heating',
                    'description': 'تعمیر پکیج و آبگرمکن دوو با بهترین کیفیت. عیب‌یابی و تعویض مشعل، مبدل، پمپ و برد کنترل.',
                    'short_description': 'تعمیر تخصصی پکیج دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-fire',
                    'price_range_min': 280000,
                    'price_range_max': 900000,
                    'estimated_time': 100,
                    'is_popular': True,
                    'order': 4,
                    'seo_title': 'تعمیر پکیج دوو در تهران | تخصصی',
                    'seo_description': 'تعمیر تخصصی پکیج دوو در تهران با ضمانت و بهترین قیمت'
                },
                {
                    'title': 'تعمیر جاروبرقی دوو',
                    'slug': 'vacuum-repair',
                    'category': 'vacuum',
                    'sub_category': 'cleaning',
                    'description': 'تعمیر جاروبرقی‌های دوو با قطعات اصلی. تعویض موتور، فیلترها و رفع مشکلات مکش.',
                    'short_description': 'تعمیر تخصصی جاروبرقی دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-broom',
                    'price_range_min': 150000,
                    'price_range_max': 450000,
                    'estimated_time': 60,
                    'is_popular': False,
                    'order': 5,
                    'seo_title': 'تعمیر جاروبرقی دوو در تهران',
                    'seo_description': 'تعمیر تخصصی جاروبرقی دوو در تهران با بهترین قیمت'
                },
                {
                    'title': 'تعمیر مایکروویو دوو',
                    'slug': 'microwave-repair',
                    'category': 'microwave',
                    'sub_category': 'kitchen',
                    'description': 'تعمیر مایکروویو دوو با بالاترین کیفیت. تعویض مگنترون، برد و رفع مشکلات گرمایشی.',
                    'short_description': 'تعمیر تخصصی مایکروویو دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-micro-wave',
                    'price_range_min': 180000,
                    'price_range_max': 500000,
                    'estimated_time': 65,
                    'is_popular': False,
                    'order': 6,
                    'seo_title': 'تعمیر مایکروویو دوو در تهران',
                    'seo_description': 'تعمیر تخصصی مایکروویو دوو در تهران با ضمانت'
                },
                {
                    'title': 'تعمیر اجاق گاز دوو',
                    'slug': 'stove-repair',
                    'category': 'stove',
                    'sub_category': 'kitchen',
                    'description': 'تعمیر انواع اجاق گاز دوو با بهترین کیفیت. رفع مشکلات مشعل، جرقه‌زن و تنظیمات.',
                    'short_description': 'تعمیر تخصصی اجاق گاز دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-fire-burner',
                    'price_range_min': 200000,
                    'price_range_max': 600000,
                    'estimated_time': 70,
                    'is_popular': False,
                    'order': 7,
                    'seo_title': 'تعمیر اجاق گاز دوو در تهران',
                    'seo_description': 'تعمیر تخصصی اجاق گاز دوو در تهران با بهترین قیمت'
                },
                {
                    'title': 'تعمیر هود دوو',
                    'slug': 'hood-repair',
                    'category': 'hood',
                    'sub_category': 'kitchen',
                    'description': 'تعمیر هود دوو با بهترین کیفیت. تعویض موتور، لامپ و رفع مشکلات مکش.',
                    'short_description': 'تعمیر تخصصی هود دوو در تمام مناطق تهران',
                    'icon': 'fa-solid fa-wind',
                    'price_range_min': 180000,
                    'price_range_max': 500000,
                    'estimated_time': 60,
                    'is_popular': False,
                    'order': 8,
                    'seo_title': 'تعمیر هود دوو در تهران',
                    'seo_description': 'تعمیر تخصصی هود دوو در تهران با ضمانت'
                },
                {
                    'title': 'تعمیر ساید بای ساید دوو',
                    'slug': 'side-by-side-repair',
                    'category': 'refrigerator',
                    'sub_category': 'cooling',
                    'description': 'تعمیر تخصصی یخچال‌های ساید بای ساید دوو با قطعات اصلی و ضمانت.',
                    'short_description': 'تعمیر تخصصی ساید بای ساید دوو در تهران',
                    'icon': 'fa-solid fa-ice-cream',
                    'price_range_min': 350000,
                    'price_range_max': 1200000,
                    'estimated_time': 120,
                    'is_popular': True,
                    'order': 9,
                    'seo_title': 'تعمیر ساید بای ساید دوو در تهران',
                    'seo_description': 'تعمیر تخصصی یخچال ساید بای ساید دوو با ضمانت'
                },
                {
                    'title': 'نصب و راه‌اندازی دوو',
                    'slug': 'installation-service',
                    'category': 'installation',
                    'sub_category': 'setup',
                    'description': 'نصب و راه‌اندازی انواع لوازم خانگی دوو شامل یخچال، لباسشویی، ظرفشویی و پکیج.',
                    'short_description': 'نصب تخصصی لوازم خانگی دوو در تهران',
                    'icon': 'fa-solid fa-tools',
                    'price_range_min': 150000,
                    'price_range_max': 400000,
                    'estimated_time': 60,
                    'is_popular': False,
                    'order': 10,
                    'seo_title': 'نصب لوازم خانگی دوو در تهران',
                    'seo_description': 'نصب تخصصی لوازم خانگی دوو با بهترین کیفیت'
                }
            ]
            
            for service_data in services:
                service = Service(**service_data)
                db.session.add(service)
            
            db.session.commit()
            print('[✅] خدمات پیش‌فرض با جزئیات کامل ایجاد شدند.')
            
            # ========== ایجاد جزئیات خدمات ==========
            service_details = [
                {
                    'service_slug': 'refrigerator-repair',
                    'details': [
                        {'problem_title': 'یخچال خنک نمی‌کند', 'problem_description': 'یخچال روشن است اما خنک نمی‌کند یا سرمای کافی ندارد.', 'solution': 'بررسی کمپرسور، گاز مبرد، ترموستات و برد کنترل.', 'price': '۲۵۰,۰۰۰ - ۸۵۰,۰۰۰ تومان', 'estimated_time': 90, 'difficulty': 'متوسط'},
                        {'problem_title': 'صدای زیاد یخچال', 'problem_description': 'یخچال صدای غیرعادی و زیاد تولید می‌کند.', 'solution': 'بررسی فن، کمپرسور، پایه‌ها و لوله‌های سیستم.', 'price': '۱۸۰,۰۰۰ - ۴۵۰,۰۰۰ تومان', 'estimated_time': 60, 'difficulty': 'آسان'},
                        {'problem_title': 'آب ریزش در یخچال', 'problem_description': 'آب از داخل یا زیر یخچال نشت می‌کند.', 'solution': 'بررسی لوله تخلیه، پمپ و درزگیرها.', 'price': '۱۵۰,۰۰۰ - ۴۰۰,۰۰۰ تومان', 'estimated_time': 45, 'difficulty': 'آسان'}
                    ]
                },
                {
                    'service_slug': 'washing-machine-repair',
                    'details': [
                        {'problem_title': 'لباسشویی آب نمی‌گیرد', 'problem_description': 'ماشین لباسشویی آب ورودی ندارد.', 'solution': 'بررسی شیر ورودی، فیلتر، برد و سنسورها.', 'price': '۲۰۰,۰۰۰ - ۵۰۰,۰۰۰ تومان', 'estimated_time': 70, 'difficulty': 'متوسط'},
                        {'problem_title': 'لباسشویی تخلیه نمی‌کند', 'problem_description': 'آب داخل لباسشویی باقی می‌ماند و تخلیه نمی‌شود.', 'solution': 'بررسی پمپ تخلیه، فیلتر و لوله‌ها.', 'price': '۱۸۰,۰۰۰ - ۴۵۰,۰۰۰ تومان', 'estimated_time': 60, 'difficulty': 'آسان'},
                        {'problem_title': 'لباسشویی نمی‌چرخد', 'problem_description': 'دrum لباسشویی نمی‌چرخد.', 'solution': 'بررسی موتور، تسمه و برد کنترل.', 'price': '۲۵۰,۰۰۰ - ۷۰۰,۰۰۰ تومان', 'estimated_time': 90, 'difficulty': 'سخت'}
                    ]
                },
                {
                    'service_slug': 'dishwasher-repair',
                    'details': [
                        {'problem_title': 'ظرفشویی تمیز نمی‌کند', 'problem_description': 'ظروف پس از شستشو تمیز نمی‌شوند.', 'solution': 'بررسی پمپ سیرکولاتور، فیلترها و نازل‌های آبکشی.', 'price': '۲۳۰,۰۰۰ - ۶۰۰,۰۰۰ تومان', 'estimated_time': 80, 'difficulty': 'متوسط'},
                        {'problem_title': 'ظرفشویی خشک نمی‌کند', 'problem_description': 'ظروف پس از شستشو خیس باقی می‌مانند.', 'solution': 'بررسی المنت خشک‌کن، فن و ترموستات.', 'price': '۲۰۰,۰۰۰ - ۵۵۰,۰۰۰ تومان', 'estimated_time': 70, 'difficulty': 'متوسط'}
                    ]
                },
                {
                    'service_slug': 'package-repair',
                    'details': [
                        {'problem_title': 'پکیج آب گرم نمی‌کند', 'problem_description': 'پکیج روشن است اما آب گرم تولید نمی‌کند.', 'solution': 'بررسی مشعل، مبدل حرارتی و سنسورها.', 'price': '۲۸۰,۰۰۰ - ۹۰۰,۰۰۰ تومان', 'estimated_time': 100, 'difficulty': 'سخت'},
                        {'problem_title': 'پکیج خاموش می‌شود', 'problem_description': 'پکیج به طور ناگهانی خاموش می‌شود.', 'solution': 'بررسی ترموستات، فن و برد کنترل.', 'price': '۲۵۰,۰۰۰ - ۷۵۰,۰۰۰ تومان', 'estimated_time': 90, 'difficulty': 'سخت'}
                    ]
                }
            ]
            
            for sd in service_details:
                service = Service.query.filter_by(slug=sd['service_slug']).first()
                if service:
                    for detail_data in sd['details']:
                        detail = ServiceDetail(
                            service_id=service.id,
                            problem_title=detail_data['problem_title'],
                            problem_description=detail_data['problem_description'],
                            solution=detail_data['solution'],
                            price=detail_data['price'],
                            estimated_time=detail_data['estimated_time'],
                            difficulty=detail_data['difficulty'],
                            is_active=True
                        )
                        db.session.add(detail)
            
            db.session.commit()
            print('[✅] جزئیات خدمات ایجاد شدند.')
            
            # ========== ایجاد سوالات متداول خدمات ==========
            service_faqs = [
                {'service_slug': 'refrigerator-repair', 'faqs': [
                    {'question': 'چقدر طول می‌کشد تا یخچال تعمیر شود؟', 'answer': 'تعمیرات معمولی بین ۱ تا ۲ ساعت زمان می‌برد.'},
                    {'question': 'آیا نیاز به جا به جایی یخچال دارید؟', 'answer': 'خیر، تکنسین‌های ما در محل شما تعمیرات را انجام می‌دهند.'}
                ]},
                {'service_slug': 'washing-machine-repair', 'faqs': [
                    {'question': 'آیا لباسشویی را به کارگاه می‌برید؟', 'answer': 'خیر، تعمیرات در محل شما انجام می‌شود.'}
                ]}
            ]
            
            for sf in service_faqs:
                service = Service.query.filter_by(slug=sf['service_slug']).first()
                if service:
                    for faq_data in sf['faqs']:
                        faq = ServiceFAQ(
                            service_id=service.id,
                            question=faq_data['question'],
                            answer=faq_data['answer'],
                            is_active=True
                        )
                        db.session.add(faq)
            
            db.session.commit()
            print('[✅] سوالات متداول خدمات ایجاد شدند.')
        
        # ============================================================
        # 6. ایجاد سوالات متداول عمومی
        # ============================================================
        if FAQ.query.count() == 0:
            faqs = [
                {'category': 'general', 'question': 'هزینه تعمیرات دوو در تهران چقدر است؟', 'answer': 'هزینه تعمیرات پس از بررسی توسط تکنسین و با توافق شما تعیین می‌شود. قیمت‌ها بر اساس نوع تعمیرات، قطعات مورد نیاز و زمان انجام کار محاسبه می‌شود.', 'order': 1},
                {'category': 'general', 'question': 'آیا تعمیرات دوو در تهران ضمانت دارد؟', 'answer': 'بله، تمام تعمیرات انجام شده توسط تکنسین‌های ما دارای ضمانت ۳ ماهه می‌باشد. در صورت بروز مشکل مجدد، تعمیرات رایگان انجام می‌شود.', 'order': 2},
                {'category': 'general', 'question': 'چقدر طول می‌کشد تا تکنسین به محل من بیاید؟', 'answer': 'تکنسین‌های ما در کمتر از ۲ ساعت به محل شما اعزام می‌شوند. در مناطق مرکزی تهران این زمان به کمتر از ۱ ساعت نیز می‌رسد.', 'order': 3},
                {'category': 'general', 'question': 'آیا از قطعات اصلی دوو استفاده می‌کنید؟', 'answer': 'بله، تمام قطعات مورد استفاده در تعمیرات، اورجینال و با ضمانت هستند. ما از قطعات اصلی دوو و برندهای معتبر استفاده می‌کنیم.', 'order': 4},
                {'category': 'general', 'question': 'چگونه می‌توانم نوبت تعمیرات بگیرم؟', 'answer': 'شما می‌توانید از طریق وب‌سایت، تماس تلفنی با شماره ۰۲۱-۵۵۵۵-۱۲۳۴ یا اپلیکیشن موبایل ما نوبت خود را رزرو کنید.', 'order': 5},
                {'category': 'pricing', 'question': 'آیا هزینه اعزام تکنسین جدا محاسبه می‌شود؟', 'answer': 'هزینه اعزام تکنسین در تهران بسته به منطقه محل سکونت شما محاسبه می‌شود و بین ۵۰,۰۰۰ تا ۱۵۰,۰۰۰ تومان است.', 'order': 6},
                {'category': 'pricing', 'question': 'آیا قیمت‌های اعلام شده نهایی است؟', 'answer': 'قیمت‌های اعلام شده تخمینی هستند و قیمت نهایی پس از بررسی و عیب‌یابی توسط تکنسین به شما اعلام می‌شود و با توافق شما انجام می‌شود.', 'order': 7},
                {'category': 'emergency', 'question': 'آیا خدمات تعمیرات اضطراری دوو در تهران دارید؟', 'answer': 'بله، خدمات تعمیرات اضطراری ۲۴ ساعته در تمام مناطق تهران ارائه می‌شود. برای ثبت درخواست اضطراری با شماره ۰۹۱۲-۱۲۳-۴۵۶۷ تماس بگیرید.', 'order': 8},
                {'category': 'emergency', 'question': 'در روزهای تعطیل نیز خدمات دارید؟', 'answer': 'بله، حتی در روزهای تعطیل رسمی نیز تکنسین‌های ما برای خدمات ضروری در دسترس هستند. هزینه خدمات در روزهای تعطیل ۲۰٪ بیشتر است.', 'order': 9},
                {'category': 'warranty', 'question': 'ضمانت تعمیرات چقدر است؟', 'answer': 'تمامی تعمیرات ما دارای ضمانت ۳ ماهه هستند. در این مدت اگر مشکلی پیش بیاید، کاملاً رایگان تعمیر می‌شود.', 'order': 10},
                {'category': 'warranty', 'question': 'آیا قطعات تعویض شده ضمانت دارند؟', 'answer': 'بله، تمام قطعاتی که توسط ما تعویض می‌شوند، دارای ضمانت ۶ ماهه هستند.', 'order': 11}
            ]
            
            for faq_data in faqs:
                faq = FAQ(**faq_data)
                db.session.add(faq)
            
            db.session.commit()
            print('[✅] سوالات متداول عمومی ایجاد شدند.')
        
        # ============================================================
        # 7. ایجاد تکنسین‌های نمونه
        # ============================================================
        if Technician.query.count() == 0:
            technicians = [
                {
                    'fullname': 'احمد رضایی',
                    'phone': '09121111111',
                    'national_code': '1234567890',
                    'expertise_areas': json.dumps(['یخچال', 'لباسشویی', 'ظرفشویی']),
                    'skill_level': 'expert',
                    'experience_years': 12,
                    'bio': 'کارشناس ارشد تعمیرات دوو با بیش از ۱۲ سال تجربه در تعمیرات تخصصی لوازم خانگی دوو',
                    'status': 'available',
                    'rating': 4.9,
                    'total_repairs': 1250,
                    'success_rate': 98.5,
                    'avg_response_time': 25,
                    'avg_arrival_time': 45,
                    'work_hours_start': datetime.strptime('08:00', '%H:%M').time(),
                    'work_hours_end': datetime.strptime('20:00', '%H:%M').time(),
                    'work_days': json.dumps([0, 1, 2, 3, 4, 5, 6]),
                    'max_daily_jobs': 5,
                    'current_jobs': 2,
                    'base_salary': 30000000,
                    'commission_percentage': 35,
                    'is_active': True,
                    'is_verified': True,
                    'current_latitude': 35.8136,
                    'current_longitude': 51.4190
                },
                {
                    'fullname': 'محمد کریمی',
                    'phone': '09122222222',
                    'national_code': '2345678901',
                    'expertise_areas': json.dumps(['پکیج', 'مایکروویو', 'اجاق گاز']),
                    'skill_level': 'expert',
                    'experience_years': 10,
                    'bio': 'تخصص در تعمیرات پکیج و سیستم‌های گرمایشی دوو با ۱۰ سال تجربه',
                    'status': 'available',
                    'rating': 4.8,
                    'total_repairs': 980,
                    'success_rate': 97.8,
                    'avg_response_time': 30,
                    'avg_arrival_time': 50,
                    'work_hours_start': datetime.strptime('08:00', '%H:%M').time(),
                    'work_hours_end': datetime.strptime('19:00', '%H:%M').time(),
                    'work_days': json.dumps([0, 1, 2, 3, 4, 5]),
                    'max_daily_jobs': 4,
                    'current_jobs': 1,
                    'base_salary': 28000000,
                    'commission_percentage': 32,
                    'is_active': True,
                    'is_verified': True,
                    'current_latitude': 35.7588,
                    'current_longitude': 51.3193
                },
                {
                    'fullname': 'سارا حسینی',
                    'phone': '09123333333',
                    'national_code': '3456789012',
                    'expertise_areas': json.dumps(['یخچال', 'لباسشویی', 'هود']),
                    'skill_level': 'senior',
                    'experience_years': 8,
                    'bio': 'تخصص در تعمیرات لوازم خانگی دوو با رویکرد مشتری‌مداری و کیفیت بالا',
                    'status': 'available',
                    'rating': 4.7,
                    'total_repairs': 850,
                    'success_rate': 97.2,
                    'avg_response_time': 28,
                    'avg_arrival_time': 42,
                    'work_hours_start': datetime.strptime('09:00', '%H:%M').time(),
                    'work_hours_end': datetime.strptime('21:00', '%H:%M').time(),
                    'work_days': json.dumps([0, 1, 2, 3, 4, 5, 6]),
                    'max_daily_jobs': 4,
                    'current_jobs': 0,
                    'base_salary': 25000000,
                    'commission_percentage': 30,
                    'is_active': True,
                    'is_verified': True,
                    'current_latitude': 35.7184,
                    'current_longitude': 51.4249
                },
                {
                    'fullname': 'علی محمدی',
                    'phone': '09124444444',
                    'national_code': '4567890123',
                    'expertise_areas': json.dumps(['ظرفشویی', 'مایکروویو', 'جاروبرقی']),
                    'skill_level': 'senior',
                    'experience_years': 7,
                    'bio': 'متخصص تعمیرات ظرفشویی و مایکروویو دوو با ۷ سال تجربه',
                    'status': 'busy',
                    'rating': 4.6,
                    'total_repairs': 720,
                    'success_rate': 96.8,
                    'avg_response_time': 32,
                    'avg_arrival_time': 48,
                    'work_hours_start': datetime.strptime('08:00', '%H:%M').time(),
                    'work_hours_end': datetime.strptime('18:00', '%H:%M').time(),
                    'work_days': json.dumps([0, 1, 2, 3, 4]),
                    'max_daily_jobs': 3,
                    'current_jobs': 3,
                    'base_salary': 22000000,
                    'commission_percentage': 28,
                    'is_active': True,
                    'is_verified': True,
                    'current_latitude': 35.7564,
                    'current_longitude': 51.5370
                },
                {
                    'fullname': 'مریم رضایی',
                    'phone': '09125555555',
                    'national_code': '5678901234',
                    'expertise_areas': json.dumps(['یخچال', 'پکیج', 'اجاق گاز']),
                    'skill_level': 'expert',
                    'experience_years': 9,
                    'bio': 'کارشناس تعمیرات دوو با تمرکز بر یخچال‌های ساید بای ساید و پکیج‌های دوو',
                    'status': 'available',
                    'rating': 4.8,
                    'total_repairs': 900,
                    'success_rate': 98.0,
                    'avg_response_time': 27,
                    'avg_arrival_time': 43,
                    'work_hours_start': datetime.strptime('08:00', '%H:%M').time(),
                    'work_hours_end': datetime.strptime('20:00', '%H:%M').time(),
                    'work_days': json.dumps([0, 1, 2, 3, 4, 5, 6]),
                    'max_daily_jobs': 5,
                    'current_jobs': 1,
                    'base_salary': 32000000,
                    'commission_percentage': 35,
                    'is_active': True,
                    'is_verified': True,
                    'current_latitude': 35.7846,
                    'current_longitude': 51.4745
                },
                {
                    'fullname': 'حسین موسوی',
                    'phone': '09126666666',
                    'national_code': '6789012345',
                    'expertise_areas': json.dumps(['لباسشویی', 'ظرفشویی', 'هود']),
                    'skill_level': 'junior',
                    'experience_years': 4,
                    'bio': 'تکنسین جوان و باانرژی دوو با تخصص در لباسشویی و ظرفشویی',
                    'status': 'available',
                    'rating': 4.4,
                    'total_repairs': 450,
                    'success_rate': 95.5,
                    'avg_response_time': 35,
                    'avg_arrival_time': 55,
                    'work_hours_start': datetime.strptime('09:00', '%H:%M').time(),
                    'work_hours_end': datetime.strptime('18:00', '%H:%M').time(),
                    'work_days': json.dumps([0, 1, 2, 3, 4]),
                    'max_daily_jobs': 3,
                    'current_jobs': 0,
                    'base_salary': 18000000,
                    'commission_percentage': 25,
                    'is_active': True,
                    'is_verified': True,
                    'current_latitude': 35.7101,
                    'current_longitude': 51.4058
                }
            ]
            
            for tech_data in technicians:
                technician = Technician(**tech_data)
                db.session.add(technician)
            
            db.session.commit()
            print('[✅] تکنسین‌های نمونه با موقعیت مکانی ایجاد شدند.')
            
            # اتصال تکنسین‌ها به مناطق
            regions = TehranRegion.query.all()
            technicians = Technician.query.all()
            for i, tech in enumerate(technicians):
                # هر تکنسین به ۲-۳ منطقه متصل می‌شود
                for j in range(i % 2, min(i + 3, len(regions))):
                    if regions[j] not in tech.regions:
                        tech.regions.append(regions[j])
            db.session.commit()
            print('[✅] اتصال تکنسین‌ها به مناطق انجام شد.')
        
        # ============================================================
        # 8. ایجاد نظرات نمونه
        # ============================================================
        if Review.query.count() == 0:
            users = User.query.filter(User.role == 'user').all()
            technicians = Technician.query.all()
            services = Service.query.all()
            
            if users and technicians and services:
                reviews = [
                    {'user': users[0], 'tech': technicians[0], 'service': services[0], 'rating': 5, 'title': 'عالی بود!', 'content': 'تکنسین خیلی حرفه‌ای و دقیق بود. یخچال من که چند روز بود کار نمی‌کرد رو در کمتر از ۲ ساعت تعمیر کرد. ممنون از تیم خوب دوو تهران.'},
                    {'user': users[1], 'tech': technicians[1], 'service': services[3], 'rating': 4, 'title': 'راضی بودم', 'content': 'پکیج من مشکل داشت، تکنسین به موقع آمد و مشکل رو برطرف کرد. قیمت مناسبی هم بود.'},
                    {'user': users[2], 'tech': technicians[2], 'service': services[1], 'rating': 5, 'title': 'فوق‌العاده', 'content': 'لباسشویی من خراب شده بود، با یک تماس تکنسین آمد و در کمترین زمان تعمیر کرد. واقعاً راضی هستم.'},
                    {'user': users[3], 'tech': technicians[0], 'service': services[2], 'rating': 4, 'title': 'خوب بود', 'content': 'ظرفشویی مشکل داشت، تکنسین به موقع آمد و خوب تعمیر کرد. فقط کمی دیر رسید.'},
                    {'user': users[0], 'tech': technicians[3], 'service': services[5], 'rating': 5, 'title': 'عالی', 'content': 'مایکروویو من خراب شده بود، با یک تماس تکنسین آمد و در کمتر از یک ساعت تعمیر کرد. ممنون.'},
                    {'user': users[1], 'tech': technicians[4], 'service': services[4], 'rating': 5, 'title': 'بی‌نظیر', 'content': 'جاروبرقی من مشکل داشت، تکنسین با تجربه بود و سریع مشکل رو پیدا و رفع کرد. پیشنهاد می‌کنم.'}
                ]
                
                for review_data in reviews:
                    review = Review(
                        user_id=review_data['user'].id,
                        technician_id=review_data['tech'].id,
                        service_id=review_data['service'].id,
                        rating=review_data['rating'],
                        title=review_data['title'],
                        content=review_data['content'],
                        is_verified=True,
                        is_approved=True
                    )
                    db.session.add(review)
                
                db.session.commit()
                print('[✅] نظرات نمونه ایجاد شدند.')
        
        # ============================================================
        # 9. ایجاد نظرات مشتریان (Testimonial)
        # ============================================================
        if Testimonial.query.count() == 0:
            testimonials = [
                {'customer_name': 'رضا محمدی', 'customer_location': 'منطقه ۱، تهران', 'text': 'خدمات عالی و تکنسین‌های حرفه‌ای. یخچال من را در کمترین زمان تعمیر کردند. حتماً به دوستانم پیشنهاد می‌کنم.', 'rating': 5},
                {'customer_name': 'مریم احمدی', 'customer_location': 'منطقه ۵، تهران', 'text': 'واقعاً راضی هستم از سرعت عمل و کیفیت کار. لباسشویی من مشکل داشت و خیلی خوب تعمیر شد.', 'rating': 5},
                {'customer_name': 'علی رضایی', 'customer_location': 'منطقه ۲، تهران', 'text': 'تکنسین خیلی با تجربه و خوش‌برخورد بود. پکیج من را به بهترین شکل تعمیر کرد. ممنون.', 'rating': 4},
                {'customer_name': 'سارا کریمی', 'customer_location': 'منطقه ۳، تهران', 'text': 'از خدمات شما بسیار راضی هستم. ظرفشویی من مشکل داشت و در کمتر از ۲ ساعت تعمیر شد. عالی بود.', 'rating': 5},
                {'customer_name': 'محمد حسینی', 'customer_location': 'منطقه ۶، تهران', 'text': 'بهترین نمایندگی تعمیرات دوو در تهران. قیمت مناسب و کیفیت عالی.', 'rating': 5},
                {'customer_name': 'زهرا نادری', 'customer_location': 'منطقه ۲۲، تهران', 'text': 'تکنسین به موقع آمد و مایکروویو من رو تعمیر کرد. خیلی خوشحالم از این خدمات.', 'rating': 4}
            ]
            
            for testimonial_data in testimonials:
                testimonial = Testimonial(**testimonial_data)
                db.session.add(testimonial)
            
            db.session.commit()
            print('[✅] نظرات مشتریان ایجاد شدند.')
        
        # ============================================================
        # 10. ایجاد مقالات
        # ============================================================
        if Article.query.count() == 0:
            admin = User.query.filter_by(role='admin').first()
            author_id = admin.id if admin else None
            
            articles = [
                {
                    'title': 'راهنمای کامل عیب‌یابی یخچال دوو',
                    'slug': 'daewoo-refrigerator-troubleshooting-guide',
                    'category': 'refrigerator',
                    'sub_category': 'troubleshooting',
                    'summary': 'در این مقاله به بررسی مشکلات رایج یخچال‌های دوو و راه‌حل‌های آن می‌پردازیم.',
                    'content': '''
                    <p>یخچال‌های دوو از بهترین برندهای لوازم خانگی هستند اما مانند هر دستگاه دیگری ممکن است دچار مشکل شوند. در این مقاله به رایج‌ترین مشکلات یخچال دوو و راه‌حل‌های آن می‌پردازیم.</p>
                    
                    <h4>مشکل ۱: یخچال خنک نمی‌کند</h4>
                    <p>اگر یخچال شما به اندازه کافی خنک نمی‌کند، ممکن است یکی از موارد زیر مشکل داشته باشد:</p>
                    <ul>
                        <li>کمبود گاز مبرد</li>
                        <li>خرابی کمپرسور</li>
                        <li>خرابی ترموستات</li>
                        <li>گرفتگی کندانسور</li>
                    </ul>
                    
                    <h4>مشکل ۲: یخچال صدای زیاد دارد</h4>
                    <p>صدای زیاد می‌تواند دلایل مختلفی داشته باشد:</p>
                    <ul>
                        <li>لرزش کمپرسور</li>
                        <li>خرابی فن اواپراتور</li>
                        <li>برخورد لوله‌ها</li>
                    </ul>
                    
                    <h4>نتیجه‌گیری</h4>
                    <p>برای تعمیر تخصصی یخچال دوو خود، با تکنسین‌های مجرب ما تماس بگیرید.</p>
                    ''',
                    'view_count': 1500,
                    'like_count': 120,
                    'comment_count': 45,
                    'is_featured': True,
                    'is_active': True,
                    'seo_title': 'راهنمای عیب‌یابی یخچال دوو | مشکلات رایج و راه‌حل‌ها',
                    'seo_description': 'آموزش عیب‌یابی و تعمیر یخچال دوو - مشکلات رایج و راه‌حل‌های تخصصی',
                    'seo_keywords': 'عیب‌یابی یخچال دوو, تعمیر یخچال دوو, مشکلات یخچال دوو',
                    'author_id': author_id
                },
                {
                    'title': '۵ نشانه خرابی لباسشویی دوو',
                    'slug': 'daewoo-washing-machine-failure-signs',
                    'category': 'washing_machine',
                    'sub_category': 'maintenance',
                    'summary': 'با این ۵ نشانه می‌توانید خرابی لباسشویی دوو را به موقع تشخیص دهید.',
                    'content': '''
                    <p>تشخیص به موقع خرابی لباسشویی می‌تواند از هزینه‌های سنگین جلوگیری کند. در این مقاله ۵ نشانه مهم خرابی لباسشویی دوو را بررسی می‌کنیم.</p>
                    
                    <h4>۱. آبگیری نامناسب</h4>
                    <p>اگر لباسشویی شما آب کافی نمی‌گیرد یا دیر آب می‌گیرد، ممکن است شیر ورودی یا فیلتر مشکل داشته باشد.</p>
                    
                    <h4>۲. تخلیه نشدن آب</h4>
                    <p>اگر آب داخل لباسشویی باقی می‌ماند، پمپ تخلیه یا فیلتر آن نیاز به بررسی دارد.</p>
                    
                    <h4>۳. نچرخیدن درام</h4>
                    <p>اگر درام لباسشویی نمی‌چرخد، احتمالاً تسمه یا موتور آن خراب شده است.</p>
                    
                    <h4>۴. صدای غیرعادی</h4>
                    <p>صدای تق‌تق یا سایش می‌تواند نشانه خرابی بلبرینگ یا گیر کردن جسم خارجی باشد.</p>
                    
                    <h4>۵. نشتی آب</h4>
                    <p>نشتی آب از لباسشویی معمولاً به دلیل خرابی واشرها یا اتصالات است.</p>
                    
                    <p>در صورت مشاهده هر یک از این نشانه‌ها، با تکنسین‌های ما تماس بگیرید.</p>
                    ''',
                    'view_count': 1200,
                    'like_count': 95,
                    'comment_count': 32,
                    'is_featured': False,
                    'is_active': True,
                    'seo_title': 'نشانه‌های خرابی لباسشویی دوو | ۵ علامت مهم',
                    'seo_description': '۵ نشانه مهم خرابی لباسشویی دوو که باید بدانید - تشخیص به موقع مشکلات',
                    'seo_keywords': 'خرابی لباسشویی دوو, نشانه خرابی لباسشویی, تعمیر لباسشویی دوو',
                    'author_id': author_id
                },
                {
                    'title': 'نکات طلایی برای افزایش عمر پکیج دوو',
                    'slug': 'daewoo-package-lifetime-tips',
                    'category': 'package',
                    'sub_category': 'maintenance',
                    'summary': 'با رعایت این نکات ساده می‌توانید عمر پکیج دوو خود را افزایش دهید.',
                    'content': '''
                    <p>پکیج‌های دوو از باکیفیت‌ترین سیستم‌های گرمایشی هستند اما برای افزایش عمر آنها باید نکاتی را رعایت کنید.</p>
                    
                    <h4>۱. سرویس دوره‌ای</h4>
                    <p>بهتر است سالی یک بار پکیج خود را توسط تکنسین مجرب سرویس کنید.</p>
                    
                    <h4>۲. بررسی فشار آب</h4>
                    <p>فشار آب مناسب برای پکیج بین ۱ تا ۱.۵ بار است. فشار کم یا زیاد به پکیج آسیب می‌زند.</p>
                    
                    <h4>۳. رسوب‌زدایی</h4>
                    <p>رسوبات آب در مبدل حرارتی باعث کاهش راندمان و خرابی پکیج می‌شود.</p>
                    
                    <h4>۴. استفاده از نرم‌کننده آب</h4>
                    <p>استفاده از نرم‌کننده آب از رسوب‌گذاری در پکیج جلوگیری می‌کند.</p>
                    
                    <h4>۵. توجه به علائم هشدار</h4>
                    <p>هرگونه صدای غیرعادی، کاهش آب گرم یا خاموش شدن پکیج را جدی بگیرید.</p>
                    ''',
                    'view_count': 850,
                    'like_count': 72,
                    'comment_count': 28,
                    'is_featured': False,
                    'is_active': True,
                    'seo_title': 'افزایش عمر پکیج دوو | ۵ نکته طلایی',
                    'seo_description': '۵ نکته مهم برای افزایش عمر پکیج دوو - سرویس و نگهداری صحیح',
                    'seo_keywords': 'عمر پکیج دوو, نگهداری پکیج دوو, افزایش عمر پکیج',
                    'author_id': author_id
                },
                {
                    'title': 'مقایسه مدل‌های ظرفشویی دوو',
                    'slug': 'daewoo-dishwasher-models-comparison',
                    'category': 'dishwasher',
                    'sub_category': 'buying-guide',
                    'summary': 'راهنمای خرید بهترین مدل ظرفشویی دوو متناسب با نیاز شما.',
                    'content': '''
                    <p>انتخاب بهترین مدل ظرفشویی دوو با توجه به نیاز و بودجه شما اهمیت دارد. در این مقاله مدل‌های مختلف را با هم مقایسه می‌کنیم.</p>
                    
                    <h4>مدل‌های اقتصادی</h4>
                    <p>ظرفشویی‌های سری DWF با قیمت مناسب و کیفیت خوب، گزینه‌ای عالی برای خانواده‌های کم‌جمعیت هستند.</p>
                    
                    <h4>مدل‌های میان‌رده</h4>
                    <p>سری DFS با امکانات بیشتر مانند خشک‌کن توربو و برنامه‌های شستشوی متنوع.</p>
                    
                    <h4>مدل‌های لوکس</h4>
                    <p>سری DFX با فناوری‌های پیشرفته مانند شستشوی بخار، بی‌صدا و مصرف بهینه آب و انرژی.</p>
                    
                    <h4>جدول مقایسه</h4>
                    <table class="table table-bordered">
                        <tr><th>ویژگی</th><th>DWF</th><th>DFS</th><th>DFX</th></tr>
                        <tr><td>ظرفیت</td><td>۱۲ نفر</td><td>۱۴ نفر</td><td>۱۶ نفر</td></tr>
                        <tr><td>مصرف آب</td><td>۱۲ لیتر</td><td>۱۰ لیتر</td><td>۸ لیتر</td></tr>
                        <tr><td>سطح صدا</td><td>۴۸ dB</td><td>۴۴ dB</td><td>۳۸ dB</td></tr>
                    </table>
                    ''',
                    'view_count': 650,
                    'like_count': 45,
                    'comment_count': 18,
                    'is_featured': False,
                    'is_active': True,
                    'seo_title': 'مقایسه مدل‌های ظرفشویی دوو | راهنمای خرید',
                    'seo_description': 'مقایسه کامل مدل‌های ظرفشویی دوو - بهترین مدل برای نیاز شما',
                    'seo_keywords': 'ظرفشویی دوو, مقایسه ظرفشویی دوو, خرید ظرفشویی دوو',
                    'author_id': author_id
                }
            ]
            
            for article_data in articles:
                article = Article(**article_data)
                db.session.add(article)
            
            db.session.commit()
            print('[✅] مقالات ایجاد شدند.')
            
            # ایجاد کامنت برای مقالات
            for article in Article.query.all():
                users = User.query.filter(User.role == 'user').limit(3).all()
                for i, user in enumerate(users):
                    comment = ArticleComment(
                        article_id=article.id,
                        user_id=user.id,
                        content=f'مطلب عالی بود! ممنون از اطلاعات مفیدی که ارائه دادید. ({i+1})',
                        is_approved=True
                    )
                    db.session.add(comment)
                article.comment_count = len(users)
            
            db.session.commit()
            print('[✅] نظرات مقالات ایجاد شدند.')
        
        # ============================================================
        # 11. ایجاد تراکنش‌های کیف پول
        # ============================================================
        if WalletTransaction.query.count() == 0:
            users = User.query.all()
            for user in users:
                # یک تراکنش شارژ
                deposit = WalletTransaction(
                    user_id=user.id,
                    amount=500000,
                    type='deposit',
                    status='completed',
                    description='شارژ اولیه کیف پول',
                    balance_before=0,
                    balance_after=500000,
                    completed_at=datetime.now()
                )
                db.session.add(deposit)
                
                # یک تراکنش پرداخت (اگر کاربر رزرو داشته باشد)
                if user.bookings.first():
                    payment = WalletTransaction(
                        user_id=user.id,
                        amount=-250000,
                        type='payment',
                        status='completed',
                        description='پرداخت هزینه تعمیرات',
                        balance_before=500000,
                        balance_after=250000,
                        booking_id=user.bookings.first().id,
                        completed_at=datetime.now()
                    )
                    db.session.add(payment)
            
            db.session.commit()
            print('[✅] تراکنش‌های کیف پول ایجاد شدند.')
        
        # ============================================================
        # 12. ایجاد اعلان‌ها
        # ============================================================
        if Notification.query.count() == 0:
            users = User.query.all()
            for user in users[:5]:
                notifications = [
                    {
                        'user_id': user.id,
                        'type': 'welcome',
                        'title': 'خوش آمدید!',
                        'message': 'به نمایندگی تعمیرات دوو تهران خوش آمدید. از خدمات ما لذت ببرید.',
                        'is_read': False,
                        'is_sent': True,
                        'sent_at': datetime.now()
                    },
                    {
                        'user_id': user.id,
                        'type': 'promotion',
                        'title': 'تخفیف ویژه',
                        'message': 'تا پایان ماه، ۱۰٪ تخفیف برای تمام خدمات تعمیرات دوو.',
                        'is_read': True,
                        'is_sent': True,
                        'sent_at': datetime.now()
                    },
                    {
                        'user_id': user.id,
                        'type': 'reminder',
                        'title': 'یادآوری سرویس',
                        'message': 'زمان سرویس دوره‌ی دستگاه‌های دوو شما فرا رسیده است.',
                        'is_read': False,
                        'is_sent': True,
                        'sent_at': datetime.now()
                    }
                ]
                for notif_data in notifications:
                    notification = Notification(**notif_data)
                    db.session.add(notification)
            
            db.session.commit()
            print('[✅] اعلان‌ها ایجاد شدند.')
        
        # ============================================================
        # 13. ایجاد محتوای پویا برای مناطق
        # ============================================================
        if DynamicContent.query.count() == 0:
            regions = TehranRegion.query.filter_by(is_active=True).limit(5).all()
            for region in regions:
                create_region_content(region.id)
            print('[✅] محتوای پویا برای مناطق ایجاد شد.')
        
        # ============================================================
        # 14. ایجاد بانک کلمات کلیدی
        # ============================================================
        if KeywordBank.query.count() == 0:
            keywords = [
                {'keyword': 'تعمیرات دوو در تهران', 'category': 'brand', 'search_volume': 1000, 'priority': 10, 'competition': 0.8, 'difficulty': 70},
                {'keyword': 'تعمیر یخچال دوو در تهران', 'category': 'service', 'search_volume': 800, 'priority': 10, 'competition': 0.7, 'difficulty': 65},
                {'keyword': 'تعمیر لباسشویی دوو در تهران', 'category': 'service', 'search_volume': 700, 'priority': 9, 'competition': 0.6, 'difficulty': 60},
                {'keyword': 'تعمیر ظرفشویی دوو', 'category': 'service', 'search_volume': 500, 'priority': 8, 'competition': 0.5, 'difficulty': 55},
                {'keyword': 'تعمیر پکیج دوو', 'category': 'service', 'search_volume': 600, 'priority': 9, 'competition': 0.6, 'difficulty': 60},
                {'keyword': 'نمایندگی دوو در منطقه ۱', 'category': 'region', 'search_volume': 300, 'priority': 8, 'competition': 0.4, 'difficulty': 45},
                {'keyword': 'نمایندگی دوو در منطقه ۵', 'category': 'region', 'search_volume': 350, 'priority': 8, 'competition': 0.4, 'difficulty': 45},
                {'keyword': 'تعمیرات دوو در سعادت‌آباد', 'category': 'neighborhood', 'search_volume': 250, 'priority': 7, 'competition': 0.3, 'difficulty': 40},
                {'keyword': 'تعمیرات دوو در تجریش', 'category': 'neighborhood', 'search_volume': 280, 'priority': 7, 'competition': 0.3, 'difficulty': 40},
                {'keyword': 'تعمیرات دوو در شهرک غرب', 'category': 'neighborhood', 'search_volume': 320, 'priority': 8, 'competition': 0.4, 'difficulty': 45},
                {'keyword': 'بهترین تعمیرکار دوو در تهران', 'category': 'brand', 'search_volume': 450, 'priority': 9, 'competition': 0.7, 'difficulty': 65},
                {'keyword': 'تعمیرات تخصصی دوو', 'category': 'brand', 'search_volume': 400, 'priority': 8, 'competition': 0.6, 'difficulty': 55},
                {'keyword': 'قطعات اصلی دوو', 'category': 'parts', 'search_volume': 200, 'priority': 6, 'competition': 0.3, 'difficulty': 35},
                {'keyword': 'ضمانت تعمیرات دوو', 'category': 'warranty', 'search_volume': 180, 'priority': 6, 'competition': 0.3, 'difficulty': 35},
                {'keyword': 'قیمت تعمیرات دوو', 'category': 'pricing', 'search_volume': 350, 'priority': 7, 'competition': 0.5, 'difficulty': 50},
                {'keyword': 'تعمیرات فوری دوو', 'category': 'emergency', 'search_volume': 280, 'priority': 7, 'competition': 0.4, 'difficulty': 45},
                {'keyword': 'تعمیرات دوو در شب', 'category': 'emergency', 'search_volume': 150, 'priority': 5, 'competition': 0.2, 'difficulty': 30},
                {'keyword': 'تعمیر ساید بای ساید دوو', 'category': 'service', 'search_volume': 400, 'priority': 8, 'competition': 0.5, 'difficulty': 55},
                {'keyword': 'تعمیر هود دوو', 'category': 'service', 'search_volume': 250, 'priority': 7, 'competition': 0.4, 'difficulty': 45},
                {'keyword': 'تعمیر مایکروویو دوو', 'category': 'service', 'search_volume': 220, 'priority': 6, 'competition': 0.3, 'difficulty': 40},
                {'keyword': 'تعمیر اجاق گاز دوو', 'category': 'service', 'search_volume': 200, 'priority': 6, 'competition': 0.3, 'difficulty': 40},
                {'keyword': 'نصب دوو', 'category': 'installation', 'search_volume': 150, 'priority': 5, 'competition': 0.2, 'difficulty': 30},
                {'keyword': 'سرویس دوره‌ای دوو', 'category': 'maintenance', 'search_volume': 120, 'priority': 4, 'competition': 0.2, 'difficulty': 25},
                {'keyword': 'دوو تهران', 'category': 'brand', 'search_volume': 900, 'priority': 10, 'competition': 0.7, 'difficulty': 65}
            ]
            
            for kw_data in keywords:
                keyword = KeywordBank(**kw_data)
                db.session.add(keyword)
            
            db.session.commit()
            print('[✅] بانک کلمات کلیدی کامل ایجاد شد.')
        
        # ============================================================
        # 15. ایجاد قالب‌های محتوا
        # ============================================================
        if ContentTemplate.query.count() == 0:
            templates = [
                {
                    'name': 'صفحه منطقه',
                    'description': 'قالب استاندارد برای صفحات مناطق تهران',
                    'type': 'region_page',
                    'template_content': '''
                    <h1>تعمیرات دوو در {{ region.name }}</h1>
                    <p>تعمیرات تخصصی دوو در منطقه {{ region.region_number }} تهران با بهترین کیفیت و قیمت مناسب.</p>
                    
                    <h2>خدمات ما در {{ region.name }}</h2>
                    <ul>
                    {% for service in services %}
                        <li>{{ service.title }} - از {{ service.price_range_min }} تومان</li>
                    {% endfor %}
                    </ul>
                    
                    <h2>تکنسین‌های فعال در {{ region.name }}</h2>
                    <ul>
                    {% for tech in technicians %}
                        <li>{{ tech.fullname }} - {{ tech.expertise_areas }}</li>
                    {% endfor %}
                    </ul>
                    
                    <h2>محله‌های تحت پوشش</h2>
                    <ul>
                    {% for district in districts %}
                        <li>{{ district }}</li>
                    {% endfor %}
                    </ul>
                    
                    <h2>خیابان‌های اصلی</h2>
                    <ul>
                    {% for street in streets %}
                        <li>{{ street }}</li>
                    {% endfor %}
                    </ul>
                    ''',
                    'variables_schema': json.dumps({
                        'title': 'string',
                        'region': 'object',
                        'services': 'array',
                        'technicians': 'array',
                        'districts': 'array',
                        'streets': 'array'
                    }),
                    'is_active': True,
                    'is_default': True
                },
                {
                    'name': 'صفحه سرویس',
                    'description': 'قالب استاندارد برای صفحات خدمات',
                    'type': 'service_page',
                    'template_content': '''
                    <h1>تعمیر {{ service.title }} در تهران</h1>
                    <p>{{ service.description }}</p>
                    
                    <h2>هزینه تعمیر {{ service.title }}</h2>
                    <p>از {{ service.price_range_min }} تا {{ service.price_range_max }} تومان</p>
                    
                    <h2>زمان انجام کار</h2>
                    <p>حدود {{ service.estimated_time }} دقیقه</p>
                    ''',
                    'variables_schema': json.dumps({
                        'service': 'object'
                    }),
                    'is_active': True,
                    'is_default': True
                }
            ]
            
            for template_data in templates:
                template = ContentTemplate(**template_data)
                db.session.add(template)
            
            db.session.commit()
            print('[✅] قالب‌های محتوا ایجاد شدند.')
        
        # ============================================================
        # 16. ایجاد رزروهای نمونه
        # ============================================================
        if Booking.query.count() == 0:
            users = User.query.filter(User.role == 'user').all()
            services = Service.query.all()
            regions = TehranRegion.query.all()
            technicians = Technician.query.all()
            
            booking_statuses = ['pending', 'confirmed', 'in_progress', 'completed', 'cancelled']
            
            for i, user in enumerate(users[:3]):
                for j in range(3):
                    service = services[j % len(services)]
                    region = regions[i % len(regions)]
                    tech = technicians[j % len(technicians)] if technicians else None
                    
                    booking = Booking(
                        booking_number=f'DW{datetime.now().strftime("%y%m%d")}{i}{j}',
                        user_id=user.id,
                        technician_id=tech.id if tech else None,
                        service_id=service.id,
                        region_id=region.id,
                        address=f'تهران، منطقه {region.region_number}، خیابان نمونه {i+1}، پلاک {j+1}',
                        latitude=region.latitude + (i * 0.01),
                        longitude=region.longitude + (j * 0.01),
                        scheduled_date=datetime.now().date() + timedelta(days=j),
                        scheduled_time=datetime.strptime(f'{9 + j}:00', '%H:%M').time(),
                        status=booking_statuses[j % len(booking_statuses)],
                        payment_status='paid' if j % 2 == 0 else 'pending',
                        payment_method='online' if j % 2 == 0 else 'cash',
                        description=f'درخواست تعمیر {service.title}',
                        estimated_price=service.price_range_min + (j * 50000),
                        final_price=service.price_range_min + (j * 50000) if j % 2 == 0 else None,
                        is_home_service=True,
                        created_at=datetime.now() - timedelta(days=j)
                    )
                    db.session.add(booking)
            
            db.session.commit()
            print('[✅] رزروهای نمونه ایجاد شدند.')
        
        # ============================================================
        # 17. ایجاد آمار بازدید (AnalyticsUser)
        # ============================================================
        if AnalyticsUser.query.count() == 0:
            from faker import Faker
            import random
            
            try:
                fake = Faker('fa_IR')
                
                devices = ['mobile', 'desktop', 'tablet']
                browsers = ['Chrome', 'Firefox', 'Safari', 'Edge', 'Opera']
                os_list = ['Windows', 'macOS', 'Android', 'iOS', 'Linux']
                
                for i in range(20):
                    analytics = AnalyticsUser(
                        session_id=f'session_{i}_{random.randint(1000, 9999)}',
                        ip_address=f'192.168.{random.randint(1, 255)}.{random.randint(1, 255)}',
                        user_agent=f'Mozilla/5.0 (compatible)',
                        referrer='https://google.com' if random.random() > 0.5 else 'https://instagram.com',
                        landing_page='/',
                        device_type=random.choice(devices),
                        browser=random.choice(browsers),
                        os=random.choice(os_list),
                        screen_resolution=f'{random.choice([1366, 1920, 1024, 768])}x{random.choice([768, 1080, 900])}',
                        location_city='تهران',
                        location_region=random.choice(['منطقه ۱', 'منطقه ۲', 'منطقه ۵', 'منطقه ۶']),
                        is_new_visitor=random.random() > 0.3,
                        created_at=datetime.now() - timedelta(days=random.randint(0, 30)),
                        last_activity=datetime.now() - timedelta(hours=random.randint(0, 72))
                    )
                    db.session.add(analytics)
            except:
                pass  # اگر Faker نصب نبود، رد شود
            
            db.session.commit()
            print('[✅] آمار بازدید ایجاد شد.')
        
        # ============================================================
        # 18. ایجاد قیمت‌گذاری پویا
        # ============================================================
        if DynamicPricing.query.count() == 0:
            services = Service.query.all()
            regions = TehranRegion.query.filter_by(is_active=True).limit(5).all()
            
            for service in services[:5]:
                for region in regions:
                    pricing = DynamicPricing(
                        service_id=service.id,
                        region_id=region.id,
                        base_price=service.price_range_min or 200000,
                        peak_hour_multiplier=1.2,
                        off_peak_multiplier=0.9,
                        emergency_multiplier=1.5,
                        weekend_multiplier=1.15,
                        holiday_multiplier=1.3,
                        distance_charge_per_km=5000,
                        min_distance_charge=50000,
                        is_active=True
                    )
                    db.session.add(pricing)
            
            db.session.commit()
            print('[✅] قیمت‌گذاری پویا ایجاد شد.')

    # ============================================================
    # 19. ایجاد دسته‌بندی‌های خطا
    # ============================================================
        if ErrorCategory.query.count() == 0:
            error_categories = [
                {'name': 'یخچال', 'slug': 'refrigerator', 'icon': 'fa-solid fa-snowflake', 
                 'description': 'راهنمای رفع خطاهای رایج یخچال‌های دوو',
                 'seo_title': 'خطاهای یخچال دوو | راهنمای عیب‌یابی',
                 'seo_description': 'راهنمای کامل خطاهای یخچال دوو - عیب‌یابی و رفع مشکلات',
                 'seo_keywords': 'خطاهای یخچال دوو, عیب‌یابی یخچال دوو', 'is_active': True},
                {'name': 'لباسشویی', 'slug': 'washing-machine', 'icon': 'fa-solid fa-tshirt',
                 'description': 'راهنمای رفع خطاهای رایج لباسشویی‌های دوو',
                 'seo_title': 'خطاهای لباسشویی دوو | راهنمای عیب‌یابی',
                 'seo_description': 'راهنمای کامل خطاهای لباسشویی دوو - عیب‌یابی و رفع مشکلات',
                 'seo_keywords': 'خطاهای لباسشویی دوو, عیب‌یابی لباسشویی دوو', 'is_active': True},
                {'name': 'ظرفشویی', 'slug': 'dishwasher', 'icon': 'fa-solid fa-utensils',
                 'description': 'راهنمای رفع خطاهای رایج ظرفشویی‌های دوو',
                 'seo_title': 'خطاهای ظرفشویی دوو | راهنمای عیب‌یابی',
                 'seo_description': 'راهنمای کامل خطاهای ظرفشویی دوو - عیب‌یابی و رفع مشکلات',
                 'seo_keywords': 'خطاهای ظرفشویی دوو, عیب‌یابی ظرفشویی دوو', 'is_active': True},
                {'name': 'پکیج', 'slug': 'package', 'icon': 'fa-solid fa-fire',
                 'description': 'راهنمای رفع خطاهای رایج پکیج‌های دوو',
                 'seo_title': 'خطاهای پکیج دوو | راهنمای عیب‌یابی',
                 'seo_description': 'راهنمای کامل خطاهای پکیج دوو - عیب‌یابی و رفع مشکلات',
                 'seo_keywords': 'خطاهای پکیج دوو, عیب‌یابی پکیج دوو', 'is_active': True},
                {'name': 'جاروبرقی', 'slug': 'vacuum', 'icon': 'fa-solid fa-broom',
                 'description': 'راهنمای رفع خطاهای رایج جاروبرقی‌های دوو',
                 'seo_title': 'خطاهای جاروبرقی دوو | راهنمای عیب‌یابی',
                 'seo_description': 'راهنمای کامل خطاهای جاروبرقی دوو - عیب‌یابی و رفع مشکلات',
                 'seo_keywords': 'خطاهای جاروبرقی دوو, عیب‌یابی جاروبرقی دوو', 'is_active': True},
                {'name': 'مایکروویو', 'slug': 'microwave', 'icon': 'fa-solid fa-micro-wave',
                 'description': 'راهنمای رفع خطاهای رایج مایکروویوهای دوو',
                 'seo_title': 'خطاهای مایکروویو دوو | راهنمای عیب‌یابی',
                 'seo_description': 'راهنمای کامل خطاهای مایکروویو دوو - عیب‌یابی و رفع مشکلات',
                 'seo_keywords': 'خطاهای مایکروویو دوو, عیب‌یابی مایکروویو دوو', 'is_active': True}
            ]
            
            for cat_data in error_categories:
                category = ErrorCategory(**cat_data)
                db.session.add(category)
            
            db.session.commit()
            print('[✅] دسته‌بندی خطاها ایجاد شدند.')
        
        # ============================================================
        # 20. ایجاد خطاهای نمونه
        # ============================================================
        if ErrorSolution.query.count() == 0:
            categories = ErrorCategory.query.all()
            category_map = {c.name: c.id for c in categories}
            
            error_solutions = [
                {'category_name': 'یخچال', 'error_code': 'E1', 
                 'error_title': 'یخچال خنک نمی‌کند',
                 'error_description': 'یخچال روشن است اما به اندازه کافی خنک نمی‌کند.',
                 'symptoms': 'غذای داخل یخچال گرم می‌شود، کمپرسور روشن و خاموش می‌شود.',
                 'solution_steps': '1. پریز برق یخچال را چک کنید\n2. ترموستات را بررسی کنید\n3. کندانسور پشت یخچال را تمیز کنید\n4. اگر مشکل ادامه داشت با تکنسین تماس بگیرید',
                 'difficulty_level': 'medium', 'estimated_time': 30, 'tools_needed': 'جاروبرقی، پیچ‌گوشتی',
                 'can_self_fix': True, 'is_featured': True,
                 'seo_title': 'رفع خطای خنک نکردن یخچال دوو',
                 'seo_description': 'راهنمای کامل رفع خطای خنک نکردن یخچال دوو',
                 'seo_keywords': 'یخچال خنک نمی‌کند, تعمیر یخچال دوو'},
                {'category_name': 'لباسشویی', 'error_code': 'L1',
                 'error_title': 'لباسشویی آب نمی‌گیرد',
                 'error_description': 'لباسشویی روشن می‌شود اما آب ورودی ندارد.',
                 'symptoms': 'موتور صدای خشک می‌دهد، برنامه شروع نمی‌شود',
                 'solution_steps': '1. شیر آب ورودی را چک کنید\n2. فیلتر ورودی آب را تمیز کنید\n3. فشار آب ساختمان را بررسی کنید',
                 'difficulty_level': 'easy', 'estimated_time': 15, 'tools_needed': 'آچار، مسواک',
                 'can_self_fix': True, 'is_featured': False,
                 'seo_title': 'رفع خطای آب نگرفتن لباسشویی دوو',
                 'seo_description': 'راهنمای کامل رفع خطای آب نگرفتن لباسشویی دوو',
                 'seo_keywords': 'لباسشویی آب نمی‌گیرد, تعمیر لباسشویی دوو'},
                {'category_name': 'پکیج', 'error_code': 'P1',
                 'error_title': 'پکیج آب گرم تولید نمی‌کند',
                 'error_description': 'پکیج روشن است اما آب گرم تولید نمی‌کند.',
                 'symptoms': 'آب سرد از شیرها خارج می‌شود، پکیج خاموش و روشن می‌شود',
                 'solution_steps': '1. فشار آب پکیج را بررسی کنید\n2. شیر گاز پکیج را چک کنید\n3. ترموستات آب گرم را تنظیم کنید',
                 'difficulty_level': 'hard', 'estimated_time': 45, 'tools_needed': 'آچار، فشارسنج',
                 'can_self_fix': False, 'is_featured': True,
                 'seo_title': 'رفع خطای آب گرم نکردن پکیج دوو',
                 'seo_description': 'راهنمای کامل رفع خطای آب گرم نکردن پکیج دوو',
                 'seo_keywords': 'پکیج آب گرم نمی‌کند, تعمیر پکیج دوو'}
            ]
            
            for sol_data in error_solutions:
                category_id = category_map.get(sol_data['category_name'])
                if category_id:
                    sol_data['category_id'] = category_id
                    del sol_data['category_name']
                    category = ErrorCategory.query.get(category_id)
                    sol_data['slug'] = generate_error_slug(sol_data['error_title'], category.name)
                    solution = ErrorSolution(**sol_data)
                    db.session.add(solution)
            
            db.session.commit()
            print('[✅] خطاهای نمونه ایجاد شدند.')
        # ============================================================
        # خلاصه نهایی
        # ============================================================
        print('\n' + '='*70)
        print('✅ ✅ ✅ مقداردهی دیتابیس با موفقیت کامل شد! ✅ ✅ ✅')
        print('='*70)
        print('\n📊 خلاصه اطلاعات:')
        print(f'👤 کاربران: {User.query.count()} (ادمین: {User.query.filter_by(role="admin").count()})')
        print(f'🗺️ مناطق تهران: {TehranRegion.query.count()}')
        print(f'🔧 خدمات: {Service.query.count()}')
        print(f'📋 جزئیات خدمات: {ServiceDetail.query.count()}')
        print(f'❓ سوالات متداول خدمات: {ServiceFAQ.query.count()}')
        print(f'👨‍🔧 تکنسین‌ها: {Technician.query.count()}')
        print(f'⭐ نظرات: {Review.query.count()}')
        print(f'💬 نظرات مشتریان: {Testimonial.query.count()}')
        print(f'📝 مقالات: {Article.query.count()}')
        print(f'💬 نظرات مقالات: {ArticleComment.query.count()}')
        print(f'❓ سوالات متداول عمومی: {FAQ.query.count()}')
        print(f'💰 تراکنش‌های کیف پول: {WalletTransaction.query.count()}')
        print(f'🔔 اعلان‌ها: {Notification.query.count()}')
        print(f'🔑 کلمات کلیدی: {KeywordBank.query.count()}')
        print(f'📄 محتوای پویا: {DynamicContent.query.count()}')
        print(f'📋 قالب‌های محتوا: {ContentTemplate.query.count()}')
        print(f'📅 رزروها: {Booking.query.count()}')
        print(f'📊 آمار بازدید: {AnalyticsUser.query.count()}')
        print(f'💰 قیمت‌گذاری پویا: {DynamicPricing.query.count()}')
        
        print('\n🔐 اطلاعات ورود ادمین:')
        print('   📱 تلفن: 09120000000')
        print('   🔑 رمز: Admin@12345')
        print('\n👤 اطلاعات ورود کاربران نمونه:')
        print('   📱 تلفن: 09123334444 تا 09126667777')
        print('   🔑 رمز: User@12345')
        print('='*70)
# ================================================================
# ===== اجرای برنامه =====
# ================================================================
# ================================================================
# ===== اجرای برنامه =====
# ================================================================
# ================================================================
# ===== اجرای برنامه =====
# ================================================================

# ================================================================
# ===== اجرای برنامه =====
# ================================================================
# ================================================================
# ===== اجرای برنامه =====
# ================================================================

# ================================================================
# ===== اجرای برنامه =====
# ================================================================
# ================================================================
# ===== اجرای برنامه =====
# ================================================================
if __name__ == '__main__':
    print('='*60)
    print('🚀 در حال راه‌اندازی سایت...')
    print('='*60)
    
    with app.app_context():
        try:
            print('📦 مرحله 1: ایجاد جداول دیتابیس...')
            db.create_all()
            print('✅ جداول ایجاد شدند.')
            
            # ===== مقداردهی اولیه (همیشه اجرا میشه) =====
            print('📦 مرحله 2: مقداردهی اولیه دیتابیس...')
            init_db()  # <-- این همه چی رو درست میکنه
            print('✅ دیتابیس مقداردهی شد.')
            
            # ===== هدف‌گذاری کلمات کلیدی =====
            print('📦 مرحله 3: هدف‌گذاری کلمات کلیدی...')
            count = KeywordBank.query.filter_by(is_active=True).update({'is_targeted': True})
            db.session.commit()
            print(f'✅ {count} کلمه هدف‌گذاری شد.')
            
            # ===== تولید صفحات سئو =====
            print('📦 مرحله 4: تولید صفحات سئو...')
            seo_count = update_all_seo_pages()
            print(f'✅ {seo_count} صفحه سئو تولید شد.')
            
            # ===== تولید سایتمپ =====
            print('📦 مرحله 5: تولید سایتمپ...')
            sitemap_count = generate_sitemap()
            print(f'✅ {sitemap_count} URL در سایتمپ ثبت شد.')
            
            # ===== بروزرسانی تنظیمات سئو =====
            print('📦 مرحله 6: بروزرسانی تنظیمات سئو...')
            update_seo_globally()
            print('✅ تنظیمات سئو بروزرسانی شد.')
            
            # ===== آمار نهایی =====
            total_keywords = KeywordBank.query.filter_by(is_active=True).count()
            targeted_keywords = KeywordBank.query.filter_by(is_active=True, is_targeted=True).count()
            seo_pages_count = SEOPage.query.filter_by(is_active=True).count()
            
            print('='*60)
            print('📊 آمار نهایی:')
            print(f'   🔑 {total_keywords} کلمه کلیدی فعال')
            print(f'   🎯 {targeted_keywords} کلمه هدف‌گذاری شده')
            print(f'   📄 {seo_pages_count} صفحه سئو')
            print(f'   🗺️ {sitemap_count} URL در سایتمپ')
            print('='*60)
            
        except Exception as e:
            print(f'❌ خطا: {e}')
            import traceback
            traceback.print_exc()
    
    # ===== Scheduler =====
    try:
        start_scheduler()
        print('✅ بروزرسانی خودکار سئو فعال شد.')
    except Exception as e:
        print(f'❌ خطا در Scheduler: {e}')
    
    print('='*60)
    print('🚀 سایت با موفقیت راه‌اندازی شد!')
    print('='*60)
    print(f'🌐 آدرس: http://localhost:5000')
    print(f'🔐 ادمین: 09120000000 / Admin@12345')
    print('='*60)
    
    app.run(debug=True, host='0.0.0.0', port=5000)