# ============================================
# 1. ایمپورت‌های اصلی
# ============================================
from flask import Flask, render_template, request, redirect, url_for, flash, session, jsonify, send_file, abort
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity, unset_jwt_cookies
from werkzeug.utils import secure_filename
from flask_mail import Mail, Message
from flask_caching import Cache
from werkzeug.utils import secure_filename
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime, timedelta
from functools import wraps
import json
import os
import re
import hashlib
import secrets
from PIL import Image
import jdatetime
from zoneinfo import ZoneInfo
import logging
from logging.handlers import RotatingFileHandler
from apscheduler.schedulers.background import BackgroundScheduler
import pytz
import re

# ============================================
# 2. راه‌اندازی Flask و تنظیمات
# ============================================
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here-change-in-production'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///shop.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['JWT_SECRET_KEY'] = 'jwt-secret-key-change-in-production'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=24)
app.config['UPLOADED_PHOTOS_DEST'] = 'static/uploads'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'your-email@gmail.com'
app.config['MAIL_PASSWORD'] = 'your-app-password'
app.config['MAIL_DEFAULT_SENDER'] = 'your-email@gmail.com'
app.config['CACHE_TYPE'] = 'SimpleCache'
app.config['CACHE_DEFAULT_TIMEOUT'] = 300

# ============================================
# 3. راه‌اندازی افزونه‌ها
# ============================================
db = SQLAlchemy(app)
migrate = Migrate(app, db)
jwt = JWTManager(app)
mail = Mail(app)
cache = Cache(app)

# تنظیمات آپلود عکس
#photos = UploadSet('photos', IMAGES)
#configure_uploads(app, photos)

# ============================================
# 4. راه‌اندازی لاگ
# ============================================
if not os.path.exists('logs'):
    os.makedirs('logs')
handler = RotatingFileHandler('logs/app.log', maxBytes=10000, backupCount=3)
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
app.logger.addHandler(handler)


# ============================================
# 5. مدل‌های دیتابیس
# ============================================
@app.after_request
def add_security_headers(response):
    response.headers['Content-Security-Policy'] = "default-src 'self'; script-src 'self' 'unsafe-inline' https://code.jquery.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; img-src 'self' data: https:; font-src 'self' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; connect-src 'self'"
    response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
    return response
# 5.1 مدل کاربران

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=True)  # اختیاری
    email = db.Column(db.String(120), unique=True, nullable=True)  # اختیاری
    password = db.Column(db.String(200), nullable=False)  # اجباری
    full_name = db.Column(db.String(150), nullable=False)  # اجباری
    phone = db.Column(db.String(20), nullable=False)  # اجباری
    address = db.Column(db.Text, nullable=True)  # اختیاری
    postal_code = db.Column(db.String(20), nullable=True)  # اختیاری
    role = db.Column(db.String(20), default='user')
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    last_login = db.Column(db.DateTime)
    # روابط
    orders = db.relationship('Order', backref='user', lazy=True)
    reviews = db.relationship('Review', backref='user', lazy=True)
    wishlist = db.relationship('Wishlist', backref='user', lazy=True)
    carts = db.relationship('Cart', backref='user', lazy=True)
    
    def set_password(self, password):
        self.password = generate_password_hash(password)
    
    def check_password(self, password):
        return check_password_hash(self.password, password)

# 5.2 مدل دسته‌بندی
class Category(db.Model):
    __tablename__ = 'categories'
    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)
    parent_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    image = db.Column(db.String(200))
    description = db.Column(db.Text)
    order = db.Column(db.Integer, default=0)
    seo_title = db.Column(db.String(150))
    seo_description = db.Column(db.String(300))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # روابط
    children = db.relationship('Category', backref=db.backref('parent', remote_side=[id]), lazy=True)
    products = db.relationship('Product', backref='category', lazy=True)

# 5.3 مدل برند
class Brand(db.Model):
    __tablename__ = 'brands'
    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)
    logo = db.Column(db.String(200))
    is_active = db.Column(db.Boolean, default=True)
    
    # روابط
    products = db.relationship('Product', backref='brand', lazy=True)

# 5.4 مدل محصول (مهم‌ترین)
class Product(db.Model):
    __tablename__ = 'products'
    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)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    brand_id = db.Column(db.Integer, db.ForeignKey('brands.id'))
    description = db.Column(db.Text)
    short_description = db.Column(db.String(300))
    price = db.Column(db.Integer, nullable=False)
    compare_price = db.Column(db.Integer)
    cost_per_item = db.Column(db.Integer)
    stock_quantity = db.Column(db.Integer, default=0)
    sku = db.Column(db.String(50), unique=True)
    weight = db.Column(db.Float, default=0)
    is_active = db.Column(db.Boolean, default=True)
    is_featured = db.Column(db.Boolean, default=False)
    is_new = db.Column(db.Boolean, default=False)
    discount_percent = db.Column(db.Integer, default=0)
    discount_price = db.Column(db.Integer)
    discount_start = db.Column(db.DateTime)
    discount_end = db.Column(db.DateTime)
    shipping_cost = db.Column(db.Integer, default=0)
    free_shipping = db.Column(db.Boolean, default=False)
    views = db.Column(db.Integer, default=0)
    sold_count = db.Column(db.Integer, default=0)
    seo_title = db.Column(db.String(150))
    seo_description = db.Column(db.String(300))
    seo_keywords = db.Column(db.String(200))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # روابط
    images = db.relationship('ProductImage', backref='product', lazy=True, cascade='all, delete-orphan')
    specs = db.relationship('ProductSpec', backref='product', lazy=True, cascade='all, delete-orphan')
    reviews = db.relationship('Review', backref='product', lazy=True)
    cart_items = db.relationship('Cart', backref='product', lazy=True)
    wishlist_items = db.relationship('Wishlist', backref='product', lazy=True)
    order_items = db.relationship('OrderItem', backref='product', lazy=True)
    
    def get_final_price(self):
        """محاسبه قیمت نهایی با تخفیف"""
        if self.discount_percent and self.discount_percent > 0:
            if self.discount_start and self.discount_end:
                now = datetime.utcnow()
                if self.discount_start <= now <= self.discount_end:
                    return int(self.price * (1 - self.discount_percent / 100))
            return int(self.price * (1 - self.discount_percent / 100))
        if self.discount_price and self.discount_price > 0:
            if self.discount_start and self.discount_end:
                now = datetime.utcnow()
                if self.discount_start <= now <= self.discount_end:
                    return self.discount_price
            return self.discount_price
        return self.price
    
    def is_in_stock(self):
        return self.stock_quantity > 0

# 5.5 مدل تصاویر محصول
class ProductImage(db.Model):
    __tablename__ = 'product_images'
    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    image_url = db.Column(db.String(300), nullable=False)
    is_main = db.Column(db.Boolean, default=False)
    order = db.Column(db.Integer, default=0)

# 5.6 مدل مشخصات فنی
class ProductSpec(db.Model):
    __tablename__ = 'product_specs'
    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    spec_key = db.Column(db.String(100), nullable=False)
    spec_value = db.Column(db.String(200), nullable=False)

# 5.7 مدل کلمات کلیدی سئو
class Keyword(db.Model):
    __tablename__ = 'keywords'
    id = db.Column(db.Integer, primary_key=True)
    keyword = db.Column(db.String(100), unique=True, nullable=False)
    slug = db.Column(db.String(100), unique=True, nullable=False)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    search_volume = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    
    # روابط
    seo_pages = db.relationship('SeoPage', backref='keyword', lazy=True)

# 5.8 مدل صفحات سئو
class SeoPage(db.Model):
    __tablename__ = 'seo_pages'
    id = db.Column(db.Integer, primary_key=True)
    keyword_id = db.Column(db.Integer, db.ForeignKey('keywords.id'), nullable=False)
    title = db.Column(db.String(150), nullable=False)
    description = db.Column(db.Text)
    content = db.Column(db.Text)
    meta_title = db.Column(db.String(150))
    meta_description = db.Column(db.String(300))
    slug = db.Column(db.String(100), unique=True, nullable=False)
    product_ids = db.Column(db.Text)  # ذخیره به صورت "1,2,3,4"
    views = db.Column(db.Integer, default=0)
    is_indexed = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

# 5.9 مدل سبد خرید
class Cart(db.Model):
    __tablename__ = 'cart'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    session_id = db.Column(db.String(100))
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    quantity = db.Column(db.Integer, default=1)
    price_at_add = db.Column(db.Integer)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

# ============================================
# مدل جوایز و امتیازات
# ============================================
class Reward(db.Model):
    __tablename__ = 'rewards'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    points = db.Column(db.Integer, default=0)
    level = db.Column(db.String(50), default='برنزی')
    total_purchases = db.Column(db.Integer, default=0)
    total_spent = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # روابط
    user = db.relationship('User', backref='reward')
    
    def get_level_badge(self):
        """دریافت نشان سطح"""
        if self.points >= 1000:
            return 'پلاتینیوم 💎'
        elif self.points >= 500:
            return 'طلایی 🥇'
        elif self.points >= 200:
            return 'نقره‌ای 🥈'
        else:
            return 'برنزی 🥉'
    
    def get_next_level_points(self):
        """امتیاز مورد نیاز برای سطح بعدی"""
        if self.points < 200:
            return 200 - self.points
        elif self.points < 500:
            return 500 - self.points
        elif self.points < 1000:
            return 1000 - self.points
        return 0

# ============================================
# مدل خبرنامه
# ============================================
class Newsletter(db.Model):
    __tablename__ = 'newsletters'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(120), unique=True, nullable=False)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

# ============================================
# مدل پیام‌های تماس
# ============================================
class ContactMessage(db.Model):
    __tablename__ = 'contact_messages'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(120), nullable=False)
    phone = db.Column(db.String(20))
    subject = db.Column(db.String(200))
    message = db.Column(db.Text, nullable=False)
    is_read = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

# ============================================
# مدل بازدیدهای سایت (آمار)
# ============================================
class Visit(db.Model):
    __tablename__ = 'visits'
    id = db.Column(db.Integer, primary_key=True)
    ip = db.Column(db.String(45))
    user_agent = db.Column(db.String(300))
    page = db.Column(db.String(200))
    referer = db.Column(db.String(300))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
# 5.10 مدل سفارشات
class Order(db.Model):
    __tablename__ = 'orders'
    id = db.Column(db.Integer, primary_key=True)
    order_number = db.Column(db.String(50), unique=True, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    full_name = db.Column(db.String(150), nullable=False)
    phone = db.Column(db.String(20), nullable=False)
    address = db.Column(db.Text, nullable=False)
    city = db.Column(db.String(50))
    postal_code = db.Column(db.String(20))
    shipping_method = db.Column(db.String(50))
    shipping_cost = db.Column(db.Integer, default=0)
    total_amount = db.Column(db.Integer, nullable=False)
    discount_amount = db.Column(db.Integer, default=0)
    final_amount = db.Column(db.Integer, nullable=False)
    payment_method = db.Column(db.String(50))
    payment_status = db.Column(db.String(20), default='pending')
    order_status = db.Column(db.String(20), default='pending')
    tracking_code = db.Column(db.String(50))
    note = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # روابط
    items = db.relationship('OrderItem', backref='order', lazy=True, cascade='all, delete-orphan')

# 5.11 مدل جزئیات سفارش
class OrderItem(db.Model):
    __tablename__ = 'order_items'
    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('orders.id'), nullable=False)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    product_title = db.Column(db.String(200), nullable=False)
    quantity = db.Column(db.Integer, nullable=False)
    price = db.Column(db.Integer, nullable=False)
    total = db.Column(db.Integer, nullable=False)

# 5.12 مدل تخفیف‌ها
class Discount(db.Model):
    __tablename__ = 'discounts'
    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'))
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    discount_percent = db.Column(db.Integer)
    discount_price = db.Column(db.Integer)
    start_date = db.Column(db.DateTime)
    end_date = db.Column(db.DateTime)
    is_active = db.Column(db.Boolean, default=True)

# 5.13 مدل کد تخفیف
class Coupon(db.Model):
    __tablename__ = 'coupons'
    id = db.Column(db.Integer, primary_key=True)
    code = db.Column(db.String(50), unique=True, nullable=False)
    discount_type = db.Column(db.String(20), default='percent')  # percent / fixed
    discount_value = db.Column(db.Integer, nullable=False)
    min_order_amount = db.Column(db.Integer, default=0)
    max_discount = db.Column(db.Integer)
    usage_limit = db.Column(db.Integer)
    used_count = db.Column(db.Integer, default=0)
    start_date = db.Column(db.DateTime)
    end_date = db.Column(db.DateTime)
    is_active = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)  # ← اضافه شد
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)  # ← اضافه شد
    
# 5.14 مدل روش ارسال
class ShippingMethod(db.Model):
    __tablename__ = 'shipping_methods'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text)
    base_cost = db.Column(db.Integer, default=0)
    cost_per_kg = db.Column(db.Integer, default=0)
    free_shipping_threshold = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)

# 5.15 مدل بنرها
class Banner(db.Model):
    __tablename__ = 'banners'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100))
    image = db.Column(db.String(200), nullable=False)
    link = db.Column(db.String(300))
    position = db.Column(db.String(50), default='home_top')
    order = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)
    start_date = db.Column(db.DateTime)
    end_date = db.Column(db.DateTime)

# 5.16 مدل نظرات
class Review(db.Model):
    __tablename__ = 'reviews'
    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    rating = db.Column(db.Integer, nullable=False)
    comment = db.Column(db.Text)
    is_approved = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

# 5.17 مدل علاقه‌مندی‌ها
class Wishlist(db.Model):
    __tablename__ = 'wishlist'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

# 5.18 مدل بک‌آپ
class Backup(db.Model):
    __tablename__ = 'backups'
    id = db.Column(db.Integer, primary_key=True)
    file_name = db.Column(db.String(200), nullable=False)
    file_size = db.Column(db.Integer)
    file_path = db.Column(db.String(300), nullable=False)
    backup_type = db.Column(db.String(20), default='full')
    description = db.Column(db.String(200))
    created_by = db.Column(db.Integer, db.ForeignKey('users.id'))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

# 5.19 مدل تنظیمات سایت

class Setting(db.Model):
    __tablename__ = 'settings'
    id = db.Column(db.Integer, primary_key=True)
    site_name = db.Column(db.String(100), default='فروشگاه تجهیزات صنعتی')
    site_logo = db.Column(db.String(200))
    site_favicon = db.Column(db.String(200))
    site_email = db.Column(db.String(100))
    site_phone = db.Column(db.String(20))
    site_address = db.Column(db.Text)
    footer_text = db.Column(db.Text)
    social_media = db.Column(db.Text)  # JSON
    currency = db.Column(db.String(10), default='تومان')
    tax_percent = db.Column(db.Integer, default=0)
    maintenance_mode = db.Column(db.Boolean, default=False)
    meta_title = db.Column(db.String(150))
    meta_description = db.Column(db.String(300))
    seo_keywords = db.Column(db.Text)
    payment_config = db.Column(db.Text)  # ← اضافه شد - تنظیمات درگاه پرداخت
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# ============================================
# 6. توابع کمکی
# ============================================

# 6.1 تبدیل اعداد به فارسی
def to_persian_numbers(number):
    """تبدیل اعداد انگلیسی به فارسی"""
    persian_map = {
        '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
        '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
    }
    return ''.join(persian_map.get(char, char) for char in str(number))

# 6.2 تبدیل تاریخ میلادی به شمسی
def to_jalali_date(date):
    """تبدیل تاریخ میلادی به شمسی"""
    if not date:
        return ''
    try:
        if isinstance(date, str):
            date = datetime.fromisoformat(date)
        jalali = jdatetime.datetime.fromgregorian(datetime=date)
        return f"{jalali.year}/{jalali.month:02d}/{jalali.day:02d}"
    except:
        return str(date)
# ============================================================
# 📌 context_processor - متغیرهای سراسری برای همه تمپلیت‌ها
# ============================================================
@app.context_processor
def inject_global_variables():
    """متغیرهایی که در تمام صفحات در دسترس هستند"""
    from datetime import datetime
    import json
    
    # ===== ۱. تنظیمات سایت =====
    setting = Setting.query.first()
    if not setting:
        setting = Setting(
            site_name='بازار آنلاین ۷۲۴',  # ✅ اصلاح شد
            site_email='info@onlinemarket724.ir',  # ✅ اصلاح شد
            site_phone='۰۲۱-۱۲۳۴۵۶۷۸',
            site_address='تهران، خیابان صنعت، پلاک ۱۲',
            currency='تومان',
            meta_title='بازار آنلاین ۷۲۴ | مرجع تخصصی تجهیزات صنعتی',  # ✅ اصلاح شد
            meta_description='خرید انواع تجهیزات صنعتی با بهترین قیمت و کیفیت از بازار آنلاین ۷۲۴'  # ✅ اصلاح شد
        )
    
    # ===== ۲. دسته‌بندی‌ها (برای منو) =====
    categories = Category.query.filter_by(parent_id=None).order_by(Category.order).all()
    
    # ===== ۳. برندها =====
    brands = Brand.query.filter_by(is_active=True).all()
    
    # ===== ۴. تعداد سبد خرید =====
    cart_count = 0
    if 'user_id' in session:
        cart_count = Cart.query.filter_by(user_id=session['user_id']).count()
    elif session.get('session_id'):
        cart_count = Cart.query.filter_by(session_id=session['session_id']).count()
    
    # ===== ۵. کد تخفیف فعال =====
    now = datetime.utcnow()
    active_coupon = Coupon.query.filter(
        Coupon.is_active == True,
        Coupon.start_date <= now,
        Coupon.end_date >= now,
        db.or_(
            Coupon.usage_limit == None,
            Coupon.used_count < Coupon.usage_limit
        )
    ).first()
    
    # ===== ۶. کاربر فعلی =====
    current_user = None
    if 'user_id' in session:
        current_user = User.query.get(session['user_id'])
    
    # ===== ۷. امتیازات کاربر =====
    user_rewards = None
    if current_user and hasattr(db, 'Reward'):
        user_rewards = Reward.query.filter_by(user_id=current_user.id).first()
    
    # ===== ۸. روش‌های ارسال =====
    shipping_methods = ShippingMethod.query.filter_by(is_active=True).all()
    
    # ===== ۹. صفحات سئو =====
    seo_pages = SeoPage.query.order_by(SeoPage.created_at.desc()).limit(6).all()
    
    # ===== ۱۰. شبکه‌های اجتماعی از تنظیمات =====
    social_media = {}
    if setting and setting.social_media:
        try:
            social_media = json.loads(setting.social_media)
        except:
            social_media = {
                'instagram': 'https://instagram.com/onlinemarket724',  # ✅ اصلاح شد
                'telegram': 'https://t.me/onlinemarket724',  # ✅ اصلاح شد
                'whatsapp': 'https://wa.me/989123456789',
                'linkedin': 'https://linkedin.com/company/onlinemarket724',  # ✅ اصلاح شد
                'aparat': 'https://aparat.com/onlinemarket724'  # ✅ اصلاح شد
            }
    
    # ===== ۱۱. تاریخ فعلی =====
    current_time = datetime.utcnow()
    
    # ===== ۱۲. آمار کلی =====
    total_products = Product.query.filter_by(is_active=True).count()
    total_orders = Order.query.count()
    total_users = User.query.count()
    total_rewards = Reward.query.count() if hasattr(db, 'Reward') else 0
    
    # ===== ۱۳. تنظیمات امنیتی =====
    csrf_token = session.get('csrf_token', '')
    
    # ===== برگرداندن همه متغیرها =====
    return {
        # تنظیمات
        'setting': setting,
        'site_name': setting.site_name if setting else 'بازار آنلاین ۷۲۴',  # ✅ اصلاح شد
        'site_email': setting.site_email if setting else 'info@onlinemarket724.ir',  # ✅ اصلاح شد
        'site_phone': setting.site_phone if setting else '۰۲۱-۱۲۳۴۵۶۷۸',
        'site_address': setting.site_address if setting else 'تهران، خیابان صنعت، پلاک ۱۲',
        'currency': setting.currency if setting else 'تومان',
        
        # دیتابیس
        'categories': categories,
        'brands': brands,
        'cart_count': cart_count,
        'active_coupon': active_coupon,
        'current_user': current_user,
        'user_rewards': user_rewards,
        'shipping_methods': shipping_methods,
        'seo_pages': seo_pages,
        'social_media': social_media,
        
        # آمار
        'total_products': total_products,
        'total_orders': total_orders,
        'total_users': total_users,
        'total_rewards': total_rewards,
        
        # متفرقه
        'current_time': current_time,
        'csrf_token': csrf_token,
        'now': current_time,
        
        # وضعیت لاگین
        'is_logged_in': 'user_id' in session,
        'is_admin': session.get('role') == 'admin' if 'user_id' in session else False,
        'username': session.get('username', ''),
        'user_full_name': session.get('full_name', ''),
    }

# 6.3 تولید اسلاگ

# ============================================================
# تبدیل فارسی به فینگلیش - جایگزین تابع قبلی
# ============================================================
# ============================================================
# تبدیل فارسی به فینگلیش - کامل و نهایی
# ============================================================
# ============================================================
# تابع تولید اسلاگ فینگلیش - با همون اسم قبلی
# ============================================================
# ============================================================
# تابع تولید اسلاگ فینگلیش - مادر همه
# ============================================================
# ============================================================
# تولید اسلاگ فینگلیش - نهایی و بدون نیاز به اصلاح
# ============================================================
# ============================================================
# تابع تولید اسلاگ فینگلیش - نهایی
# ============================================================
import re

def generate_slug(text, model=None):
    """تولید اسلاگ فینگلیش از متن - با قابلیت بررسی یکتا بودن"""
    if not text:
        return 'unknown'
    
    # دیکشنری کامل تبدیل فارسی به انگلیسی
    d = {
        'آ': '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',
        ' ': '-', '_': '-', '،': '', '؟': '',
        '!': '', '?': '', '.': '', ',': '',
        ';': '', ':': '', '"': '', "'": '',
        '(': '', ')': '', '[': '', ']': '',
        '{': '', '}': '', '<': '', '>': '',
        '/': '', '\\': '', '|': '', '&': '',
        '*': '', '%': '', '$': '', '#': '',
        '@': '', '^': '', '+': '', '=': '',
        '~': '', '`': '', '…': ''
    }
    
    # تبدیل به فینگلیش
    text = text.lower().strip()
    out = ''
    for ch in text:
        out += d.get(ch, ch if ch.isalnum() else '-')
    
    out = re.sub(r'-+', '-', out)
    base_slug = out.strip('-') or 'unknown'
    
    # اگر مدل داده نشده، بدون بررسی یکتا برمی‌گردونیم
    if not model:
        return base_slug
    
    # بررسی یکتا بودن
    slug = base_slug
    counter = 1
    while model.query.filter_by(slug=slug).first():
        slug = f"{base_slug}-{counter}"
        counter += 1
    
    return slug
# 6.4 آپلود عکس

def upload_image(file, folder='products'):
    if not file:
        return None
    
    from werkzeug.utils import secure_filename
    import secrets
    import os
    
    upload_dir = os.path.join('static', 'uploads', folder)
    os.makedirs(upload_dir, exist_ok=True)
    
    filename = secure_filename(file.filename)
    name, ext = os.path.splitext(filename)
    unique_name = f"{name}_{secrets.token_hex(8)}{ext}"
    
    filepath = os.path.join(upload_dir, unique_name)
    file.save(filepath)
    
    return f'/static/uploads/{folder}/{unique_name}'
    
# 6.5 تابع احراز هویت ادمین
def admin_required(f):
    """دکوراتور برای محدودیت دسترسی ادمین"""
    @wraps(f)
    def decorated_function(*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_function

# 6.6 تولید sitemap.xml
def generate_sitemap():
    """تولید فایل sitemap.xml"""
    # اطمینان از وجود پوشه static
    if not os.path.exists('static'):
        os.makedirs('static')
    
    base_url = request.host_url.rstrip('/')
    sitemap = '<?xml version="1.0" encoding="UTF-8"?>\n'
    sitemap += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
    
    # صفحات اصلی
    pages = ['/', '/products', '/about', '/contact', '/coupons']
    for page in pages:
        sitemap += f'<url>\n<loc>{base_url}{page}</loc>\n'
        sitemap += f'<lastmod>{datetime.utcnow().date()}</lastmod>\n'
        sitemap += '<changefreq>weekly</changefreq>\n<priority>0.8</priority>\n</url>\n'
    
    # محصولات
    products = Product.query.filter_by(is_active=True).all()
    for product in products:
        sitemap += f'<url>\n<loc>{base_url}/product/{product.slug}</loc>\n'
        sitemap += f'<lastmod>{product.updated_at.date() if product.updated_at else datetime.utcnow().date()}</lastmod>\n'
        sitemap += '<changefreq>daily</changefreq>\n<priority>0.9</priority>\n</url>\n'
    
    # صفحات سئو
    seo_pages = SeoPage.query.all()
    for page in seo_pages:
        sitemap += f'<url>\n<loc>{base_url}/seo/{page.slug}</loc>\n'
        sitemap += f'<lastmod>{page.updated_at.date() if page.updated_at else datetime.utcnow().date()}</lastmod>\n'
        sitemap += '<changefreq>weekly</changefreq>\n<priority>0.7</priority>\n</url>\n'
    
    # دسته‌بندی‌ها
    categories = Category.query.all()
    for category in categories:
        sitemap += f'<url>\n<loc>{base_url}/category/{category.slug}</loc>\n'
        sitemap += f'<lastmod>{category.created_at.date() if category.created_at else datetime.utcnow().date()}</lastmod>\n'
        sitemap += '<changefreq>weekly</changefreq>\n<priority>0.6</priority>\n</url>\n'
    
    sitemap += '</urlset>'
    
    # ذخیره در فایل
    with open('static/sitemap.xml', 'w', encoding='utf-8') as f:
        f.write(sitemap)
    
    return True

@app.route('/robots.txt')
def robots():
    return """User-agent: *
Allow: /
Disallow: /admin/
Disallow: /cart/
Disallow: /checkout/
Sitemap: {}/sitemap.xml
""".format(request.url_root)

# 6.7 تولید فید برای ترب و باسلام

def generate_torob_feed():
    """تولید فید XML برای ترب و باسلام"""
    # اطمینان از وجود پوشه static
    if not os.path.exists('static'):
        os.makedirs('static')
    
    products = Product.query.filter_by(is_active=True).all()
    
    feed = '<?xml version="1.0" encoding="UTF-8"?>\n'
    feed += '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">\n'
    feed += '<channel>\n'
    feed += '<title>فروشگاه تجهیزات صنعتی</title>\n'
    feed += '<link>' + request.host_url + '</link>\n'
    feed += '<description>لیست محصولات فروشگاه</description>\n'
    
    for product in products:
        feed += '<item>\n'
        feed += f'<g:id>{product.id}</g:id>\n'
        feed += f'<title>{product.title}</title>\n'
        feed += f'<description>{product.short_description or product.description[:200]}</description>\n'
        
        # تصویر اصلی
        main_image = ProductImage.query.filter_by(product_id=product.id, is_main=True).first()
        if main_image:
            feed += f'<g:image_link>{request.host_url.rstrip("/")}{main_image.image_url}</g:image_link>\n'
        
        feed += f'<g:price>{product.get_final_price()}</g:price>\n'
        feed += f'<g:currency>IRR</g:currency>\n'
        feed += f'<g:availability>{"in_stock" if product.is_in_stock() else "out_of_stock"}</g:availability>\n'
        feed += f'<g:brand>{product.brand.name if product.brand else ""}</g:brand>\n'
        
        if product.category:
            feed += f'<g:category>{product.category.name}</g:category>\n'
        
        feed += f'<link>{request.host_url.rstrip("/")}/product/{product.slug}</link>\n'
        feed += '</item>\n'
    
    feed += '</channel>\n</rss>'
    
    # ذخیره در فایل
    with open('static/torob_feed.xml', 'w', encoding='utf-8') as f:
        f.write(feed)
    
    return True
# 6.8 بک‌آپ‌گیری
def create_backup(backup_type='full', description=''):
    """ایجاد بک‌آپ از دیتابیس و فایل‌ها"""
    timestamp = datetime.utcnow().strftime('%Y%m%d_%H%M%S')
    backup_dir = 'backups'
    if not os.path.exists(backup_dir):
        os.makedirs(backup_dir)
    
    backup_data = {
        'type': backup_type,
        'created_at': datetime.utcnow().isoformat(),
        'tables': {}
    }
    
    # بک‌آپ دیتابیس (به صورت JSON)
    if backup_type in ['full', 'database']:
        tables = {
            'users': User,
            'categories': Category,
            'brands': Brand,
            'products': Product,
            'product_images': ProductImage,
            'product_specs': ProductSpec,
            'keywords': Keyword,
            'seo_pages': SeoPage,
            'orders': Order,
            'order_items': OrderItem,
            'carts': Cart,
            'discounts': Discount,
            'coupons': Coupon,
            'shipping_methods': ShippingMethod,
            'banners': Banner,
            'reviews': Review,
            'wishlist': Wishlist,
            'settings': Setting
        }
        
        for table_name, model in tables.items():
            try:
                records = model.query.all()
                table_data = []
                for record in records:
                    # تبدیل به دیکشنری
                    record_dict = {}
                    for column in record.__table__.columns:
                        value = getattr(record, column.name)
                        if isinstance(value, datetime):
                            value = value.isoformat()
                        record_dict[column.name] = value
                    table_data.append(record_dict)
                backup_data['tables'][table_name] = table_data
            except Exception as e:
                app.logger.error(f"Error backing up {table_name}: {str(e)}")
    
    # ذخیره فایل JSON
    file_name = f"backup_{timestamp}_{backup_type}.json"
    file_path = os.path.join(backup_dir, file_name)
    
    with open(file_path, 'w', encoding='utf-8') as f:
        json.dump(backup_data, f, ensure_ascii=False, indent=2)
    
    # ذخیره در دیتابیس
    backup_record = Backup(
        file_name=file_name,
        file_size=os.path.getsize(file_path) // 1024,  # KB
        file_path=file_path,
        backup_type=backup_type,
        description=description,
        created_by=session.get('user_id', 1)
    )
    db.session.add(backup_record)
    db.session.commit()
    
    # تنظیم بک‌آپ خودکار
    schedule_auto_backup()
    
    return file_name

# 6.9 بازیابی از بک‌آپ
def restore_backup(file_path):
    """بازیابی دیتابیس از فایل بک‌آپ - با حفظ جدول backups"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            backup_data = json.load(f)
        
        if 'tables' not in backup_data:
            return False, "فایل بک‌آپ معتبر نیست"
        
        # ===== گرفتن بک‌آپ‌های فعلی قبل از حذف =====
        current_backups = []
        try:
            current_backups = Backup.query.all()
            # ذخیره موقت داده‌های بک‌آپ‌ها
            backups_data = []
            for b in current_backups:
                backups_data.append({
                    'id': b.id,
                    'file_name': b.file_name,
                    'file_size': b.file_size,
                    'file_path': b.file_path,
                    'backup_type': b.backup_type,
                    'description': b.description,
                    'created_by': b.created_by,
                    'created_at': b.created_at
                })
        except:
            backups_data = []
        
        # ===== حذف داده‌های قبلی (به جز جدول backups) =====
        for table in reversed(db.metadata.sorted_tables):
            # جدول backups رو حذف نکن
            if table.name == 'backups':
                continue
            try:
                db.session.execute(table.delete())
            except:
                pass
        db.session.commit()
        
        # ===== بازیابی داده‌ها (به جز جدول backups) =====
        for table_name, records in backup_data['tables'].items():
            if not records:
                continue
            
            # از بازیابی جدول backups صرف‌نظر کن
            if table_name == 'backups':
                continue
            
            model_map = {
                'users': User, 'categories': Category, 'brands': Brand,
                'products': Product, 'product_images': ProductImage,
                'product_specs': ProductSpec, 'keywords': Keyword,
                'seo_pages': SeoPage, 'orders': Order, 'order_items': OrderItem,
                'carts': Cart, 'discounts': Discount, 'coupons': Coupon,
                'shipping_methods': ShippingMethod, 'banners': Banner,
                'reviews': Review, 'wishlist': Wishlist, 'settings': Setting,
                'rewards': Reward, 'newsletters': Newsletter,
                'contact_messages': ContactMessage, 'visits': Visit
            }
            
            model = model_map.get(table_name)
            if not model:
                continue
            
            for record_data in records:
                # حذف تاریخ‌ها
                clean_data = {}
                for key, value in record_data.items():
                    if key not in ['created_at', 'updated_at', 'last_login', 'start_date', 
                                   'end_date', 'discount_start', 'discount_end']:
                        clean_data[key] = value
                
                # درست کردن payment_config
                if table_name == 'settings' and 'payment_config' in clean_data:
                    if clean_data['payment_config'] is None:
                        clean_data['payment_config'] = '{}'
                
                new_record = model(**clean_data)
                db.session.add(new_record)
        
        # ===== برگردوندن بک‌آپ‌های قبلی =====
        for b_data in backups_data:
            # بررسی اینکه قبلاً وجود نداره
            existing = Backup.query.filter_by(file_name=b_data['file_name']).first()
            if not existing:
                backup = Backup(
                    file_name=b_data['file_name'],
                    file_size=b_data['file_size'],
                    file_path=b_data['file_path'],
                    backup_type=b_data.get('backup_type', 'full'),
                    description=b_data.get('description', ''),
                    created_by=b_data.get('created_by', 1),
                    created_at=b_data.get('created_at', datetime.utcnow())
                )
                db.session.add(backup)
        
        db.session.commit()
        return True, "✅ بازیابی با موفقیت انجام شد (جدول بک‌آپ حفظ شد)"
    
    except Exception as e:
        db.session.rollback()
        app.logger.error(f"Restore error: {str(e)}")
        return False, f"❌ خطا: {str(e)}"

# 6.10 بک‌آپ خودکار
def schedule_auto_backup():
    """تنظیم بک‌آپ خودکار هر 24 ساعت"""
    scheduler = BackgroundScheduler()
    scheduler.add_job(
        func=lambda: create_backup('full', 'بک‌آپ خودکار'),
        trigger='interval',
        hours=24
    )
    scheduler.start()
    return scheduler

# 6.11 ارسال ایمیل
def send_email(to, subject, body):
    """ارسال ایمیل"""
    try:
        msg = Message(subject, recipients=[to])
        msg.body = body
        msg.html = body
        mail.send(msg)
        return True
    except Exception as e:
        app.logger.error(f"Email error: {str(e)}")
        return False

# 6.12 محاسبه هزینه ارسال
def calculate_shipping(product_id, quantity, city='tehran'):
    """محاسبه هزینه ارسال بر اساس محصول و شهر"""
    product = Product.query.get(product_id)
    if not product:
        return 0
    
    # اگر ارسال رایگان است
    if product.free_shipping:
        return 0
    
    # هزینه پایه
    shipping_cost = product.shipping_cost or 0
    
    # هزینه بر اساس وزن
    if product.weight:
        shipping_method = ShippingMethod.query.filter_by(is_active=True).first()
        if shipping_method:
            shipping_cost += shipping_method.base_cost
            shipping_cost += int(product.weight * shipping_method.cost_per_kg)
    
    return shipping_cost

# 6.13 تابع تولید شماره سفارش
def generate_order_number():
    """تولید شماره سفارش یکتا"""
    timestamp = datetime.utcnow().strftime('%Y%m%d%H%M%S')
    random_part = secrets.token_hex(4).upper()
    return f"ORD-{timestamp}-{random_part}"
    
# ============================================
# 7. دکوراتورها و فیلترهای سفارشی
# ============================================

# 7.1 فیلترهای Jinja2 برای نمایش اعداد فارسی و تاریخ شمسی
# ============================================================
# فیلترهای Jinja2 برای اعداد فارسی و تاریخ شمسی
# ============================================================

@app.template_filter('persian_number')
def persian_number_filter(number):
    """تبدیل اعداد انگلیسی به فارسی با جداکننده هزارگان"""
    if number is None:
        return '۰'
    try:
        # تبدیل به عدد صحیح
        num = int(number)
        # جداکننده هزارگان با کاما فارسی
        formatted = f"{num:,}".replace(',', '٬')
        # تبدیل هر رقم به فارسی
        persian_map = {
            '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
            '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
        }
        return ''.join(persian_map.get(char, char) for char in formatted)
    except:
        return str(number)

@app.template_filter('persian_number_simple')
def persian_number_simple_filter(number):
    """تبدیل اعداد انگلیسی به فارسی (بدون جداکننده)"""
    if number is None:
        return '۰'
    persian_map = {
        '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
        '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
    }
    return ''.join(persian_map.get(char, char) for char in str(number))


# ============================================================
# فیلترهای Jinja2 برای تاریخ شمسی و زمان
# ============================================================

@app.template_filter('jalali_date')
def jalali_date_filter(date):
    """تبدیل تاریخ میلادی به شمسی (سال/ماه/روز)"""
    if not date:
        return ''
    try:
        if isinstance(date, str):
            date = datetime.fromisoformat(date)
        jalali = jdatetime.datetime.fromgregorian(datetime=date)
        return f"{jalali.year}/{jalali.month:02d}/{jalali.day:02d}"
    except:
        return str(date)


@app.template_filter('jalali_time')
def jalali_time_filter(date):
    """تبدیل تاریخ به ساعت شمسی"""
    if not date:
        return ''
    try:
        if isinstance(date, str):
            date = datetime.fromisoformat(date)
        jalali = jdatetime.datetime.fromgregorian(datetime=date)
        return f"{jalali.hour:02d}:{jalali.minute:02d}"
    except:
        return str(date)


@app.template_filter('jalali_date_full')
def jalali_date_full_filter(date):
    """تبدیل تاریخ میلادی به شمسی با نام روز و ماه (کامل)"""
    if not date:
        return ''
    try:
        if isinstance(date, str):
            date = datetime.fromisoformat(date)
        jalali = jdatetime.datetime.fromgregorian(datetime=date)
        
        month_names = {
            1: 'فروردین', 2: 'اردیبهشت', 3: 'خرداد',
            4: 'تیر', 5: 'مرداد', 6: 'شهریور',
            7: 'مهر', 8: 'آبان', 9: 'آذر',
            10: 'دی', 11: 'بهمن', 12: 'اسفند'
        }
        
        weekday_names = {
            0: 'دوشنبه', 1: 'سه‌شنبه', 2: 'چهارشنبه',
            3: 'پنجشنبه', 4: 'جمعه', 5: 'شنبه', 6: 'یکشنبه'
        }
        
        weekday = weekday_names.get(jalali.weekday(), '')
        month = month_names.get(jalali.month, '')
        
        return f"{weekday} {jalali.day} {month} {jalali.year}"
    except:
        return str(date)


@app.template_filter('jalali_date_simple')
def jalali_date_simple_filter(date):
    """تبدیل تاریخ میلادی به شمسی ساده (بدون نام روز)"""
    if not date:
        return ''
    try:
        if isinstance(date, str):
            date = datetime.fromisoformat(date)
        jalali = jdatetime.datetime.fromgregorian(datetime=date)
        
        month_names = {
            1: 'فروردین', 2: 'اردیبهشت', 3: 'خرداد',
            4: 'تیر', 5: 'مرداد', 6: 'شهریور',
            7: 'مهر', 8: 'آبان', 9: 'آذر',
            10: 'دی', 11: 'بهمن', 12: 'اسفند'
        }
        
        month = month_names.get(jalali.month, '')
        return f"{jalali.day} {month} {jalali.year}"
    except:
        return str(date)

@app.template_filter('persian_price')
def persian_price_filter(price):
    """نمایش قیمت به صورت فارسی با جداکننده هزارگان و واحد تومان"""
    if not price:
        return '۰'
    try:
        num = int(price)
        formatted = f"{num:,}".replace(',', '٬')
        persian_map = {
            '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
            '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
        }
        return ''.join(persian_map.get(char, char) for char in formatted)
    except:
        return str(price)

@app.template_filter('persian_price_with_unit')
def persian_price_with_unit_filter(price):
    """نمایش قیمت با واحد تومان به صورت فارسی"""
    if not price:
        return '۰ تومان'
    try:
        num = int(price)
        formatted = f"{num:,}".replace(',', '٬')
        persian_map = {
            '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
            '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
        }
        result = ''.join(persian_map.get(char, char) for char in formatted)
        return f"{result} تومان"
    except:
        return f"{price} تومان"
        




# 7.2 دکوراتور برای کاربران لاگین شده
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            flash('لطفاً ابتدا وارد شوید', 'warning')
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated_function

# 7.3 دکوراتور برای جلوگیری از CSRF (غیرفعال - مطابق درخواست شما)

# ============================================
# 8. روت‌های عمومی
# ============================================
# ============================================
# روت صفحه اصلی - کاملترین نسخه
# ============================================
# ============================================
# روت ثبت‌نام در خبرنامه
# ============================================
@app.route('/api/newsletter/subscribe', methods=['POST'])
def subscribe_newsletter():
    """ثبت ایمیل در خبرنامه"""
    try:
        data = request.get_json()
        email = data.get('email')
        
        if not email or '@' not in email:
            return jsonify({
                'status': 'error',
                'message': 'لطفاً ایمیل معتبر وارد کنید'
            }), 400
        
        # بررسی تکراری نبودن
        existing = Newsletter.query.filter_by(email=email).first()
        if existing:
            if existing.is_active:
                return jsonify({
                    'status': 'error',
                    'message': 'این ایمیل قبلاً در خبرنامه ثبت شده است'
                }), 400
            else:
                # فعال کردن مجدد
                existing.is_active = True
                existing.created_at = datetime.utcnow()
                db.session.commit()
                return jsonify({
                    'status': 'success',
                    'message': 'ایمیل شما مجدداً در خبرنامه فعال شد'
                })
        
        # ایجاد جدید
        newsletter = Newsletter(
            email=email,
            is_active=True,
            created_at=datetime.utcnow()
        )
        db.session.add(newsletter)
        db.session.commit()
        
        # ارسال ایمیل خوش‌آمدگویی
        try:
            setting = Setting.query.first()
            send_email(
                email,
                'ثبت‌نام در خبرنامه سام‌صنعت',
                f"""
                <h2>به خبرنامه {setting.site_name or 'سام‌صنعت'} خوش آمدید</h2>
                <p>شما با موفقیت در خبرنامه ما ثبت نام کردید.</p>
                <p>همیشه با آخرین تخفیف‌ها و محصولات جدید آشنا خواهید شد.</p>
                """
            )
        except:
            pass
        
        return jsonify({
            'status': 'success',
            'message': 'ایمیل شما با موفقیت در خبرنامه ثبت شد'
        })
        
    except Exception as e:
        app.logger.error(f"Newsletter error: {str(e)}")
        return jsonify({
            'status': 'error',
            'message': 'خطا در ثبت‌نام خبرنامه'
        }), 500
        
@app.route('/')
def index():
    setting = Setting.query.first()
    if not setting:
        setting = Setting(
            site_name='صنعت استور',
            site_email='info@sanatstore.com',
            site_phone='۰۲۱-۱۲۳۴۵۶۷۸',
            site_address='تهران، خیابان صنعت، پلاک ۱۲',
            currency='تومان',
            meta_title='صنعت استور | فروشگاه تخصصی تجهیزات صنعتی',
            meta_description='خرید بهترین تجهیزات صنعتی با قیمت مناسب و کیفیت عالی از صنعت استور',
            seo_keywords='تجهیزات صنعتی, صنعت استور, قطعات صنعتی, ابزارآلات, ماشین‌آلات'
        )
        db.session.add(setting)
        db.session.commit()
    
    now = datetime.utcnow()
    
    return render_template('index.html',
        setting=setting,
        total_products=Product.query.filter_by(is_active=True).count(),
        total_orders=Order.query.count(),
        total_users=User.query.count(),
        total_rewards=Reward.query.count() if hasattr(db, 'Reward') else 0,
        featured_products=Product.query.filter_by(is_featured=True, is_active=True).order_by(Product.created_at.desc()).limit(12).all(),
        new_products=Product.query.filter_by(is_new=True, is_active=True).order_by(Product.created_at.desc()).limit(12).all(),
        discounted_products=Product.query.filter(Product.discount_percent > 0, Product.is_active == True).order_by(Product.discount_percent.desc()).limit(12).all(),
        best_sellers=Product.query.filter_by(is_active=True).order_by(Product.sold_count.desc()).limit(8).all(),
        categories=Category.query.filter_by(parent_id=None).order_by(Category.order).all(),
        brands=Brand.query.filter_by(is_active=True).all(),
        banners=Banner.query.filter(Banner.is_active == True, db.or_(Banner.start_date <= now, Banner.start_date == None), db.or_(Banner.end_date >= now, Banner.end_date == None)).order_by(Banner.order).all(),
        active_coupon=Coupon.query.filter(Coupon.is_active == True, Coupon.start_date <= now, Coupon.end_date >= now, db.or_(Coupon.usage_limit == None, Coupon.used_count < Coupon.usage_limit)).first(),
        seo_pages=SeoPage.query.order_by(SeoPage.created_at.desc()).limit(6).all(),
        latest_reviews=Review.query.filter_by(is_approved=True).order_by(Review.created_at.desc()).limit(5).all(),
        cart_count=Cart.query.filter_by(user_id=session.get('user_id')).count() if session.get('user_id') else 0
    )
    
# 8.2 لیست محصولات با فیلتر
@app.route('/products')
def products():
    """لیست محصولات با فیلتر و مرتب‌سازی"""
    page = request.args.get('page', 1, type=int)
    per_page = 20
    
    # ===== دریافت فیلترها =====
    category_id = request.args.get('category', type=int)
    brand_id = request.args.get('brand', type=int)
    min_price = request.args.get('min_price', type=int)
    max_price = request.args.get('max_price', type=int)
    sort = request.args.get('sort', 'newest')
    search = request.args.get('q', '').strip()
    
    # ===== ساخت کوئری =====
    query = Product.query.filter_by(is_active=True)
    
    # فیلتر دسته‌بندی
    if category_id:
        query = query.filter_by(category_id=category_id)
    
    # فیلتر برند
    if brand_id:
        query = query.filter_by(brand_id=brand_id)
    
    # فیلتر قیمت
    if min_price:
        query = query.filter(Product.price >= min_price)
    if max_price:
        query = query.filter(Product.price <= max_price)
    
    # فیلتر جستجو
    if search:
        query = query.filter(
            db.or_(
                Product.title.contains(search),
                Product.description.contains(search),
                Product.short_description.contains(search)
            )
        )
    
    # ===== مرتب‌سازی =====
    if sort == 'newest':
        query = query.order_by(Product.created_at.desc())
    elif sort == 'price_low':
        query = query.order_by(Product.price.asc())
    elif sort == 'price_high':
        query = query.order_by(Product.price.desc())
    elif sort == 'popular':
        query = query.order_by(Product.sold_count.desc())
    elif sort == 'discount':
        query = query.filter(Product.discount_percent > 0).order_by(Product.discount_percent.desc())
    else:
        query = query.order_by(Product.created_at.desc())
    
    # ===== صفحه‌بندی =====
    products = query.paginate(page=page, per_page=per_page)
    
    # context_processor already provides categories and brands
    return render_template('products.html',
        products=products,
        sort=sort
    )

@app.route('/product/<slug>')
def product_detail(slug):
    product = Product.query.filter_by(slug=slug, is_active=True).first_or_404()
    
    # افزایش بازدید
    product.views += 1
    db.session.commit()
    
    # تصاویر
    images = ProductImage.query.filter_by(product_id=product.id).order_by(ProductImage.order).all()
    
    # مشخصات فنی
    specs = ProductSpec.query.filter_by(product_id=product.id).all()
    
    # نظرات تایید شده
    reviews = Review.query.filter_by(product_id=product.id, is_approved=True).order_by(Review.created_at.desc()).all()
    
    # محصولات مرتبط
    related_products = Product.query.filter(
        Product.category_id == product.category_id,
        Product.id != product.id,
        Product.is_active == True
    ).limit(6).all()
    
    return render_template('product_detail.html',
        product=product,
        images=images,
        specs=specs,
        reviews=reviews,
        related_products=related_products
    )
# 8.4 صفحات سئو شده
@app.route('/seo/<slug>')
def seo_page(slug):
    seo_page = SeoPage.query.filter_by(slug=slug).first_or_404()
    
    # افزایش بازدید
    seo_page.views += 1
    db.session.commit()
    
    # دریافت محصولات مرتبط
    product_ids = seo_page.product_ids.split(',') if seo_page.product_ids else []
    products = Product.query.filter(Product.id.in_(product_ids), Product.is_active == True).all()
    
    return render_template('seo_page.html',
                         seo_page=seo_page,
                         products=products)

# 8.5 دسته‌بندی محصولات
@app.route('/category/<slug>')
def category_products(slug):
    """نمایش محصولات یک دسته‌بندی"""
    category = Category.query.filter_by(slug=slug).first_or_404()
    
    page = request.args.get('page', 1, type=int)
    per_page = 20
    
    # گرفتن فیلترها
    brand_id = request.args.get('brand', type=int)
    min_price = request.args.get('min_price', type=int)
    max_price = request.args.get('max_price', type=int)
    sort = request.args.get('sort', 'newest')
    
    # ساخت کوئری
    query = Product.query.filter_by(
        category_id=category.id,
        is_active=True
    )
    
    # فیلتر برند
    if brand_id:
        query = query.filter_by(brand_id=brand_id)
    
    # فیلتر قیمت
    if min_price:
        query = query.filter(Product.price >= min_price)
    if max_price:
        query = query.filter(Product.price <= max_price)
    
    # مرتب‌سازی
    if sort == 'newest':
        query = query.order_by(Product.created_at.desc())
    elif sort == 'price_low':
        query = query.order_by(Product.price.asc())
    elif sort == 'price_high':
        query = query.order_by(Product.price.desc())
    elif sort == 'popular':
        query = query.order_by(Product.sold_count.desc())
    elif sort == 'discount':
        query = query.filter(Product.discount_percent > 0).order_by(Product.discount_percent.desc())
    else:
        query = query.order_by(Product.created_at.desc())
    
    # صفحه‌بندی
    products = query.paginate(page=page, per_page=per_page)
    
    # برندها برای فیلتر
    brands = Brand.query.filter_by(is_active=True).all()
    
    return render_template('category.html',
        category=category,
        products=products,
        brands=brands
    )
@app.route('/coupons')
def coupons():
    """نمایش کوپن‌های تخفیف فعال"""
    now = datetime.utcnow()
    coupons = Coupon.query.filter(
        Coupon.is_active == True,
        Coupon.start_date <= now,
        Coupon.end_date >= now,
        db.or_(
            Coupon.usage_limit == None,
            Coupon.used_count < Coupon.usage_limit
        )
    ).order_by(Coupon.discount_value.desc()).all()
    
    return render_template('coupons.html', coupons=coupons)
# 8.6 سبد خرید
@app.route('/cart')
def cart():
    cart_items = []
    total = 0
    total_discount = 0
    
    if 'user_id' in session:
        # کاربر لاگین کرده
        items = Cart.query.filter_by(user_id=session['user_id']).all()
    else:
        # کاربر مهمان
        session_id = session.get('session_id')
        if session_id:
            items = Cart.query.filter_by(session_id=session_id).all()
        else:
            items = []
    
    for item in items:
        product = Product.query.get(item.product_id)
        if product:
            price = product.get_final_price()
            item_total = price * item.quantity
            total += item_total
            
            # محاسبه تخفیف
            if product.price > price:
                discount = (product.price - price) * item.quantity
                total_discount += discount
            
            cart_items.append({
                'cart_item': item,
                'product': product,
                'price': price,
                'total': item_total
            })
    
    # محاسبه هزینه ارسال
    shipping_cost = 0
    if cart_items:
        # فرض می‌کنیم ارسال بر اساس اولین محصول
        first_item = cart_items[0]
        shipping_cost = calculate_shipping(first_item['product'].id, first_item['cart_item'].quantity)
    
    final_total = total + shipping_cost
    
    return render_template('cart.html',
                         cart_items=cart_items,
                         total=total,
                         total_discount=total_discount,
                         shipping_cost=shipping_cost,
                         final_total=final_total)
                         
                         
# ===== به‌روزرسانی تعداد =====
@app.route('/api/cart/update', methods=['POST'])
def update_cart():
    try:
        data = request.get_json()
        cart_id = data.get('cart_id')
        quantity = data.get('quantity', 1)
        
        cart_item = Cart.query.get_or_404(cart_id)
        
        # بررسی دسترسی
        if 'user_id' in session and cart_item.user_id != session['user_id']:
            return jsonify({'status': 'error', 'message': 'دسترسی غیرمجاز'}), 403
        
        if quantity < 1:
            return jsonify({'status': 'error', 'message': 'تعداد باید حداقل ۱ باشد'}), 400
        
        product = Product.query.get(cart_item.product_id)
        if quantity > product.stock_quantity:
            return jsonify({'status': 'error', 'message': 'موجودی کافی نیست'}), 400
        
        cart_item.quantity = quantity
        cart_item.updated_at = datetime.utcnow()
        db.session.commit()
        
        return jsonify({'status': 'success', 'message': 'تعداد به‌روزرسانی شد'})
        
    except Exception as e:
        return jsonify({'status': 'error', 'message': str(e)}), 500

# ===== خالی کردن سبد خرید =====
@app.route('/api/cart/clear', methods=['POST'])
def clear_cart():
    try:
        if 'user_id' in session:
            Cart.query.filter_by(user_id=session['user_id']).delete()
        elif session.get('session_id'):
            Cart.query.filter_by(session_id=session['session_id']).delete()
        else:
            return jsonify({'status': 'error', 'message': 'سبد خرید یافت نشد'}), 404
        
        db.session.commit()
        return jsonify({'status': 'success', 'message': 'سبد خرید خالی شد'})
        
    except Exception as e:
        return jsonify({'status': 'error', 'message': str(e)}), 500
# ============================================
# افزودن به سبد خرید - پشتیبانی از کاربر مهمان
# ============================================
@app.route('/api/cart/add', methods=['POST'])
def add_to_cart():
    try:
        data = request.get_json()
        product_id = data.get('product_id')
        quantity = data.get('quantity', 1)
        
        # ===== اعتبارسنجی محصول =====
        product = Product.query.get(product_id)
        if not product or not product.is_active:
            return jsonify({
                'status': 'error',
                'message': 'محصول موجود نیست'
            }), 404
        
        if quantity > product.stock_quantity:
            return jsonify({
                'status': 'error',
                'message': 'موجودی کافی نیست'
            }), 400
        
        # ===== تعیین کاربر یا مهمان =====
        user_id = None
        session_id = None
        
        if 'user_id' in session:
            user_id = session['user_id']
        else:
            session_id = session.get('session_id')
            if not session_id:
                session_id = secrets.token_hex(16)
                session['session_id'] = session_id
        
        # ===== بررسی وجود در سبد خرید =====
        cart_item = Cart.query.filter(
            db.or_(
                Cart.user_id == user_id,
                Cart.session_id == session_id
            ),
            Cart.product_id == product_id
        ).first()
        
        if cart_item:
            cart_item.quantity += quantity
            cart_item.updated_at = datetime.utcnow()
        else:
            cart_item = Cart(
                user_id=user_id,
                session_id=session_id,
                product_id=product_id,
                quantity=quantity,
                price_at_add=product.price
            )
            db.session.add(cart_item)
        
        db.session.commit()
        
        # ===== محاسبه تعداد کل سبد =====
        if user_id:
            total_cart = Cart.query.filter_by(user_id=user_id).count()
        else:
            total_cart = Cart.query.filter_by(session_id=session_id).count()
        
        return jsonify({
            'status': 'success',
            'message': '✅ محصول به سبد خرید اضافه شد',
            'cart_count': total_cart,
            'product_title': product.title
        })
        
    except Exception as e:
        app.logger.error(f"Add to cart error: {str(e)}")
        return jsonify({
            'status': 'error',
            'message': 'خطا در افزودن به سبد خرید'
        }), 500

# 8.8 حذف از سبد خرید
@app.route('/api/cart/remove/<int:cart_id>', methods=['POST'])
def remove_from_cart(cart_id):
    cart_item = Cart.query.get_or_404(cart_id)
    
    # بررسی دسترسی
    if 'user_id' in session and cart_item.user_id != session['user_id']:
        return jsonify({'status': 'error', 'message': 'دسترسی غیرمجاز'})
    
    db.session.delete(cart_item)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'محصول از سبد خرید حذف شد'})

# ============================================
# افزودن به علاقه‌مندی‌ها
# ============================================
@app.route('/api/wishlist/add', methods=['POST'])
@login_required
def add_to_wishlist():
    """افزودن محصول به علاقه‌مندی‌ها"""
    try:
        data = request.get_json()
        product_id = data.get('product_id')
        
        if not product_id:
            return jsonify({
                'status': 'error',
                'message': 'شناسه محصول الزامی است'
            }), 400
        
        product = Product.query.get(product_id)
        if not product:
            return jsonify({
                'status': 'error',
                'message': 'محصول یافت نشد'
            }), 404
        
        user_id = session['user_id']
        
        existing = Wishlist.query.filter_by(
            user_id=user_id,
            product_id=product_id
        ).first()
        
        if existing:
            db.session.delete(existing)
            db.session.commit()
            return jsonify({
                'status': 'success',
                'message': 'محصول از علاقه‌مندی‌ها حذف شد'
            })
        else:
            wishlist = Wishlist(
                user_id=user_id,
                product_id=product_id
            )
            db.session.add(wishlist)
            db.session.commit()
            return jsonify({
                'status': 'success',
                'message': 'محصول به علاقه‌مندی‌ها اضافه شد'
            })
        
    except Exception as e:
        app.logger.error(f"Wishlist error: {str(e)}")
        return jsonify({
            'status': 'error',
            'message': 'خطا در افزودن به علاقه‌مندی‌ها'
        }), 500


# ============================================
# اعمال کد تخفیف
# ============================================
@app.route('/api/coupon/apply', methods=['POST'])
def apply_coupon():
    """اعمال کد تخفیف"""
    try:
        data = request.get_json()
        code = data.get('code', '').strip().upper()
        
        if not code:
            return jsonify({
                'status': 'error',
                'message': 'لطفاً کد تخفیف را وارد کنید'
            }), 400
        
        now = datetime.utcnow()
        coupon = Coupon.query.filter(
            Coupon.code == code,
            Coupon.is_active == True,
            Coupon.start_date <= now,
            Coupon.end_date >= now,
            db.or_(
                Coupon.usage_limit == None,
                Coupon.used_count < Coupon.usage_limit
            )
        ).first()
        
        if not coupon:
            return jsonify({
                'status': 'error',
                'message': 'کد تخفیف نامعتبر یا منقضی شده است'
            }), 404
        
        # ذخیره در session
        session['coupon_code'] = code
        session['coupon_discount'] = coupon.discount_value
        session['coupon_type'] = coupon.discount_type
        
        return jsonify({
            'status': 'success',
            'message': f'کد تخفیف با موفقیت اعمال شد',
            'discount': coupon.discount_value,
            'type': coupon.discount_type
        })
        
    except Exception as e:
        app.logger.error(f"Coupon error: {str(e)}")
        return jsonify({
            'status': 'error',
            'message': 'خطا در اعمال کد تخفیف'
        }), 500
# 8.9 تسویه حساب (Checkout)
@app.route('/checkout')
@login_required
def checkout():
    user = User.query.get(session['user_id'])
    cart_items = Cart.query.filter_by(user_id=user.id).all()
    
    if not cart_items:
        flash('سبد خرید شما خالی است', 'warning')
        return redirect(url_for('cart'))
    
    total = 0
    total_discount = 0  # ← این رو اضافه کن
    
    for item in cart_items:
        product = Product.query.get(item.product_id)
        if product:
            price = product.get_final_price()
            item_total = price * item.quantity
            total += item_total
            
            # محاسبه تخفیف
            if product.price > price:
                discount = (product.price - price) * item.quantity
                total_discount += discount  # ← اینجا محاسبه میشه
    
    # محاسبه هزینه ارسال
    shipping_cost = 0
    if cart_items:
        first_item = cart_items[0]
        product = Product.query.get(first_item.product_id)
        if product:
            shipping_cost = calculate_shipping(product.id, first_item.quantity)
    
    final_total = total + shipping_cost - total_discount  # ← تخفیف اعمال میشه
    
    shipping_methods = ShippingMethod.query.filter_by(is_active=True).all()
    
    return render_template('checkout.html',
        user=user,
        cart_items=cart_items,
        total=total,
        total_discount=total_discount,  # ← حتماً این رو پاس بده
        shipping_cost=shipping_cost,
        final_total=final_total,
        shipping_methods=shipping_methods
    )
# 8.10 ثبت سفارش
@app.route('/checkout/complete', methods=['POST'])
def complete_order():
    if 'user_id' not in session:
        return jsonify({'status': 'error', 'message': 'لطفاً وارد شوید'})
    
    user = User.query.get(session['user_id'])
    cart_items = Cart.query.filter_by(user_id=user.id).all()
    
    if not cart_items:
        return jsonify({'status': 'error', 'message': 'سبد خرید خالی است'})
    
    # دریافت اطلاعات از فرم
    full_name = request.form.get('full_name')
    phone = request.form.get('phone')
    address = request.form.get('address')
    city = request.form.get('city')
    postal_code = request.form.get('postal_code')
    shipping_method = request.form.get('shipping_method')
    payment_method = request.form.get('payment_method', 'online')
    note = request.form.get('note', '')
    
    # محاسبه مبالغ
    total = 0
    order_items_data = []
    
    for item in cart_items:
        product = Product.query.get(item.product_id)
        if product:
            price = product.get_final_price()
            item_total = price * item.quantity
            total += item_total
            order_items_data.append({
                'product': product,
                'quantity': item.quantity,
                'price': price,
                'total': item_total
            })
    
    # محاسبه هزینه ارسال
    shipping_cost = 0
    if order_items_data:
        first_item = order_items_data[0]
        shipping_cost = calculate_shipping(first_item['product'].id, first_item['quantity'])
    
    final_total = total + shipping_cost
    
    # ایجاد سفارش
    order = Order(
        order_number=generate_order_number(),
        user_id=user.id,
        full_name=full_name,
        phone=phone,
        address=address,
        city=city,
        postal_code=postal_code,
        shipping_method=shipping_method,
        shipping_cost=shipping_cost,
        total_amount=total,
        discount_amount=0,
        final_amount=final_total,
        payment_method=payment_method,
        payment_status='pending',
        order_status='pending',
        note=note
    )
    
    db.session.add(order)
    db.session.flush()
    
    # افزودن آیتم‌های سفارش
    for item_data in order_items_data:
        order_item = OrderItem(
            order_id=order.id,
            product_id=item_data['product'].id,
            product_title=item_data['product'].title,
            quantity=item_data['quantity'],
            price=item_data['price'],
            total=item_data['total']
        )
        db.session.add(order_item)
    
    # کاهش موجودی
    for item in cart_items:
        product = Product.query.get(item.product_id)
        if product:
            product.stock_quantity -= item.quantity
            product.sold_count += item.quantity
    
    # حذف سبد خرید
    for item in cart_items:
        db.session.delete(item)
    
    db.session.commit()
    
    # ارسال ایمیل تایید سفارش
    if user.email:
        email_body = f"""
        <h2>سفارش شما ثبت شد</h2>
        <p>شماره سفارش: {order.order_number}</p>
        <p>مبلغ قابل پرداخت: {to_persian_numbers(final_total)} تومان</p>
        <p>وضعیت سفارش: در انتظار پرداخت</p>
        """
        send_email(user.email, 'تایید ثبت سفارش', email_body)
    
    # اگر پرداخت آنلاین است، به درگاه هدایت کن
    if payment_method == 'online':
        return redirect(url_for('payment_initiate', order_id=order.id))
    
    flash('سفارش شما با موفقیت ثبت شد', 'success')
    return redirect(url_for('order_tracking', order_id=order.id))

# ============================================
# 9. درگاه پرداخت (زرین‌پال)
# ============================================

# تنظیمات زرین‌پال (در محیط واقعی از متغیرهای محیطی استفاده کنید)
ZARINPAL_MERCHANT_ID = 'your-merchant-id'
ZARINPAL_SANDBOX = True  # برای تست

@app.route('/payment/initiate/<int:order_id>')
def payment_initiate(order_id):
    """شروع فرآیند پرداخت"""
    order = Order.query.get_or_404(order_id)
    
    if order.payment_status == 'paid':
        flash('این سفارش قبلاً پرداخت شده است', 'warning')
        return redirect(url_for('order_tracking', order_id=order.id))
    
    # آماده‌سازی داده‌ها برای زرین‌پال
    import requests
    import json
    
    amount = order.final_amount
    description = f"پرداخت سفارش شماره {order.order_number}"
    callback_url = url_for('payment_verify', _external=True)
    
    if ZARINPAL_SANDBOX:
        payment_url = 'https://sandbox.zarinpal.com/pg/rest/WebGate/PaymentRequest.json'
    else:
        payment_url = 'https://api.zarinpal.com/pg/v4/payment/request.json'
    
    payload = {
        'merchant_id': ZARINPAL_MERCHANT_ID,
        'amount': amount,
        'description': description,
        'callback_url': callback_url,
        'metadata': {
            'order_id': order.id,
            'order_number': order.order_number
        }
    }
    
    try:
        response = requests.post(payment_url, json=payload)
        data = response.json()
        
        if data.get('data', {}).get('code') == 100:
            authority = data['data']['authority']
            # ذخیره authority در سفارش
            order.tracking_code = authority
            db.session.commit()
            
            if ZARINPAL_SANDBOX:
                gateway_url = f'https://sandbox.zarinpal.com/pg/StartPay/{authority}'
            else:
                gateway_url = f'https://www.zarinpal.com/pg/StartPay/{authority}'
            
            return redirect(gateway_url)
        else:
            flash('خطا در اتصال به درگاه پرداخت', 'danger')
            return redirect(url_for('checkout'))
    
    except Exception as e:
        app.logger.error(f"Payment initiation error: {str(e)}")
        flash('خطا در اتصال به درگاه پرداخت', 'danger')
        return redirect(url_for('checkout'))

@app.route('/payment/verify')
def payment_verify():
    """تایید پرداخت"""
    import requests
    import json
    
    authority = request.args.get('Authority')
    status = request.args.get('Status')
    
    if status != 'OK':
        flash('پرداخت لغو شد', 'warning')
        return redirect(url_for('cart'))
    
    # پیدا کردن سفارش با authority
    order = Order.query.filter_by(tracking_code=authority).first()
    if not order:
        flash('سفارش یافت نشد', 'danger')
        return redirect(url_for('index'))
    
    # تایید پرداخت با زرین‌پال
    if ZARINPAL_SANDBOX:
        verify_url = 'https://sandbox.zarinpal.com/pg/rest/WebGate/PaymentVerification.json'
    else:
        verify_url = 'https://api.zarinpal.com/pg/v4/payment/verify.json'
    
    payload = {
        'merchant_id': ZARINPAL_MERCHANT_ID,
        'amount': order.final_amount,
        'authority': authority
    }
    
    try:
        response = requests.post(verify_url, json=payload)
        data = response.json()
        
        if data.get('data', {}).get('code') == 100:
            # پرداخت موفق
            order.payment_status = 'paid'
            order.order_status = 'processing'
            db.session.commit()
            
            flash('پرداخت با موفقیت انجام شد', 'success')
            
            # ارسال ایمیل تایید پرداخت
            if order.user:
                email_body = f"""
                <h2>پرداخت سفارش شما تایید شد</h2>
                <p>شماره سفارش: {order.order_number}</p>
                <p>وضعیت: پرداخت شده</p>
                <p>به زودی سفارش شما ارسال خواهد شد</p>
                """
                send_email(order.user.email, 'تایید پرداخت سفارش', email_body)
            
            return redirect(url_for('order_tracking', order_id=order.id))
        else:
            # پرداخت ناموفق
            order.order_status = 'cancelled'
            db.session.commit()
            flash('پرداخت ناموفق بود، لطفاً دوباره تلاش کنید', 'danger')
            return redirect(url_for('cart'))
    
    except Exception as e:
        app.logger.error(f"Payment verification error: {str(e)}")
        flash('خطا در تایید پرداخت', 'danger')
        return redirect(url_for('cart'))
        
# ============================================
# 10. روت‌های احراز هویت
# ============================================
# ============================================
# روت ورود - با قابلیت هدایت به صفحه قبلی
# ============================================
@app.route('/login', methods=['GET', 'POST'])
def login():
    if 'user_id' in session:
        return redirect(url_for('index'))
    
    if request.method == 'POST':
        username = request.form.get('username')  # این میتونه نام کاربری، ایمیل یا موبایل باشه
        password = request.form.get('password')
        remember = request.form.get('remember', False)
        
        # ===== جستجو در چند فیلد =====
        user = User.query.filter(
            db.or_(
                User.username == username,
                User.email == username,
                User.phone == username
            )
        ).first()
        
        if not user or not user.check_password(password):
            flash('نام کاربری، ایمیل، موبایل یا رمز عبور اشتباه است', 'danger')
            return render_template('login.html')
        
        if not user.is_active:
            flash('حساب کاربری شما غیرفعال شده است', 'danger')
            return render_template('login.html')
        
        # ===== ذخیره در جلسه =====
        session['user_id'] = user.id
        session['username'] = user.username
        session['role'] = user.role
        session['full_name'] = user.full_name
        
        # ===== به‌روزرسانی آخرین ورود =====
        user.last_login = datetime.utcnow()
        db.session.commit()
        
        # ===== انتقال سبد خرید مهمان به کاربر =====
        session_id = session.get('session_id')
        if session_id:
            guest_cart = Cart.query.filter_by(session_id=session_id).all()
            for item in guest_cart:
                existing = Cart.query.filter_by(
                    user_id=user.id,
                    product_id=item.product_id
                ).first()
                if existing:
                    existing.quantity += item.quantity
                else:
                    item.user_id = user.id
                    item.session_id = None
            db.session.commit()
        
        # ===== ایجاد/به‌روزرسانی امتیازات کاربر =====
        if hasattr(db, 'Reward'):
            reward = Reward.query.filter_by(user_id=user.id).first()
            if not reward:
                reward = Reward(user_id=user.id, points=50)
                db.session.add(reward)
                db.session.commit()
        
        flash(f'✨ خوش آمدید {user.full_name or user.username}', 'success')
        
        # ===== هدایت به صفحه قبلی =====
        next_url = request.args.get('next')
        if next_url:
            return redirect(next_url)
        
        return redirect(url_for('index'))
    
    return render_template('login.html')
    
@app.route('/register', methods=['GET', 'POST'])
def register():
    if 'user_id' in session:
        return redirect(url_for('index'))
    
    if request.method == 'POST':
        # ===== دریافت اطلاعات =====
        full_name = request.form.get('full_name')
        phone = request.form.get('phone')
        password = request.form.get('password')
        confirm_password = request.form.get('confirm_password')
        username = request.form.get('username')  # اختیاری
        email = request.form.get('email')  # اختیاری
        address = request.form.get('address')  # اختیاری
        postal_code = request.form.get('postal_code')  # اختیاری
        
        # ===== اعتبارسنجی (فقط ۳ فیلد اجباری) =====
        errors = []
        
        if not full_name:
            errors.append('نام و نام خانوادگی اجباری است')
        if not phone:
            errors.append('شماره تماس اجباری است')
        if not password or len(password) < 6:
            errors.append('رمز عبور حداقل ۶ کاراکتر باشد')
        if password != confirm_password:
            errors.append('رمز عبور و تکرار آن مطابقت ندارند')
        
        if errors:
            for error in errors:
                flash(error, 'danger')
            return render_template('register.html')
        
        # ===== بررسی تکراری بودن =====
        if User.query.filter_by(phone=phone).first():
            flash('این شماره تماس قبلاً ثبت شده است', 'danger')
            return render_template('register.html')
        
        if username and User.query.filter_by(username=username).first():
            flash('این نام کاربری قبلاً ثبت شده است', 'danger')
            return render_template('register.html')
        
        if email and User.query.filter_by(email=email).first():
            flash('این ایمیل قبلاً ثبت شده است', 'danger')
            return render_template('register.html')
        
        # ===== ایجاد کاربر جدید =====
        user = User(
            full_name=full_name,
            phone=phone,
            username=username or None,
            email=email or None,
            address=address or None,
            postal_code=postal_code or None,
            is_active=True,
            role='user'
        )
        user.set_password(password)
        db.session.add(user)
        db.session.flush()
        
        # ===== امتیاز اولیه =====
        if hasattr(db, 'Reward'):
            reward = Reward(user_id=user.id, points=50)
            db.session.add(reward)
        
        db.session.commit()
        
        flash('✅ ثبت‌نام با موفقیت انجام شد، لطفاً وارد شوید', 'success')
        return redirect(url_for('login'))
    
    return render_template('register.html')

# 10.3 خروج
@app.route('/logout')
def logout():
    session.clear()
    flash('با موفقیت خارج شدید', 'info')
    return redirect(url_for('index'))

# 10.4 پروفایل کاربر
@app.route('/profile')
@login_required
def profile():
    user = User.query.get(session['user_id'])
    return render_template('profile.html', user=user)

# 10.5 ویرایش پروفایل

@app.route('/profile/edit', methods=['POST'])
@login_required
def profile_edit():
    user = User.query.get(session['user_id'])
    
    user.full_name = request.form.get('full_name', user.full_name)
    user.phone = request.form.get('phone', user.phone)
    user.email = request.form.get('email', user.email)
    user.address = request.form.get('address', user.address)  # ✅ آدرس ذخیره میشه
    user.postal_code = request.form.get('postal_code', user.postal_code)  # ✅ کد پستی ذخیره میشه
    
    # تغییر رمز عبور
    new_password = request.form.get('new_password')
    if new_password:
        current_password = request.form.get('current_password')
        if user.check_password(current_password):
            if len(new_password) >= 6:
                user.set_password(new_password)
                flash('رمز عبور با موفقیت تغییر کرد', 'success')
            else:
                flash('رمز عبور جدید باید حداقل ۶ کاراکتر باشد', 'danger')
                return redirect(url_for('profile'))
        else:
            flash('رمز عبور فعلی اشتباه است', 'danger')
            return redirect(url_for('profile'))
    
    db.session.commit()
    flash('اطلاعات با موفقیت به‌روزرسانی شد', 'success')
    return redirect(url_for('profile'))
    
# 10.6 پیگیری سفارش
@app.route('/order/<int:order_id>')
@login_required
def order_tracking(order_id):
    order = Order.query.get_or_404(order_id)
    
    # بررسی دسترسی
    if order.user_id != session['user_id'] and session.get('role') != 'admin':
        flash('شما دسترسی به این سفارش ندارید', 'danger')
        return redirect(url_for('profile'))
    
    return render_template('order_tracking.html', order=order)

# ============================================
# 11. روت‌های API (برای موبایل)
# ============================================

# 11.1 لیست محصولات (API)
@app.route('/api/products', methods=['GET'])
def api_products():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    category_id = request.args.get('category_id', type=int)
    search = request.args.get('search', '')
    
    query = Product.query.filter_by(is_active=True)
    
    if category_id:
        query = query.filter_by(category_id=category_id)
    if search:
        query = query.filter(
            db.or_(
                Product.title.contains(search),
                Product.description.contains(search)
            )
        )
    
    query = query.order_by(Product.created_at.desc())
    products = query.paginate(page=page, per_page=per_page)
    
    result = {
        'status': 'success',
        'data': {
            'products': [{
                'id': p.id,
                'title': p.title,
                'slug': p.slug,
                'price': p.price,
                'final_price': p.get_final_price(),
                'image': p.images[0].image_url if p.images else None,
                'stock': p.stock_quantity,
                'is_in_stock': p.is_in_stock()
            } for p in products.items],
            'pagination': {
                'page': products.page,
                'per_page': products.per_page,
                'total': products.total,
                'pages': products.pages
            }
        }
    }
    
    return jsonify(result)

# 11.2 جزئیات محصول (API)
@app.route('/api/product/<int:product_id>', methods=['GET'])
def api_product_detail(product_id):
    product = Product.query.get_or_404(product_id)
    
    # افزایش بازدید
    product.views += 1
    db.session.commit()
    
    images = ProductImage.query.filter_by(product_id=product.id).order_by(ProductImage.order).all()
    specs = ProductSpec.query.filter_by(product_id=product.id).all()
    
    result = {
        'status': 'success',
        'data': {
            'id': product.id,
            'title': product.title,
            'slug': product.slug,
            'description': product.description,
            'short_description': product.short_description,
            'price': product.price,
            'final_price': product.get_final_price(),
            'compare_price': product.compare_price,
            'stock_quantity': product.stock_quantity,
            'is_in_stock': product.is_in_stock(),
            'weight': product.weight,
            'discount_percent': product.discount_percent,
            'shipping_cost': product.shipping_cost,
            'free_shipping': product.free_shipping,
            'images': [img.image_url for img in images],
            'specs': [{'key': spec.spec_key, 'value': spec.spec_value} for spec in specs],
            'category': product.category.name if product.category else None,
            'brand': product.brand.name if product.brand else None
        }
    }
    
    return jsonify(result)

# 11.3 افزودن به سبد خرید (API)
@app.route('/api/cart/add', methods=['POST'])
@jwt_required()
def api_add_to_cart():
    user_id = get_jwt_identity()
    data = request.get_json()
    
    product_id = data.get('product_id')
    quantity = data.get('quantity', 1)
    
    product = Product.query.get(product_id)
    if not product or not product.is_active:
        return jsonify({'status': 'error', 'message': 'محصول موجود نیست'}), 404
    
    if quantity > product.stock_quantity:
        return jsonify({'status': 'error', 'message': 'موجودی کافی نیست'}), 400
    
    cart_item = Cart.query.filter_by(user_id=user_id, product_id=product_id).first()
    
    if cart_item:
        cart_item.quantity += quantity
    else:
        cart_item = Cart(
            user_id=user_id,
            product_id=product_id,
            quantity=quantity,
            price_at_add=product.price
        )
        db.session.add(cart_item)
    
    db.session.commit()
    
    return jsonify({
        'status': 'success',
        'message': 'محصول به سبد خرید اضافه شد',
        'cart_count': Cart.query.filter_by(user_id=user_id).count()
    })

# 11.4 مشاهده سبد خرید (API)
@app.route('/api/cart', methods=['GET'])
@jwt_required()
def api_cart():
    user_id = get_jwt_identity()
    cart_items = Cart.query.filter_by(user_id=user_id).all()
    
    items = []
    total = 0
    for item in cart_items:
        product = Product.query.get(item.product_id)
        if product:
            price = product.get_final_price()
            item_total = price * item.quantity
            total += item_total
            items.append({
                'id': item.id,
                'product_id': product.id,
                'product_title': product.title,
                'quantity': item.quantity,
                'price': price,
                'total': item_total,
                'image': product.images[0].image_url if product.images else None
            })
    
    return jsonify({
        'status': 'success',
        'data': {
            'items': items,
            'total': total,
            'count': len(items)
        }
    })

# 11.5 حذف از سبد خرید (API)
@app.route('/api/cart/remove/<int:item_id>', methods=['DELETE'])
@jwt_required()
def api_remove_from_cart(item_id):
    user_id = get_jwt_identity()
    cart_item = Cart.query.get_or_404(item_id)
    
    if cart_item.user_id != user_id:
        return jsonify({'status': 'error', 'message': 'دسترسی غیرمجاز'}), 403
    
    db.session.delete(cart_item)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'محصول از سبد خرید حذف شد'})

# 11.6 ورود با JWT (API)
@app.route('/api/auth/login', methods=['POST'])
def api_login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    
    user = User.query.filter_by(username=username).first()
    
    if not user or not user.check_password(password):
        return jsonify({'status': 'error', 'message': 'نام کاربری یا رمز عبور اشتباه است'}), 401
    
    if not user.is_active:
        return jsonify({'status': 'error', 'message': 'حساب کاربری غیرفعال است'}), 403
    
    access_token = create_access_token(identity=user.id)
    
    return jsonify({
        'status': 'success',
        'data': {
            'access_token': access_token,
            'user': {
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'full_name': user.full_name,
                'role': user.role
            }
        }
    })

# 11.7 ثبت‌نام (API)
@app.route('/api/auth/register', methods=['POST'])
def api_register():
    data = request.get_json()
    
    username = data.get('username')
    email = data.get('email')
    password = data.get('password')
    full_name = data.get('full_name')
    phone = data.get('phone')
    
    # اعتبارسنجی
    if not username or not email or not password:
        return jsonify({'status': 'error', 'message': 'فیلدهای اجباری را پر کنید'}), 400
    
    if len(password) < 6:
        return jsonify({'status': 'error', 'message': 'رمز عبور باید حداقل ۶ کاراکتر باشد'}), 400
    
    if User.query.filter_by(username=username).first():
        return jsonify({'status': 'error', 'message': 'نام کاربری تکراری است'}), 400
    
    if User.query.filter_by(email=email).first():
        return jsonify({'status': 'error', 'message': 'ایمیل تکراری است'}), 400
    
    user = User(
        username=username,
        email=email,
        full_name=full_name,
        phone=phone
    )
    user.set_password(password)
    
    db.session.add(user)
    db.session.commit()
    
    return jsonify({
        'status': 'success',
        'message': 'ثبت‌نام با موفقیت انجام شد'
    })

# 11.8 پروفایل کاربر (API)
@app.route('/api/user/profile', methods=['GET'])
@jwt_required()
def api_profile():
    user_id = get_jwt_identity()
    user = User.query.get(user_id)
    
    return jsonify({
        'status': 'success',
        'data': {
            'id': user.id,
            'username': user.username,
            'email': user.email,
            'full_name': user.full_name,
            'phone': user.phone,
            'address': user.address,
            'created_at': user.created_at.isoformat() if user.created_at else None
        }
    })

# 11.9 تاریخچه سفارشات (API)
@app.route('/api/orders', methods=['GET'])
@jwt_required()
def api_orders():
    user_id = get_jwt_identity()
    orders = Order.query.filter_by(user_id=user_id).order_by(Order.created_at.desc()).all()
    
    result = []
    for order in orders:
        result.append({
            'id': order.id,
            'order_number': order.order_number,
            'final_amount': order.final_amount,
            'order_status': order.order_status,
            'payment_status': order.payment_status,
            'created_at': order.created_at.isoformat() if order.created_at else None
        })
    
    return jsonify({
        'status': 'success',
        'data': result
    })

# 11.10 جستجو (API)
@app.route('/api/search', methods=['GET'])
def api_search():
    query = request.args.get('q', '')
    if not query or len(query) < 2:
        return jsonify({'status': 'success', 'data': []})
    
    products = Product.query.filter(
        Product.is_active == True,
        db.or_(
            Product.title.contains(query),
            Product.description.contains(query),
            Product.seo_keywords.contains(query)
        )
    ).limit(20).all()
    
    result = [{
        'id': p.id,
        'title': p.title,
        'price': p.price,
        'final_price': p.get_final_price(),
        'image': p.images[0].image_url if p.images else None
    } for p in products]
    
    return jsonify({'status': 'success', 'data': result})
    
# ============================================
# 12. روت‌های مدیریت (پنل ادمین)
# ============================================

# 12.1 داشبورد مدیریت
@app.route('/admin')
@admin_required
def admin_dashboard():
    # آمار کلی
    total_products = Product.query.count()
    total_orders = Order.query.count()
    total_users = User.query.count()
    pending_orders = Order.query.filter_by(order_status='pending').count()
    
    # فروش امروز
    today = datetime.utcnow().date()
    today_orders = Order.query.filter(
        db.func.date(Order.created_at) == today,
        Order.payment_status == 'paid'
    ).all()
    today_sales = sum(order.final_amount for order in today_orders)
    
    # فروش ماه جاری
    month_start = datetime(today.year, today.month, 1)
    month_orders = Order.query.filter(
        Order.created_at >= month_start,
        Order.payment_status == 'paid'
    ).all()
    month_sales = sum(order.final_amount for order in month_orders)
    
    # آخرین سفارشات
    recent_orders = Order.query.order_by(Order.created_at.desc()).limit(10).all()
    
    # محصولات کم‌موجود
    low_stock_products = Product.query.filter(Product.stock_quantity < 5).limit(10).all()
    
    return render_template('admin/dashboard.html',
                         total_products=total_products,
                         total_orders=total_orders,
                         total_users=total_users,
                         pending_orders=pending_orders,
                         today_sales=today_sales,
                         month_sales=month_sales,
                         recent_orders=recent_orders,
                         low_stock_products=low_stock_products)


# ============================================================
# روت‌های مدیریت پرداخت و تراکنش‌ها
# ============================================================
# ============================================================
# روت‌های ادمین - برندها
# ============================================================

@app.route('/admin/brands')
@admin_required
def admin_brands():
    """مدیریت برندها"""
    brands = Brand.query.order_by(Brand.name).all()
    return render_template('admin/brands.html', brands=brands)


@app.route('/admin/brand/add', methods=['POST'])
@admin_required
def admin_brand_add():
    """افزودن برند جدید"""
    name = request.form.get('name')
    is_active = request.form.get('is_active') == 'on'
    
    if not name:
        flash('نام برند اجباری است', 'danger')
        return redirect(url_for('admin_brands'))
    
    # بررسی تکراری نبودن
    if Brand.query.filter_by(name=name).first():
        flash('این برند قبلاً ثبت شده است', 'danger')
        return redirect(url_for('admin_brands'))
    
    # تولید اسلاگ
    slug = generate_slug(name, Brand)
    if Brand.query.filter_by(slug=slug).first():
        slug = f"{slug}-{secrets.token_hex(4)}"
    
    brand = Brand(
        name=name,
        slug=slug,
        is_active=is_active
    )
    
    # آپلود لوگو
    logo = request.files.get('logo')
    if logo and logo.filename:
        logo_url = upload_image(logo, 'brands')
        if logo_url:
            brand.logo = logo_url
    
    db.session.add(brand)
    db.session.commit()
    
    flash('✅ برند با موفقیت اضافه شد', 'success')
    return redirect(url_for('admin_brands'))


@app.route('/admin/brand/edit/<int:id>', methods=['GET', 'POST'])
@admin_required
def admin_brand_edit(id):
    """ویرایش برند"""
    brand = Brand.query.get_or_404(id)
    
    if request.method == 'POST':
        brand.name = request.form.get('name', brand.name)
        brand.is_active = request.form.get('is_active') == 'on'
        
        # آپلود لوگو
        logo = request.files.get('logo')
        if logo and logo.filename:
            logo_url = upload_image(logo, 'brands')
            if logo_url:
                brand.logo = logo_url
        
        db.session.commit()
        flash('✅ برند با موفقیت ویرایش شد', 'success')
        return redirect(url_for('admin_brands'))
    
    return render_template('admin/brand_edit.html', brand=brand)


@app.route('/admin/brand/delete/<int:id>', methods=['POST'])
@admin_required
def admin_brand_delete(id):
    """حذف برند"""
    brand = Brand.query.get_or_404(id)
    
    # حذف لوگو
    if brand.logo:
        filepath = os.path.join('static', brand.logo.lstrip('/'))
        if os.path.exists(filepath):
            os.remove(filepath)
    
    db.session.delete(brand)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'برند با موفقیت حذف شد'})


@app.route('/product/review/<int:product_id>', methods=['POST'])
@login_required
def add_review(product_id):
    """افزودن نظر برای محصول"""
    product = Product.query.get_or_404(product_id)
    rating = request.form.get('rating', type=int)
    comment = request.form.get('comment')
    
    # اعتبارسنجی
    if not rating or rating < 1 or rating > 5:
        flash('لطفاً امتیاز معتبر وارد کنید (۱ تا ۵)', 'danger')
        return redirect(url_for('product_detail', slug=product.slug))
    
    if not comment or len(comment) < 10:
        flash('لطفاً نظر خود را با حداقل ۱۰ کاراکتر وارد کنید', 'danger')
        return redirect(url_for('product_detail', slug=product.slug))
    
    # بررسی تکراری نبودن
    existing = Review.query.filter_by(
        product_id=product_id,
        user_id=session['user_id']
    ).first()
    
    if existing:
        flash('شما قبلاً برای این محصول نظر داده‌اید', 'warning')
        return redirect(url_for('product_detail', slug=product.slug))
    
    # ایجاد نظر
    review = Review(
        product_id=product_id,
        user_id=session['user_id'],
        rating=rating,
        comment=comment,
        is_approved=True  # تایید خودکار
    )
    
    db.session.add(review)
    db.session.commit()
    
    flash('✅ نظر شما با موفقیت ثبت شد', 'success')
    return redirect(url_for('product_detail', slug=product.slug))

# ============================================================
# روت‌های ادمین - کاربران
# ============================================================

@app.route('/admin/users')
@admin_required
def admin_users():
    """مدیریت کاربران"""
    page = request.args.get('page', 1, type=int)
    search = request.args.get('search', '')
    per_page = 20
    
    query = User.query
    if search:
        query = query.filter(
            db.or_(
                User.username.contains(search),
                User.email.contains(search),
                User.full_name.contains(search)
            )
        )
    
    users = query.order_by(User.created_at.desc()).paginate(page=page, per_page=per_page)
    return render_template('admin/users.html', users=users)


@app.route('/admin/user/edit/<int:id>', methods=['GET', 'POST'])
@admin_required
def admin_user_edit(id):
    """ویرایش کاربر"""
    user = User.query.get_or_404(id)
    
    if request.method == 'POST':
        user.username = request.form.get('username', user.username)
        user.email = request.form.get('email', user.email)
        user.full_name = request.form.get('full_name', user.full_name)
        user.phone = request.form.get('phone', user.phone)
        user.role = request.form.get('role', user.role)
        user.is_active = request.form.get('is_active') == 'on'
        
        # تغییر رمز عبور
        password = request.form.get('password')
        if password and len(password) >= 6:
            user.set_password(password)
        
        db.session.commit()
        flash('✅ کاربر با موفقیت ویرایش شد', 'success')
        return redirect(url_for('admin_users'))
    
    return render_template('admin/user_edit.html', user=user)


@app.route('/admin/user/delete/<int:id>', methods=['POST'])
@admin_required
def admin_user_delete(id):
    """حذف کاربر"""
    user = User.query.get_or_404(id)
    
    # جلوگیری از حذف ادمین خودش
    if user.id == session.get('user_id'):
        return jsonify({'status': 'error', 'message': 'نمی‌توانید خودتان را حذف کنید'})
    
    db.session.delete(user)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'کاربر با موفقیت حذف شد'})


# ============================================================
# روت‌های ادمین - تنظیمات پرداخت
# ============================================================

@app.route('/admin/payment/settings', methods=['GET', 'POST'])
@admin_required
def admin_payment_settings():
    """تنظیمات درگاه پرداخت زرین‌پال"""
    setting = Setting.query.first()
    if not setting:
        setting = Setting()
        db.session.add(setting)
        db.session.commit()
    
    if request.method == 'POST':
        # ذخیره تنظیمات پرداخت در setting
        payment_config = {
            'merchant_id': request.form.get('merchant_id'),
            'sandbox': request.form.get('sandbox') == 'on',
            'callback_url': request.form.get('callback_url', url_for('payment_verify', _external=True))
        }
        setting.payment_config = json.dumps(payment_config, ensure_ascii=False)
        db.session.commit()
        flash('✅ تنظیمات پرداخت با موفقیت ذخیره شد', 'success')
        return redirect(url_for('admin_payment_settings'))
    
    payment_config = {}
    if setting and setting.payment_config:
        try:
            payment_config = json.loads(setting.payment_config)
        except:
            pass
    
    return render_template('admin/payment_settings.html', payment_config=payment_config)


@app.route('/admin/transactions')
@admin_required
def admin_transactions():
    """مشاهده همه تراکنش‌ها"""
    page = request.args.get('page', 1, type=int)
    per_page = 20
    status = request.args.get('status', 'all')
    
    # دریافت تراکنش‌ها از دیتابیس
    query = Order.query.filter(Order.payment_status != 'pending')
    if status == 'paid':
        query = query.filter_by(payment_status='paid')
    elif status == 'failed':
        query = query.filter_by(payment_status='failed')
    
    transactions = query.order_by(Order.created_at.desc()).paginate(page=page, per_page=per_page)
    
    return render_template('admin/transactions.html', transactions=transactions, status=status)


@app.route('/admin/payment/report')
@admin_required
def admin_payment_report():
    """گزارش پرداخت‌ها"""
    from datetime import datetime, timedelta
    
    today = datetime.utcnow().date()
    month_start = datetime(today.year, today.month, 1)
    
    # آمار پرداخت‌ها
    total_paid = Order.query.filter_by(payment_status='paid').count()
    total_pending = Order.query.filter_by(payment_status='pending').count()
    total_failed = Order.query.filter_by(payment_status='failed').count()
    
    # مبالغ
    paid_amount = Order.query.filter_by(payment_status='paid').with_entities(db.func.sum(Order.final_amount)).scalar() or 0
    pending_amount = Order.query.filter_by(payment_status='pending').with_entities(db.func.sum(Order.final_amount)).scalar() or 0
    
    # امروز
    today_start = datetime(today.year, today.month, today.day)
    today_orders = Order.query.filter(Order.created_at >= today_start, Order.payment_status == 'paid').all()
    today_paid = sum(o.final_amount for o in today_orders)
    
    # ماه جاری
    month_orders = Order.query.filter(Order.created_at >= month_start, Order.payment_status == 'paid').all()
    month_paid = sum(o.final_amount for o in month_orders)
    
    return render_template('admin/payment_report.html',
        total_paid=total_paid,
        total_pending=total_pending,
        total_failed=total_failed,
        paid_amount=paid_amount,
        pending_amount=pending_amount,
        today_paid=today_paid,
        month_paid=month_paid
    )
# 12.2 مدیریت محصولات
@app.route('/admin/products')
@admin_required
def admin_products():
    page = request.args.get('page', 1, type=int)
    per_page = 20
    products = Product.query.order_by(Product.created_at.desc()).paginate(page=page, per_page=per_page)
    return render_template('admin/products.html', products=products)

# 12.3 افزودن محصول
@app.route('/admin/products/add', methods=['GET', 'POST'])
@admin_required
def admin_product_add():
    categories = Category.query.all()
    brands = Brand.query.all()
    
    if request.method == 'POST':
        # دریافت اطلاعات
        title = request.form.get('title')
        category_id = request.form.get('category_id', type=int)
        brand_id = request.form.get('brand_id', type=int)
        description = request.form.get('description')
        short_description = request.form.get('short_description')
        price = request.form.get('price', type=int)
        compare_price = request.form.get('compare_price', type=int)
        cost_per_item = request.form.get('cost_per_item', type=int)
        stock_quantity = request.form.get('stock_quantity', type=int, default=0)
        sku = request.form.get('sku')
        weight = request.form.get('weight', type=float, default=0)
        shipping_cost = request.form.get('shipping_cost', type=int, default=0)
        free_shipping = request.form.get('free_shipping') == 'on'
        is_featured = request.form.get('is_featured') == 'on'
        is_new = request.form.get('is_new') == 'on'
        is_active = request.form.get('is_active') == 'on'
        discount_percent = request.form.get('discount_percent', type=int, default=0)
        discount_start = request.form.get('discount_start')
        discount_end = request.form.get('discount_end')
        seo_title = request.form.get('seo_title')
        seo_description = request.form.get('seo_description')
        seo_keywords = request.form.get('seo_keywords')
        
        # اعتبارسنجی
        if not title or not price:
            flash('عنوان و قیمت اجباری هستند', 'danger')
            return render_template('admin/product_add.html', categories=categories, brands=brands)
        
        # ایجاد اسلاگ
        slug = generate_slug(title, Product)
        # بررسی یکتا بودن اسلاگ
        if Product.query.filter_by(slug=slug).first():
            slug = f"{slug}-{secrets.token_hex(4)}"
        
        # ایجاد محصول
        product = Product(
            title=title,
            slug=slug,
            category_id=category_id,
            brand_id=brand_id,
            description=description,
            short_description=short_description,
            price=price,
            compare_price=compare_price,
            cost_per_item=cost_per_item,
            stock_quantity=stock_quantity,
            sku=sku or f"SKU-{secrets.token_hex(6).upper()}",
            weight=weight,
            shipping_cost=shipping_cost,
            free_shipping=free_shipping,
            is_featured=is_featured,
            is_new=is_new,
            is_active=is_active,
            discount_percent=discount_percent,
            seo_title=seo_title,
            seo_description=seo_description,
            seo_keywords=seo_keywords
        )
        
        # تنظیم زمان تخفیف
        if discount_start:
            product.discount_start = datetime.fromisoformat(discount_start)
        if discount_end:
            product.discount_end = datetime.fromisoformat(discount_end)
        
        # محاسبه قیمت تخفیف‌خورده
        if discount_percent > 0:
            product.discount_price = int(price * (1 - discount_percent / 100))
        
        db.session.add(product)
        db.session.flush()
        
        # آپلود تصاویر
        images = request.files.getlist('images')
        is_main = True
        for img in images:
            if img and img.filename:
                image_url = upload_image(img, 'products')
                if image_url:
                    product_image = ProductImage(
                        product_id=product.id,
                        image_url=image_url,
                        is_main=is_main,
                        order=0 if is_main else len(product.images)
                    )
                    db.session.add(product_image)
                    is_main = False
        
        # مشخصات فنی
        spec_keys = request.form.getlist('spec_key[]')
        spec_values = request.form.getlist('spec_value[]')
        for key, value in zip(spec_keys, spec_values):
            if key and value:
                spec = ProductSpec(
                    product_id=product.id,
                    spec_key=key,
                    spec_value=value
                )
                db.session.add(spec)
        
        db.session.commit()
        
        flash('محصول با موفقیت اضافه شد', 'success')
        return redirect(url_for('admin_products'))
    
    return render_template('admin/product_add.html', categories=categories, brands=brands)

# 12.4 ویرایش محصول
@app.route('/admin/products/edit/<int:product_id>', methods=['GET', 'POST'])
@admin_required
def admin_product_edit(product_id):
    product = Product.query.get_or_404(product_id)
    categories = Category.query.all()
    brands = Brand.query.all()
    
    if request.method == 'POST':
        # به‌روزرسانی اطلاعات
        product.title = request.form.get('title', product.title)
        product.category_id = request.form.get('category_id', type=int) or product.category_id
        product.brand_id = request.form.get('brand_id', type=int) or product.brand_id
        product.description = request.form.get('description', product.description)
        product.short_description = request.form.get('short_description', product.short_description)
        product.price = request.form.get('price', type=int, default=product.price)
        product.compare_price = request.form.get('compare_price', type=int)
        product.cost_per_item = request.form.get('cost_per_item', type=int)
        product.stock_quantity = request.form.get('stock_quantity', type=int, default=0)
        product.sku = request.form.get('sku', product.sku)
        product.weight = request.form.get('weight', type=float, default=0)
        product.shipping_cost = request.form.get('shipping_cost', type=int, default=0)
        product.free_shipping = request.form.get('free_shipping') == 'on'
        product.is_featured = request.form.get('is_featured') == 'on'
        product.is_new = request.form.get('is_new') == 'on'
        product.is_active = request.form.get('is_active') == 'on'
        product.discount_percent = request.form.get('discount_percent', type=int, default=0)
        product.seo_title = request.form.get('seo_title', product.seo_title)
        product.seo_description = request.form.get('seo_description', product.seo_description)
        product.seo_keywords = request.form.get('seo_keywords', product.seo_keywords)
        
        # زمان تخفیف
        discount_start = request.form.get('discount_start')
        discount_end = request.form.get('discount_end')
        if discount_start:
            product.discount_start = datetime.fromisoformat(discount_start)
        if discount_end:
            product.discount_end = datetime.fromisoformat(discount_end)
        
        # محاسبه قیمت تخفیف‌خورده
        if product.discount_percent > 0:
            product.discount_price = int(product.price * (1 - product.discount_percent / 100))
        else:
            product.discount_price = None
        
        # به‌روزرسانی اسلاگ در صورت تغییر عنوان
        new_slug = generate_slug(product.title,Product)
        if new_slug != product.slug:
            if not Product.query.filter_by(slug=new_slug).first():
                product.slug = new_slug
        
        db.session.commit()
        
        flash('محصول با موفقیت ویرایش شد', 'success')
        return redirect(url_for('admin_products'))
    
    return render_template('admin/product_edit.html',
                         product=product,
                         categories=categories,
                         brands=brands)

# 12.5 حذف محصول
@app.route('/admin/products/delete/<int:product_id>', methods=['POST'])
@admin_required
def admin_product_delete(product_id):
    product = Product.query.get_or_404(product_id)
    
    # حذف تصاویر
    for image in product.images:
        # حذف فایل فیزیکی
        filepath = os.path.join('static', image.image_url.lstrip('/'))
        if os.path.exists(filepath):
            os.remove(filepath)
    
    db.session.delete(product)
    db.session.commit()
    
    flash('محصول با موفقیت حذف شد', 'success')
    return redirect(url_for('admin_products'))

# 12.6 مدیریت دسته‌بندی‌ها
@app.route('/admin/categories')
@admin_required
def admin_categories():
    categories = Category.query.all()
    return render_template('admin/categories.html', categories=categories)

# 12.7 افزودن دسته‌بندی
@app.route('/admin/categories/add', methods=['POST'])
@admin_required
def admin_category_add():
    name = request.form.get('name')
    parent_id = request.form.get('parent_id', type=int)
    description = request.form.get('description')
    seo_title = request.form.get('seo_title')
    seo_description = request.form.get('seo_description')
    
    if not name:
        flash('نام دسته‌بندی اجباری است', 'danger')
        return redirect(url_for('admin_categories'))
    
    slug = generate_slug(name, Category)
    if Category.query.filter_by(slug=slug).first():
        slug = f"{slug}-{secrets.token_hex(4)}"
    
    category = Category(
        name=name,
        slug=slug,
        parent_id=parent_id,
        description=description,
        seo_title=seo_title,
        seo_description=seo_description
    )
    
    # آپلود تصویر
    image = request.files.get('image')
    if image and image.filename:
        image_url = upload_image(image, 'categories')
        if image_url:
            category.image = image_url
    
    db.session.add(category)
    db.session.commit()
    
    flash('دسته‌بندی با موفقیت اضافه شد', 'success')
    return redirect(url_for('admin_categories'))

# 12.8 مدیریت سفارشات
@app.route('/admin/orders')
@admin_required
def admin_orders():
    """مدیریت سفارشات"""
    page = request.args.get('page', 1, type=int)
    per_page = 20
    status = request.args.get('status', 'all')
    search = request.args.get('search', '')
    payment = request.args.get('payment', '')
    
    query = Order.query
    
    if status != 'all':
        query = query.filter_by(order_status=status)
    
    if search:
        query = query.filter(Order.order_number.contains(search))
    
    if payment:
        query = query.filter_by(payment_method=payment)
    
    orders = query.order_by(Order.created_at.desc()).paginate(page=page, per_page=per_page)
    return render_template('admin/orders.html', orders=orders, status=status)
    
# 12.9 تغییر وضعیت سفارش
@app.route('/admin/orders/update/<int:order_id>', methods=['POST'])
@admin_required
def admin_order_update(order_id):
    order = Order.query.get_or_404(order_id)
    order_status = request.form.get('order_status')
    tracking_code = request.form.get('tracking_code')
    
    if order_status:
        old_status = order.order_status
        order.order_status = order_status
        
        # ارسال ایمیل به کاربر در صورت تغییر وضعیت
        if old_status != order_status and order.user and order.user.email:
            status_names = {
                'pending': 'در انتظار پرداخت',
                'processing': 'در حال پردازش',
                'shipped': 'ارسال شده',
                'delivered': 'تحویل داده شده',
                'cancelled': 'لغو شده'
            }
            email_body = f"""
            <h2>به‌روزرسانی وضعیت سفارش</h2>
            <p>شماره سفارش: {order.order_number}</p>
            <p>وضعیت جدید: {status_names.get(order_status, order_status)}</p>
            """
            if tracking_code:
                email_body += f"<p>کد رهگیری: {tracking_code}</p>"
            send_email(order.user.email, 'به‌روزرسانی سفارش', email_body)
    
    if tracking_code:
        order.tracking_code = tracking_code
    
    db.session.commit()
    flash('وضعیت سفارش به‌روزرسانی شد', 'success')
    return redirect(url_for('admin_orders'))

# 12.10 مدیریت بک‌آپ
# ============================================================
# روت‌های ادمین - بک‌آپ
# ============================================================

@app.route('/admin/backup')
@admin_required
def admin_backup():
    backups = Backup.query.order_by(Backup.created_at.desc()).all()
    return render_template('admin/backup.html', backups=backups)


@app.route('/admin/backup/create', methods=['POST'])
@admin_required
def admin_backup_create():
    backup_type = request.form.get('backup_type', 'full')
    description = request.form.get('description', '')
    
    filename = create_backup(backup_type, description)
    flash(f'✅ بک‌آپ با موفقیت ایجاد شد: {filename}', 'success')
    return redirect(url_for('admin_backup'))


@app.route('/admin/backup/download/<int:backup_id>')
@admin_required
def admin_backup_download(backup_id):
    backup = Backup.query.get_or_404(backup_id)
    
    if not os.path.exists(backup.file_path):
        flash('❌ فایل بک‌آپ یافت نشد', 'danger')
        return redirect(url_for('admin_backup'))
    
    return send_file(backup.file_path, as_attachment=True, download_name=backup.file_name)


@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'))
    
    # ذخیره فایل موقت
    temp_path = os.path.join('backups', 'temp_restore.json')
    os.makedirs('backups', exist_ok=True)
    file.save(temp_path)
    
    # بازیابی
    success, message = restore_backup(temp_path)
    
    # حذف فایل موقت
    if os.path.exists(temp_path):
        os.remove(temp_path)
    
    if success:
        flash(f'✅ {message}', 'success')
    else:
        flash(f'❌ {message}', 'danger')
    
    return redirect(url_for('admin_backup'))


@app.route('/admin/backup/delete/<int:id>', methods=['POST'])
@admin_required
def admin_backup_delete(id):
    backup = Backup.query.get_or_404(id)
    
    # حذف فایل فیزیکی
    if os.path.exists(backup.file_path):
        os.remove(backup.file_path)
    
    db.session.delete(backup)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'بک‌آپ با موفقیت حذف شد'})


# ============================================================
# روت‌های ادمین - سفارشات
# ============================================================

@app.route('/admin/order/detail/<int:order_id>')
@admin_required
def admin_order_detail(order_id):
    order = Order.query.get_or_404(order_id)
    return render_template('admin/order_detail.html', order=order)


@app.route('/admin/order/edit/<int:order_id>', methods=['GET', 'POST'])
@admin_required
def admin_order_edit(order_id):
    order = Order.query.get_or_404(order_id)
    
    if request.method == 'POST':
        order.order_status = request.form.get('order_status', order.order_status)
        order.tracking_code = request.form.get('tracking_code', order.tracking_code)
        order.note = request.form.get('note', order.note)
        
        db.session.commit()
        flash('✅ سفارش با موفقیت به‌روزرسانی شد', 'success')
        return redirect(url_for('admin_orders'))
    
    return render_template('admin/order_edit.html', order=order)


@app.route('/admin/order/delete/<int:id>', methods=['POST'])
@admin_required
def admin_order_delete(id):
    order = Order.query.get_or_404(id)
    db.session.delete(order)
    db.session.commit()
    return jsonify({'status': 'success', 'message': 'سفارش با موفقیت حذف شد'})


# ============================================================
# روت‌های ادمین - دسته‌بندی‌ها
# ============================================================

@app.route('/admin/category/delete/<int:id>', methods=['POST'])
@admin_required
def admin_category_delete(id):
    category = Category.query.get_or_404(id)
    db.session.delete(category)
    db.session.commit()
    return jsonify({'status': 'success', 'message': 'دسته‌بندی با موفقیت حذف شد'})


@app.route('/admin/category/edit/<int:id>', methods=['GET', 'POST'])
@admin_required
def admin_category_edit(id):
    category = Category.query.get_or_404(id)
    categories = Category.query.filter(Category.id != id).all()
    
    if request.method == 'POST':
        category.name = request.form.get('name', category.name)
        category.parent_id = request.form.get('parent_id', type=int) or None
        category.description = request.form.get('description', category.description)
        category.order = request.form.get('order', type=int, default=0)
        
        # آپلود تصویر
        image = request.files.get('image')
        if image and image.filename:
            image_url = upload_image(image, 'categories')
            if image_url:
                category.image = image_url
        
        db.session.commit()
        flash('✅ دسته‌بندی با موفقیت به‌روزرسانی شد', 'success')
        return redirect(url_for('admin_categories'))
    
    return render_template('admin/category_edit.html', category=category, categories=categories)

# 12.14 انتشار در ترب و باسلام
@app.route('/admin/generate-sitemap')
@admin_required
def admin_generate_sitemap():
    """تولید Sitemap.xml"""
    try:
        # اطمینان از وجود پوشه static
        if not os.path.exists('static'):
            os.makedirs('static')
        
        base_url = request.host_url.rstrip('/')
        sitemap = '<?xml version="1.0" encoding="UTF-8"?>\n'
        sitemap += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
        
        # صفحات اصلی
        pages = ['/', '/products', '/about', '/contact', '/coupons']
        for page in pages:
            sitemap += f'<url>\n<loc>{base_url}{page}</loc>\n'
            sitemap += f'<lastmod>{datetime.utcnow().date()}</lastmod>\n'
            sitemap += '<changefreq>weekly</changefreq>\n<priority>0.8</priority>\n</url>\n'
        
        # محصولات
        products = Product.query.filter_by(is_active=True).all()
        for product in products:
            sitemap += f'<url>\n<loc>{base_url}/product/{product.slug}</loc>\n'
            sitemap += f'<lastmod>{product.updated_at.date() if product.updated_at else datetime.utcnow().date()}</lastmod>\n'
            sitemap += '<changefreq>daily</changefreq>\n<priority>0.9</priority>\n</url>\n'
        
        # صفحات سئو
        seo_pages = SeoPage.query.all()
        for page in seo_pages:
            sitemap += f'<url>\n<loc>{base_url}/seo/{page.slug}</loc>\n'
            sitemap += f'<lastmod>{page.updated_at.date() if page.updated_at else datetime.utcnow().date()}</lastmod>\n'
            sitemap += '<changefreq>weekly</changefreq>\n<priority>0.7</priority>\n</url>\n'
        
        # دسته‌بندی‌ها
        categories = Category.query.all()
        for category in categories:
            sitemap += f'<url>\n<loc>{base_url}/category/{category.slug}</loc>\n'
            sitemap += f'<lastmod>{category.created_at.date() if category.created_at else datetime.utcnow().date()}</lastmod>\n'
            sitemap += '<changefreq>weekly</changefreq>\n<priority>0.6</priority>\n</url>\n'
        
        sitemap += '</urlset>'
        
        # ذخیره در فایل
        with open('static/sitemap.xml', 'w', encoding='utf-8') as f:
            f.write(sitemap)
        
        flash('✅ فایل Sitemap با موفقیت تولید شد', 'success')
    except Exception as e:
        flash(f'❌ خطا در تولید Sitemap: {str(e)}', 'danger')
    
    return redirect(url_for('admin_dashboard'))
# 12.15 مدیریت کلمات کلیدی سئو
# ============================================================
# روت‌های ادمین - سئو و کلمات کلیدی
# ============================================================
@app.route('/admin/export/torob')
@admin_required
def admin_export_torob():
    """خروجی برای ترب و باسلام"""
    try:
        # اطمینان از وجود پوشه static
        if not os.path.exists('static'):
            os.makedirs('static')
        
        products = Product.query.filter_by(is_active=True).all()
        
        feed = '<?xml version="1.0" encoding="UTF-8"?>\n'
        feed += '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">\n'
        feed += '<channel>\n'
        feed += '<title>فروشگاه تجهیزات صنعتی</title>\n'
        feed += '<link>' + request.host_url + '</link>\n'
        feed += '<description>لیست محصولات فروشگاه</description>\n'
        
        for product in products:
            feed += '<item>\n'
            feed += f'<g:id>{product.id}</g:id>\n'
            feed += f'<title>{product.title}</title>\n'
            feed += f'<description>{product.short_description or product.description[:200] if product.description else ""}</description>\n'
            
            # تصویر اصلی
            main_image = ProductImage.query.filter_by(product_id=product.id, is_main=True).first()
            if main_image:
                feed += f'<g:image_link>{request.host_url.rstrip("/")}{main_image.image_url}</g:image_link>\n'
            
            feed += f'<g:price>{product.get_final_price()}</g:price>\n'
            feed += f'<g:currency>IRR</g:currency>\n'
            feed += f'<g:availability>{"in_stock" if product.is_in_stock() else "out_of_stock"}</g:availability>\n'
            feed += f'<g:brand>{product.brand.name if product.brand else ""}</g:brand>\n'
            
            if product.category:
                feed += f'<g:category>{product.category.name}</g:category>\n'
            
            feed += f'<link>{request.host_url.rstrip("/")}/product/{product.slug}</link>\n'
            feed += '</item>\n'
        
        feed += '</channel>\n</rss>'
        
        # ذخیره در فایل
        with open('static/torob_feed.xml', 'w', encoding='utf-8') as f:
            f.write(feed)
        
        flash('✅ فید ترب با موفقیت تولید شد', 'success')
    except Exception as e:
        flash(f'❌ خطا در تولید فید ترب: {str(e)}', 'danger')
    
    return redirect(url_for('admin_dashboard'))
    
@app.route('/admin/seo/keywords')
@admin_required
def admin_seo_keywords():
    page = request.args.get('page', 1, type=int)
    search = request.args.get('search', '')
    per_page = 20
    
    query = Keyword.query
    if search:
        query = query.filter(Keyword.keyword.contains(search))
    
    keywords = query.order_by(Keyword.keyword).paginate(page=page, per_page=per_page)
    return render_template('admin/seo_keywords.html', keywords=keywords)

@app.route('/admin/seo/keyword/edit/<int:id>', methods=['GET', 'POST'])
@admin_required
def admin_seo_keyword_edit(id):
    """ویرایش کلمه کلیدی سئو"""
    keyword = Keyword.query.get_or_404(id)
    categories = Category.query.all()
    
    if request.method == 'POST':
        keyword.keyword = request.form.get('keyword', keyword.keyword)
        keyword.category_id = request.form.get('category_id', type=int) or None
        keyword.is_active = request.form.get('is_active') == 'on'
        
        db.session.commit()
        flash('✅ کلمه کلیدی با موفقیت ویرایش شد', 'success')
        return redirect(url_for('admin_seo_keywords'))
    
    return render_template('admin/seo_keyword_edit.html', keyword=keyword, categories=categories)
@app.route('/admin/seo/keywords/add', methods=['GET', 'POST'])
@admin_required
def admin_seo_keywords_add():
    categories = Category.query.all()
    
    if request.method == 'POST':
        keyword_text = request.form.get('keyword')
        category_id = request.form.get('category_id', type=int)
        seo_title = request.form.get('seo_title')
        seo_description = request.form.get('seo_description')
        seo_content = request.form.get('seo_content')
        is_active = request.form.get('is_active') == 'on'
        
        if not keyword_text:
            flash('کلمه کلیدی اجباری است', 'danger')
            return render_template('admin/seo_keywords_add.html', categories=categories)
        
        # بررسی تکراری نبودن
        if Keyword.query.filter_by(keyword=keyword_text).first():
            flash('این کلمه کلیدی قبلاً ثبت شده است', 'danger')
            return render_template('admin/seo_keywords_add.html', categories=categories)
        
        # تولید اسلاگ
        slug = generate_slug(keyword_text, Keyword)
        if Keyword.query.filter_by(slug=slug).first():
            slug = f"{slug}-{secrets.token_hex(4)}"
        
        # ایجاد کلمه کلیدی
        keyword = Keyword(
            keyword=keyword_text,
            slug=slug,
            category_id=category_id,
            is_active=is_active
        )
        db.session.add(keyword)
        db.session.flush()
        
        # ===== تولید خودکار صفحه سئو =====
        # پیدا کردن محصولات مرتبط
        query = Product.query.filter_by(is_active=True)
        if category_id:
            query = query.filter_by(category_id=category_id)
        
        related_products = query.filter(
            db.or_(
                Product.title.contains(keyword_text),
                Product.description.contains(keyword_text),
                Product.seo_keywords.contains(keyword_text)
            )
        ).limit(20).all()
        
        product_ids = ','.join([str(p.id) for p in related_products])
        
        # عنوان و توضیحات
        if not seo_title:
            seo_title = f"خرید {keyword_text} با بهترین قیمت در {setting.site_name or 'بازار آنلاین ۷۲۴'}"
        
        if not seo_description:
            seo_description = f"مشاهده و خرید انواع {keyword_text} با قیمت مناسب و کیفیت عالی از {setting.site_name or 'بازار آنلاین ۷۲۴'}"
        
        if not seo_content:
            seo_content = f"""
            <h1>خرید {keyword_text}</h1>
            <p>بهترین محصولات مربوط به {keyword_text} را در این صفحه مشاهده کنید. {setting.site_name or 'بازار آنلاین ۷۲۴'} مرجع تخصصی تجهیزات صنعتی و ابزارآلات.</p>
            <p>با خرید از {setting.site_name or 'بازار آنلاین ۷۲۴'}، از کیفیت بالا و قیمت مناسب محصولات اطمینان حاصل کنید.</p>
            """
        
        seo_page = SeoPage(
            keyword_id=keyword.id,
            title=seo_title,
            description=seo_description,
            content=seo_content,
            meta_title=seo_title,
            meta_description=seo_description[:150],
            slug=slug,
            product_ids=product_ids
        )
        
        db.session.add(seo_page)
        db.session.commit()
        
        flash(f'✅ کلمه کلیدی و صفحه سئو با موفقیت ایجاد شد', 'success')
        return redirect(url_for('admin_seo_keywords'))
    
    return render_template('admin/seo_keywords_add.html', categories=categories)


@app.route('/admin/seo/keyword/generate/<int:id>')
@admin_required
def admin_seo_keyword_generate(id):
    """بازتولید صفحه سئو برای کلمه کلیدی"""
    keyword = Keyword.query.get_or_404(id)
    
    # پیدا کردن محصولات مرتبط
    query = Product.query.filter_by(is_active=True)
    if keyword.category_id:
        query = query.filter_by(category_id=keyword.category_id)
    
    related_products = query.filter(
        db.or_(
            Product.title.contains(keyword.keyword),
            Product.description.contains(keyword.keyword),
            Product.seo_keywords.contains(keyword.keyword)
        )
    ).limit(20).all()
    
    product_ids = ','.join([str(p.id) for p in related_products])
    
    # به‌روزرسانی صفحه سئو
    seo_page = SeoPage.query.filter_by(keyword_id=keyword.id).first()
    if seo_page:
        seo_page.product_ids = product_ids
        seo_page.updated_at = datetime.utcnow()
        db.session.commit()
        flash('✅ صفحه سئو با موفقیت به‌روزرسانی شد', 'success')
    else:
        flash('❌ صفحه سئو یافت نشد', 'danger')
    
    return redirect(url_for('admin_seo_keywords'))


@app.route('/admin/seo/keyword/delete/<int:id>', methods=['POST'])
@admin_required
def admin_seo_keyword_delete(id):
    keyword = Keyword.query.get_or_404(id)
    
    # حذف صفحه سئو مرتبط
    seo_page = SeoPage.query.filter_by(keyword_id=keyword.id).first()
    if seo_page:
        db.session.delete(seo_page)
    
    db.session.delete(keyword)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'کلمه کلیدی با موفقیت حذف شد'})



@app.route('/admin/robots')
@admin_required
def admin_robots():
    """مدیریت فایل robots.txt"""
    robots_path = os.path.join('static', 'robots.txt')
    
    if request.method == 'POST':
        content = request.form.get('content')
        with open(robots_path, 'w', encoding='utf-8') as f:
            f.write(content)
        flash('✅ فایل robots.txt با موفقیت ذخیره شد', 'success')
        return redirect(url_for('admin_robots'))
    
    content = ''
    if os.path.exists(robots_path):
        with open(robots_path, 'r', encoding='utf-8') as f:
            content = f.read()
    else:
        content = """User-agent: *
Allow: /
Disallow: /admin/
Disallow: /cart/
Disallow: /checkout/
Sitemap: {}/sitemap.xml
""".format(request.url_root.rstrip('/'))
    
    return render_template('admin/robots.html', content=content)


@app.route('/admin/robots/save', methods=['POST'])
@admin_required
def admin_robots_save():
    """ذخیره فایل robots.txt"""
    content = request.form.get('content')
    robots_path = os.path.join('static', 'robots.txt')
    
    with open(robots_path, 'w', encoding='utf-8') as f:
        f.write(content)
    
    flash('✅ فایل robots.txt با موفقیت ذخیره شد', 'success')
    return redirect(url_for('admin_robots'))
    


# 12.17 مدیریت تنظیمات سایت
# ============================================================
# روت‌های ادمین - تنظیمات، بنرها، کوپن‌ها
# ============================================================

@app.route('/admin/settings', methods=['GET', 'POST'])
@admin_required
def admin_settings():
    setting = Setting.query.first()
    if not setting:
        setting = Setting()
        db.session.add(setting)
        db.session.commit()
    
    # دریافت شبکه‌های اجتماعی
    social_media = {}
    if setting.social_media:
        try:
            social_media = json.loads(setting.social_media)
        except:
            social_media = {}
    
    if request.method == 'POST':
        # اطلاعات اصلی
        setting.site_name = request.form.get('site_name', setting.site_name)
        setting.site_email = request.form.get('site_email', setting.site_email)
        setting.site_phone = request.form.get('site_phone', setting.site_phone)
        setting.site_address = request.form.get('site_address', setting.site_address)
        setting.footer_text = request.form.get('footer_text', setting.footer_text)
        setting.currency = request.form.get('currency', 'تومان')
        setting.tax_percent = request.form.get('tax_percent', type=int, default=0)
        setting.maintenance_mode = request.form.get('maintenance_mode') == 'on'
        
        # سئو
        setting.meta_title = request.form.get('meta_title', setting.meta_title)
        setting.meta_description = request.form.get('meta_description', setting.meta_description)
        setting.seo_keywords = request.form.get('seo_keywords', setting.seo_keywords)
        
        # شبکه‌های اجتماعی
        social_data = {
            'instagram': request.form.get('social_instagram', ''),
            'telegram': request.form.get('social_telegram', ''),
            'whatsapp': request.form.get('social_whatsapp', ''),
            'linkedin': request.form.get('social_linkedin', '')
        }
        setting.social_media = json.dumps(social_data, ensure_ascii=False)
        
        # آپلود لوگو
        logo = request.files.get('site_logo')
        if logo and logo.filename:
            logo_url = upload_image(logo, 'settings')
            if logo_url:
                setting.site_logo = logo_url
        
        # آپلود فاویکون
        favicon = request.files.get('site_favicon')
        if favicon and favicon.filename:
            favicon_url = upload_image(favicon, 'settings')
            if favicon_url:
                setting.site_favicon = favicon_url
        
        db.session.commit()
        flash('✅ تنظیمات با موفقیت ذخیره شد', 'success')
        return redirect(url_for('admin_settings'))
    
    return render_template('admin/settings.html', setting=setting, social_media=social_media)


@app.route('/admin/banners')
@admin_required
def admin_banners():
    banners = Banner.query.order_by(Banner.order).all()
    return render_template('admin/banners.html', banners=banners)


@app.route('/admin/banners/add', methods=['GET', 'POST'])
@admin_required
def admin_banner_add():
    if request.method == 'POST':
        title = request.form.get('title')
        link = request.form.get('link')
        position = request.form.get('position', 'home_top')
        order = request.form.get('order', type=int, default=0)
        is_active = request.form.get('is_active') == 'on'
        start_date = request.form.get('start_date')
        end_date = request.form.get('end_date')
        
        # آپلود تصویر
        image = request.files.get('image')
        if not image or not image.filename:
            flash('تصویر بنر اجباری است', 'danger')
            return render_template('admin/banner_add.html')
        
        image_url = upload_image(image, 'banners')
        if not image_url:
            flash('خطا در آپلود تصویر', 'danger')
            return render_template('admin/banner_add.html')
        
        banner = Banner(
            title=title,
            image=image_url,
            link=link,
            position=position,
            order=order,
            is_active=is_active
        )
        
        if start_date:
            banner.start_date = datetime.fromisoformat(start_date)
        if end_date:
            banner.end_date = datetime.fromisoformat(end_date)
        
        db.session.add(banner)
        db.session.commit()
        
        flash('✅ بنر با موفقیت اضافه شد', 'success')
        return redirect(url_for('admin_banners'))
    
    return render_template('admin/banner_add.html')


@app.route('/admin/banner/delete/<int:id>', methods=['POST'])
@admin_required
def admin_banner_delete(id):
    banner = Banner.query.get_or_404(id)
    
    # حذف فایل تصویر
    if banner.image:
        filepath = os.path.join('static', banner.image.lstrip('/'))
        if os.path.exists(filepath):
            os.remove(filepath)
    
    db.session.delete(banner)
    db.session.commit()
    
    return jsonify({'status': 'success', 'message': 'بنر با موفقیت حذف شد'})


@app.route('/admin/coupons')
@admin_required
def admin_coupons():
    coupons = Coupon.query.order_by(Coupon.created_at.desc()).all()
    return render_template('admin/coupons.html', coupons=coupons)


@app.route('/admin/coupons/add', methods=['GET', 'POST'])
@admin_required
def admin_coupon_add():
    if request.method == 'POST':
        code = request.form.get('code', '').strip().upper()
        discount_type = request.form.get('discount_type')
        discount_value = request.form.get('discount_value', type=int)
        min_order_amount = request.form.get('min_order_amount', type=int, default=0)
        max_discount = request.form.get('max_discount', type=int)
        usage_limit = request.form.get('usage_limit', type=int, default=0)
        start_date = request.form.get('start_date')
        end_date = request.form.get('end_date')
        is_active = request.form.get('is_active') == 'on'
        
        if not code or not discount_value:
            flash('کد تخفیف و مقدار تخفیف اجباری هستند', 'danger')
            return render_template('admin/coupon_add.html')
        
        if Coupon.query.filter_by(code=code).first():
            flash('این کد تخفیف قبلاً ثبت شده است', 'danger')
            return render_template('admin/coupon_add.html')
        
        coupon = Coupon(
            code=code,
            discount_type=discount_type,
            discount_value=discount_value,
            min_order_amount=min_order_amount,
            max_discount=max_discount or 0,
            usage_limit=usage_limit or None,
            is_active=is_active
        )
        
        if start_date:
            coupon.start_date = datetime.fromisoformat(start_date)
        if end_date:
            coupon.end_date = datetime.fromisoformat(end_date)
        
        db.session.add(coupon)
        db.session.commit()
        
        flash('✅ کوپن تخفیف با موفقیت ایجاد شد', 'success')
        return redirect(url_for('admin_coupons'))
    
    return render_template('admin/coupon_add.html')


@app.route('/admin/coupon/delete/<int:id>', methods=['POST'])
@admin_required
def admin_coupon_delete(id):
    coupon = Coupon.query.get_or_404(id)
    db.session.delete(coupon)
    db.session.commit()
    return jsonify({'status': 'success', 'message': 'کوپن با موفقیت حذف شد'})


@app.route('/admin/coupon/status/<int:id>', methods=['POST'])
@admin_required
def admin_coupon_status(id):
    coupon = Coupon.query.get_or_404(id)
    coupon.is_active = not coupon.is_active
    db.session.commit()
    return jsonify({
        'status': 'success', 
        'is_active': coupon.is_active,
        'message': 'وضعیت کوپن تغییر کرد'
    })
# ============================================
# 13. مدیریت خطاها
# ============================================
@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/contact', methods=['GET', 'POST'])
def contact():
    if request.method == 'POST':
        name = request.form.get('name')
        email = request.form.get('email')
        phone = request.form.get('phone')
        subject = request.form.get('subject')
        message = request.form.get('message')
        
        # ذخیره در دیتابیس
        contact = ContactMessage(
            name=name,
            email=email,
            phone=phone,
            subject=subject,
            message=message
        )
        db.session.add(contact)
        db.session.commit()
        
        flash('✅ پیام شما با موفقیت ارسال شد. به زودی با شما تماس خواهیم گرفت.', 'success')
        return redirect(url_for('contact'))
    
    return render_template('contact.html')

@app.route('/rules')
def rules():
    return render_template('rules.html')

@app.route('/privacy')
def privacy():
    return render_template('privacy.html')
@app.route('/api/stats')
def api_stats():
    """API برای دریافت آمار لحظه‌ای"""
    from datetime import datetime, timedelta
    
    today = datetime.utcnow().date()
    today_start = datetime(today.year, today.month, today.day)
    
    # بازدید امروز
    today_visits = Visit.query.filter(Visit.created_at >= today_start).count()
    
    # کاربران آنلاین (در 5 دقیقه اخیر)
    five_min_ago = datetime.utcnow() - timedelta(minutes=5)
    online_users = Visit.query.filter(Visit.created_at >= five_min_ago).distinct(Visit.ip).count()
    
    return jsonify({
        'today_visits': to_persian_numbers(today_visits),
        'online_users': to_persian_numbers(online_users)
    })
    
@app.errorhandler(404)
def not_found(error):
    return render_template('errors/404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    app.logger.error(f"Internal Server Error: {str(error)}")
    return render_template('errors/500.html'), 500

@app.errorhandler(403)
def forbidden(error):
    return render_template('errors/403.html'), 403

# 13.1 لاگ‌گیری خطاها
@app.errorhandler(Exception)
def handle_exception(e):
    app.logger.error(f"Unhandled Exception: {str(e)}", exc_info=True)
    return render_template('errors/500.html'), 500

# ============================================
# 14. تولید Sitemap خودکار
# ============================================
@app.route('/sitemap.xml')
def sitemap():
    generate_sitemap()
    return send_file('static/sitemap.xml', mimetype='application/xml')

# ============================================
# 15. ایجاد جداول و داده‌های اولیه
# ============================================
@app.before_request
def create_tables():
    db.create_all()
    
    # ایجاد ادمین پیش‌فرض
    if not User.query.filter_by(role='admin').first():
# جایی که ادمین ساخته میشه
        admin = User(
            username='admin',
            email='admin@onlinemarket724.ir',
            full_name='مدیر فروشگاه',
            phone='09123456789',  # ← یه شماره پیش‌فرض بذار
            role='admin',
            is_active=True
        )
        admin.set_password('admin123')
        db.session.add(admin)
        db.session.commit()
        print("✅ ادمین ایجاد شد: admin / admin123")
    
    # ایجاد تنظیمات پیش‌فرض
    if not Setting.query.first():
        setting = Setting(
            site_name='بازار آنلاین ۷۲۴',
            site_email='info@onlinemarket724.ir',
            site_phone='۰۲۱-۱۲۳۴۵۶۷۸',
            site_address='تهران، خیابان صنعت، پلاک ۱۲',
            currency='تومان',
            meta_title='بازار آنلاین ۷۲۴ | مرجع تخصصی تجهیزات صنعتی و ابزارآلات',
            meta_description='خرید انواع تجهیزات صنعتی، قطعات الکترونیک، ابزارآلات و ماشین‌آلات با بهترین قیمت و کیفیت از بازار آنلاین ۷۲۴',
            seo_keywords='بازار آنلاین 724, onlinemarket724, تجهیزات صنعتی, قطعات صنعتی, ابزارآلات, ماشین‌آلات',
            footer_text='بازار آنلاین ۷۲۴ - مرجع تخصصی تجهیزات صنعتی و ابزارآلات',
            social_media=json.dumps({
                'instagram': 'https://instagram.com/onlinemarket724',
                'telegram': 'https://t.me/onlinemarket724',
                'whatsapp': 'https://wa.me/989123456789',
                'linkedin': 'https://linkedin.com/company/onlinemarket724',
                'aparat': 'https://aparat.com/onlinemarket724'
            })
        )
        db.session.add(setting)
        db.session.commit()
        print("✅ تنظیمات سایت ایجاد شد")
# ============================================
# 16. اجرای برنامه
# ============================================
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        
        # شروع بک‌آپ خودکار
        scheduler = BackgroundScheduler()
        scheduler.add_job(
            func=lambda: create_backup('full', 'بک‌آپ خودکار روزانه'),
            trigger='interval',
            hours=24
        )
        scheduler.start()
    
    app.run(debug=True, host='0.0.0.0', port=5000)
