import os
import random
import string
import time as time_module
from datetime import datetime, timezone, time, timedelta
from flask import Flask, render_template, request, redirect, url_for, flash, send_file, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.utils import secure_filename
import pandas as pd
from flask import render_template_string

app = Flask(__name__)
app.secret_key = 'arabiata_online_secret_key_123'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///arabiata_online.db'
app.config['UPLOAD_FOLDER'] = os.path.join(app.root_path, 'static/uploads')
app.config['TRANSFERS_FOLDER'] = os.path.join(app.root_path, 'static/transfers')  # مجلد صور التحويلات المنفصل
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16 MB max
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'webp'}

os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['TRANSFERS_FOLDER'], exist_ok=True)  # إنشاء مجلد التحويلات تلقائياً

db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def delete_uploaded_file(filename):
    if filename and filename != 'default_food.png':
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        if os.path.exists(file_path):
            try:
                os.remove(file_path)
            except OSError:
                pass

# --- Models ---
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password_hash = db.Column(db.String(200), nullable=False)
    role = db.Column(db.String(20), default='staff')
    
    can_view_dashboard = db.Column(db.Boolean, default=True)
    can_view_reports = db.Column(db.Boolean, default=False)
    can_manage_branches = db.Column(db.Boolean, default=False)
    can_manage_menu = db.Column(db.Boolean, default=False)
    can_manage_offers = db.Column(db.Boolean, default=False)
    can_manage_users = db.Column(db.Boolean, default=False)
    can_manage_settings = db.Column(db.Boolean, default=False)      # الإعدادات الشاملة
    can_cancel_orders = db.Column(db.Boolean, default=False)        # إلغاء الطلبات
    can_manage_system_date = db.Column(db.Boolean, default=False)   # تاريخ السيستم
    can_export_menu = db.Column(db.Boolean, default=False)          # استخراج المنيو

    @property
    def is_staff_member(self):
        return self.role in ['admin', 'staff', 'employee', 'manager']

class Branch(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    phone = db.Column(db.String(20), nullable=False)
    wallet_number = db.Column(db.String(20), nullable=True)
    latitude = db.Column(db.Float, nullable=True)   # خط العرض للفرع
    longitude = db.Column(db.Float, nullable=True)  # خط الطول للفرع
    categories = db.relationship('Category', backref='branch', lazy=True, cascade="all, delete-orphan")

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    branch_id = db.Column(db.Integer, db.ForeignKey('branch.id'), nullable=False)
    items = db.relationship('MenuItem', backref='category', lazy=True, cascade="all, delete-orphan")

class MenuItem(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    price = db.Column(db.Float, nullable=False)
    image = db.Column(db.String(200), nullable=True, default='default_food.png')
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False)
    
class RestaurantBanner(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    image_name = db.Column(db.String(200), nullable=False)

class SpecialOffer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    image_name = db.Column(db.String(200), nullable=False)

class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    customer_name = db.Column(db.String(100), nullable=False)
    customer_phone = db.Column(db.String(20), nullable=False)
    branch_id = db.Column(db.Integer, db.ForeignKey('branch.id'), nullable=False)
    total_price = db.Column(db.Float, nullable=False)
    payment_proof = db.Column(db.String(200), nullable=False)
    status = db.Column(db.String(20), default='New')
    pickup_code = db.Column(db.String(50), nullable=True)
    shift_active = db.Column(db.Boolean, default=True)
    edit_reason = db.Column(db.String(300), nullable=True)
    reject_reason = db.Column(db.String(300), nullable=True)
    customer_comment = db.Column(db.String(500), nullable=True)
    scheduled_pickup_time = db.Column(db.String(20), nullable=True)  # <--- الحقل الجديد لوقت الاستلام الاختياري
    created_at = db.Column(db.DateTime, default=datetime.now)
    branch = db.relationship('Branch')
    order_items = db.relationship('OrderItem', backref='order', lazy=True, cascade="all, delete-orphan")

class OrderItem(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False)
    item_name = db.Column(db.String(100), nullable=False)
    price = db.Column(db.Float, nullable=False)
    quantity = db.Column(db.Integer, nullable=False)

class Setting(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    key = db.Column(db.String(50), unique=True, nullable=False)
    value = db.Column(db.String(200), nullable=False)

from flask import redirect, request, session

from flask import session
from translate import translations  # استيراد ملف الترجمة

@app.context_processor
def inject_lang():
    lang = session.get('lang', 'ar') # اللغة الافتراضية عربية
    return dict(t=translations.get(lang, translations['ar']), current_lang=lang)

# مسار تغيير اللغة
@app.route('/set_language/<lang>')
def set_language(lang):
    if lang in ['ar', 'en']:
        session['lang'] = lang
    return redirect(request.referrer or url_for('index'))
@login_manager.user_loader
def load_user(user_id):
    return db.session.get(User, int(user_id))

def get_current_shift_range():
    # استخدام تاريخ النظام المحدد إذا وجد، وإلا يتم الاعتماد على تاريخ اليوم الافتراضي
    sys_setting = Setting.query.filter_by(key='system_start_date').first()
    system_start_date = datetime.strptime(sys_setting.value, '%Y-%m-%d').date() if sys_setting else None

    now = datetime.now()
    if now.time() < time(6, 0):
        shift_start = datetime.combine(now.date() - timedelta(days=1), time(6, 0))
    else:
        shift_start = datetime.combine(now.date(), time(6, 0))
    
    # إذا كان تاريخ بداية النظام بعد تاريخ بداية الوردية الحالي، نجعل بداية الوردية تبدأ من تاريخ النظام
    if system_start_date and shift_start.date() < system_start_date:
        shift_start = datetime.combine(system_start_date, time(6, 0))

    shift_end = shift_start + timedelta(days=1)
    return shift_start, shift_end

# تمرير تاريخ النظام لجميع القوالب تلقائياً
@app.context_processor
def inject_system_date():
    # datetime.now() تأخذ التوقيت المحلي من نظام التشغيل مباشرة
    local_now = datetime.now()
    return {
        'system_date': local_now.strftime('%Y-%m-%d'),
        'system_time': local_now.strftime('%H:%M:%S'),
        'full_system_datetime': local_now
    }

# --- Client Routes ---
@app.route('/')
def index():
    banners = RestaurantBanner.query.all()
    return render_template('index.html', banners=banners)

@app.route('/offers')
def offers():
    special_offers = SpecialOffer.query.all()
    return render_template('offers.html', offers=special_offers)

from math import radians, sin, cos, sqrt, atan2

def calculate_distance(lat1, lon1, lat2, lon2):
    # حساب المسافة بالكيلومتر بين نقطتين (معادلة Haversine)
    R = 6371.0
    lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return R * c

@app.route('/create_order', methods=['GET', 'POST'])
def create_order():
    branches = Branch.query.all()
    if request.method == 'POST':
        customer_name = request.form.get('customer_name', '').strip()
        customer_phone = request.form.get('customer_phone', '').strip()
        user_lat = request.form.get('user_lat', type=float)
        user_lon = request.form.get('user_lon', type=float)
        
        # 1. التحقق الصارم من وجود الاسم ورقم التليفون
        if not customer_name or not customer_phone:
            flash("يرجى إدخال اسم العميل ورقم الموبايل أولاً!", "danger")
            return redirect(url_for('create_order'))
            
        # 2. التحقق الصارم من وجود الإحداثيات (اللوكيشن)
        if user_lat is None or user_lon is None:
            flash("يرجى تحديد الموقع الجغرافي (اللوكيشن) للتحقق من النطاق!", "danger")
            return redirect(url_for('create_order'))
            
        closest_branch = None
        min_distance = float('inf')
        
        for b in branches:
            if b.latitude and b.longitude:
                dist = calculate_distance(user_lat, user_lon, b.latitude, b.longitude) # بالكيلومتر
                if dist < min_distance:
                    min_distance = dist
                    closest_branch = b
        
        # 3. التحقق من أن العميل داخل نطاق الـ 1 كيلومتر
        if closest_branch and min_distance <= 1.0:
            branch_id = closest_branch.id
        else:
            flash("عذراً، أنت خارج نطاق تغطية فروعنا (أبعد من 1 كيلومتر). نعتذر لعدم توفر خدمة التوصيل لمنطقتك حالياً.", "danger")
            return redirect(url_for('create_order'))
            
        # لو كل الشروط تمت بنجاح، نحفظهم في الجلسة (Session) ونوجهه لصفحة المنيو/الطلب
        session['customer_name'] = customer_name
        session['customer_phone'] = customer_phone
        session['branch_id'] = branch_id
            
        return redirect(url_for('view_menu', branch_id=branch_id))
        
    return render_template('create_order.html')

@app.route('/menu/<int:branch_id>', methods=['GET', 'POST'])
def view_menu(branch_id):
    branch = db.session.get(Branch, branch_id)
    if not branch:
        flash("الفرع غير موجود", "danger")
        return redirect(url_for('create_order'))

    categories = Category.query.filter_by(branch_id=branch_id).all()
    
    payment_number = branch.wallet_number
    if not payment_number:
        gen_setting = Setting.query.filter_by(key='payment_number').first()
        payment_number = gen_setting.value if gen_setting else "غير محدد"

    customer_name = request.args.get('name', '') or session.get('customer_name', '')
    customer_phone = request.args.get('phone', '') or session.get('customer_phone', '')

    if request.method == 'POST':
        c_name = request.form.get('customer_name')
        c_phone = request.form.get('customer_phone')
        file = request.files.get('payment_proof')
        c_comment = request.form.get('customer_comment', '').strip()
        scheduled_pickup_time = request.form.get('scheduled_pickup_time', '').strip() # <--- استقبال الوقت
        
        total = 0.0
        selected_items_list = []

        for cat in categories:
            for item in cat.items:
                qty = int(request.form.get(f'qty_{item.id}', 0))
                if qty > 0:
                    total += item.price * qty
                    selected_items_list.append({
                        'name': item.name,
                        'price': item.price,
                        'qty': qty
                    })

        if total == 0:
            flash("يرجى اختيار صنف واحد على الأقل!", "danger")
            return redirect(url_for('view_menu', branch_id=branch_id, name=c_name, phone=c_phone))

        if not file or file.filename == '':
            flash("يرجى إرفاق صورة إيصال التحويل!", "danger")
            return redirect(url_for('view_menu', branch_id=branch_id, name=c_name, phone=c_phone))

        if file and allowed_file(file.filename):
            # اسم الملف الفريد
            filename = secure_filename(f"{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}")
            
            # الحفظ الإلزامي في فولدر التحويلات فقط
            filepath = os.path.join(app.config['TRANSFERS_FOLDER'], filename)
            file.save(filepath)

            new_order = Order(
                customer_name=c_name,
                customer_phone=c_phone,
                branch_id=branch_id,
                total_price=total,
                payment_proof=filename, # تخزين اسم الملف فقط في قاعدة البيانات
                shift_active=True,
                customer_comment=c_comment,
                scheduled_pickup_time=scheduled_pickup_time if scheduled_pickup_time else 'فوراً / في أسرع وقت'
            )
            db.session.add(new_order)
            db.session.flush() # لتوليد الـ ID الخاص بالطلب الجديد

            # 1. حفظ الأصناف أولاً في قاعدة البيانات
            for item_data in selected_items_list:
                order_item = OrderItem(
                    order_id=new_order.id,
                    item_name=item_data['name'],
                    price=item_data['price'],
                    quantity=item_data['qty']
                )
                db.session.add(order_item)

            # 2. حفظ التغييرات نهائياً
            db.session.commit()
            
            # 3. إرسال الرسالة والتوجيه مرة واحدة فقط في النهاية
            flash(f"تم إرسال طلبك بنجاح! رقم المتابعة: {c_phone}", "success")
            return redirect(url_for('track_order', phone=c_phone))
        else:
            flash("نوع الملف غير مدعوم، يرجى إرفاق صورة صالحة.", "danger")

    return render_template('menu.html', branch=branch, categories=categories, payment_number=payment_number, customer_name=customer_name, customer_phone=customer_phone)
            
@app.route('/track', methods=['GET', 'POST'])
def track_order():
    phone = request.args.get('phone', '')
    orders = []
    if request.method == 'POST':
        phone = request.form.get('phone')
    if phone:
        orders = Order.query.filter_by(customer_phone=phone).order_by(Order.created_at.desc()).all()
    return render_template('track.html', orders=orders, phone=phone)

# --- Auth & Dashboard Routes ---
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form.get('username', '').strip()
        password = request.form.get('password', '').strip()
        user = User.query.filter_by(username=username).first()
        if user and check_password_hash(user.password_hash, password):
            login_user(user)
            if user.is_staff_member:
                return redirect(url_for('dashboard'))
            return redirect(url_for('index'))
            
        flash("اسم المستخدم أو كلمة السر غير صحيحة", "danger")
    return render_template('login.html')

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))

@app.route('/dashboard')
@login_required
def dashboard():
    
    if not current_user.is_staff_member or not current_user.can_view_dashboard:
        flash("غير مصرح لك بالدخول إلى لوحة التحكم.", "danger")
        return redirect(url_for('index'))

    branch_id = request.args.get('branch_id', type=int)
    status = request.args.get('status', '').strip()
    selected_date = request.args.get('date', '').strip()
    search_query = request.args.get('search', '').strip()

    branches = Branch.query.all()
    shift_start, shift_end = get_current_shift_range()

    new_orders_query = Order.query.filter(
        Order.status == 'New',
        Order.created_at >= shift_start,
        Order.created_at < shift_end
    )
    
    # تم تعديل هذا الاستعلام لاستبعاد الأوردات المؤرشفة حتى تختفي وتفضي تماماً عند إنهاء اليوم
    prev_orders_query = Order.query.filter(
        Order.status != 'archived',
        (Order.status != 'New') | (Order.created_at < shift_start)
    )

    if branch_id:
        new_orders_query = new_orders_query.filter(Order.branch_id == branch_id)
        prev_orders_query = prev_orders_query.filter(Order.branch_id == branch_id)

    if status:
        prev_orders_query = prev_orders_query.filter(Order.status == status)

    if selected_date:
        try:
            filter_date = datetime.strptime(selected_date, '%Y-%m-%d').date()
            new_orders_query = new_orders_query.filter(db.func.date(Order.created_at) == filter_date)
            prev_orders_query = prev_orders_query.filter(db.func.date(Order.created_at) == filter_date)
        except ValueError:
            pass

    if search_query:
        search_filter = (
            Order.customer_name.ilike(f"%{search_query}%") |
            Order.customer_phone.ilike(f"%{search_query}%") |
            Order.pickup_code.ilike(f"%{search_query}%")
        )
        new_orders_query = new_orders_query.filter(search_filter)
        prev_orders_query = prev_orders_query.filter(search_filter)

    new_orders = new_orders_query.order_by(Order.created_at.asc()).all()
    previous_orders = prev_orders_query.order_by(Order.created_at.desc()).all()

    return render_template(
        'dashboard.html',
        branches=branches,
        new_orders=new_orders,
        previous_orders=previous_orders,
        selected_branch=branch_id,
        selected_status=status,
        selected_date=selected_date,
        search_query=search_query
    )

# --- دالة وراوت إدارة تاريخ النظام ---

@app.route('/system-date', methods=['GET', 'POST'])
@login_required
def system_date():
    if current_user.role != 'admin' and not current_user.can_manage_branches:
        flash("غير مصرح لك بتعديل تاريخ النظام.", "danger")
        return redirect(url_for('dashboard'))
        
    setting = Setting.query.filter_by(key='system_start_date').first()
    
    if request.method == 'POST':
        selected_date = request.form.get('system_date')
        if selected_date:
            if not setting:
                setting = Setting(key='system_start_date', value=selected_date)
                db.session.add(setting)
            else:
                setting.value = selected_date
            db.session.commit()
            flash('تم تحديث تاريخ بداية النظام بنجاح!', 'success')
            return redirect(url_for('system_date'))
            
    current_date = setting.value if setting and setting.value else datetime.now().strftime('%Y-%m-%d')
    
    # هذه الصفحة ستظهر مباشرة من هنا دون الحاجة لملف HTML خارجي لنتاكد هل المشكلة من ملفات الـ templates أم لا
    html_content = """
    <!DOCTYPE html>
    <html lang="ar" dir="rtl">
    <head>
        <meta charset="UTF-8">
        <title>اختبار تاريخ النظام</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/rtl.min.css">
    </head>
    <body class="bg-dark text-white p-5 text-center">
        <div class="container">
            <h1 class="text-warning">⚠️ صفحة الاختبار المباشر تعمل بنجاح!</h1>
            <h3 class="text-info my-4">التاريخ الحالي المعتمد هو: {{ current_date }}</h3>
            <form method="POST" class="card p-4 bg-light text-dark col-md-6 mx-auto">
                <div class="mb-3">
                    <label class="fw-bold">اختر التاريخ الجديد:</label>
                    <input type="date" name="system_date" value="{{ current_date }}" class="form-control text-center" required>
                </div>
                <button type="submit" class="btn btn-danger btn-lg w-100">حفظ التاريخ فوراً</button>
            </form>
            <br>
            <a href="{{ url_for('dashboard') }}" class="btn btn-secondary">العودة للرئيسية</a>
        </div>
    </body>
    </html>
    """
    
    return render_template_string(html_content, current_date=current_date)
    
    return render_template('system_date.html', current_date=current_date)

@app.route('/clear_screen_orders', methods=['POST'])
def clear_screen_orders():
    if not current_user.is_authenticated:
        return redirect(url_for('login'))
    
    try:
        # أرشفة جميع الطلبات التي ليس حالتها مؤرشفة أو ملغية/مرفوضة لكي تختفي من لوحة التحكم الشاشة الحالية
        orders_to_clear = Order.query.filter(Order.status != 'archived').all()
        for order in orders_to_clear:
            order.status = 'archived'
        
        db.session.commit()
        flash('تم تفريغ الشاشة بنجاح ونقل الطلبات للتقارير دون تغيير تاريخ النظام!', 'success')
    except Exception as e:
        flash(f'حدث خطأ أثناء تفريغ الشاشة: {str(e)}', 'danger')
        
    return redirect(url_for('dashboard'))

@app.route('/end_day', methods=['POST', 'GET'])
def end_day():
    # دالة فارغة لضمان عدم حدوث خطأ ولإتمام تفريغ الشاشة بنجاح
    flash('تم تفريغ الشاشة بنجاح ونقل الطلبات للتقارير دون تغيير التاريخ.', 'success')
    return redirect(url_for('dashboard'))
    
@app.route('/order/accept/<int:order_id>')
@login_required
def accept_order(order_id):
    if not current_user.is_staff_member:
        return "غير مصرح", 403
    order = db.session.get(Order, order_id)
    if order:
        today_str = datetime.now().strftime("%Y%m%d")
        order.pickup_code = f"{today_str}-{order.branch_id}-{order.id}"
        order.status = 'Accepted'
        db.session.commit()
        flash("تم ارسال الاوردر للفرع وتوليد كود الاستلام بنجاح!", "success")
    return redirect(url_for('dashboard'))

@app.route('/order/complete/<int:order_id>')
@login_required
def complete_order(order_id):
    if not current_user.is_staff_member:
        return "غير مصرح", 403
    order = db.session.get(Order, order_id)
    if order:
        order.status = 'Completed'
        db.session.commit()
        flash("تم تسليم الطلب بنجاح!", "success")
    return redirect(url_for('dashboard'))

@app.route('/order/reject/<int:order_id>', methods=['POST'])
@login_required
def reject_order(order_id):
    if not current_user.is_staff_member:
        return "غير مصرح", 403
    
    reason = request.form.get('reject_reason', '').strip()
    order = db.session.get(Order, order_id)
    if order:
        order.status = 'Rejected'
        order.reject_reason = reason if reason else "لم يتم توضيح السبب"
        db.session.commit()
        flash("تم رفض الطلب وإرسال السبب بنجاح!", "warning")
    return redirect(url_for('dashboard'))

# --- Admin Order Control ---
@app.route('/admin/order/delete/<int:order_id>')
@login_required
def admin_delete_order(order_id):
    if current_user.role != 'admin' and not current_user.can_cancel_orders:
        flash("غير مصرح لك بهذه العملية.", "danger")
        return redirect(url_for('dashboard'))
    
    order = db.session.get(Order, order_id)
    if order:
        delete_uploaded_file(order.payment_proof)
        db.session.delete(order)
        db.session.commit()
        flash("تم حذف الطلب نهائياً بنجاح!", "success")
    return redirect(url_for('dashboard'))

@app.route('/admin/order/cancel_with_reason/<int:order_id>', methods=['POST'])
@login_required
def admin_cancel_order(order_id):
    if current_user.role != 'admin' and not current_user.can_cancel_orders:
        flash("غير مصرح لك بهذه العملية.", "danger")
        return redirect(url_for('dashboard'))
    
    reason = request.form.get('edit_reason', '').strip()
    order = db.session.get(Order, order_id)
    if order:
        order.status = 'Cancelled'
        order.edit_reason = f"تم الإلغاء بواسطة {current_user.username}. السبب: {reason}"
        db.session.commit()
        flash(f"تم إلغاء الطلب بنجاح. السبب: {reason}", "warning")
    return redirect(url_for('dashboard'))

@app.route('/api/check_new_orders')
def check_new_orders():
    shift_start, shift_end = get_current_shift_range()
    new_orders = Order.query.filter(
        Order.status == 'New',
        Order.created_at >= shift_start,
        Order.created_at < shift_end
    ).order_by(Order.created_at.desc()).all()

    orders_data = [{'id': o.id, 'customer_name': o.customer_name} for o in new_orders]
    return jsonify({
        'count': len(new_orders),
        'orders': orders_data
    })

# --- System Date Settings Route ---
@app.route('/admin/system-date', methods=['GET', 'POST'])
@login_required

# دالة مساعدة عامة لجلب تاريخ السيستم الحالي في أي وقت
def get_current_system_date():
    setting = Setting.query.filter_by(key='system_start_date').first()
    if setting and setting.value:
        try:
            return datetime.strptime(setting.value.strip(), '%Y-%m-%d').date()
        except ValueError:
            pass
    return datetime.now().date() # قيمة افتراضية لو لم يتم تحديد التاريخ بعد

# جعل تاريخ السيستم ظاهراً تلقائياً في الشريط العلوي (base.html) لكل الصفحات
@app.context_processor
def inject_system_date():
    setting = Setting.query.filter_by(key='system_start_date').first()
    sys_date = setting.value if setting else datetime.now().strftime('%Y-%m-%d')
    return dict(current_system_date=sys_date)


# --- Admin Settings & Reports ---
@app.route('/admin/settings', methods=['GET', 'POST'])
@login_required
def admin_settings():
    if current_user.role != 'admin' and not (current_user.can_manage_branches or current_user.can_manage_menu or current_user.can_manage_offers or current_user.can_manage_users or current_user.can_view_reports or current_user.can_manage_settings):
        flash("غير مصرح لك بالدخول إلى لوحة التحكم والتحكم في الإعدادات.", "danger")
        return redirect(url_for('index'))
    
    # جلب تاريخ السيستم الحالي من قاعدة البيانات لعرضه
    setting = Setting.query.filter_by(key='system_start_date').first()
    system_start_date = setting.value if setting and setting.value else datetime.now().strftime('%Y-%m-%d')
    
    if request.method == 'POST':
        action = request.form.get('action')
        
        # معالجة حفظ وتحديث تاريخ النظام
        if action == 'update_system_date':
            system_date_val = request.form.get('system_start_date')
            if system_date_val:
                if not setting:
                    setting = Setting(key='system_start_date', value=system_date_val)
                    db.session.add(setting)
                else:
                    setting.value = system_date_val
                db.session.commit()
                flash('تم تحديث تاريخ بداية النظام بنجاح!', 'success')
                return redirect(url_for('admin_settings'))
        
        elif action == 'add_branch':
            if current_user.role != 'admin' and not current_user.can_manage_branches:
                flash("غير مصرح لك بإضافة فروع.", "danger")
            else:
                name = request.form.get('branch_name', '').strip()
                phone = request.form.get('branch_phone', '').strip()
                wallet = request.form.get('branch_wallet', '').strip()
                
                # استقبال وفصل الإحداثيات الموحدة للفرع الجديد
                raw_coords = request.form.get('branch_coords', '').strip()
                lat, lon = None, None
                if raw_coords:
                    try:
                        parts = [p.strip() for p in raw_coords.split(',')]
                        lat = float(parts[0])
                        lon = float(parts[1])
                    except (ValueError, IndexError):
                        pass

                if name and phone:
                    db.session.add(Branch(
                        name=name, 
                        phone=phone, 
                        wallet_number=wallet,
                        latitude=lat,
                        longitude=lon
                    ))
                    db.session.commit()
                    flash("تم إضافة الفرع بنجاح!", "success")

        elif action == 'add_category':
            if current_user.role != 'admin' and not current_user.can_manage_menu:
                flash("غير مصرح لك بإدارة المنيو.", "danger")
            else:
                branch_id = request.form.get('branch_id', type=int)
                cat_name = request.form.get('category_name', '').strip()
                if branch_id and cat_name:
                    db.session.add(Category(name=cat_name, branch_id=branch_id))
                    db.session.commit()
                    flash("تم إضافة المجموعة للفرع بنجاح!", "success")

        elif action == 'add_user':
            if current_user.role != 'admin' and not current_user.can_manage_users:
                flash("غير مصرح لك بإدارة المستخدمين.", "danger")
            else:
                username = request.form.get('username', '').strip()
                password = request.form.get('password', '').strip()
                role = request.form.get('role', 'staff')
                
                can_view_dashboard = bool(request.form.get('can_view_dashboard'))
                can_view_reports = bool(request.form.get('can_view_reports'))
                can_manage_branches = bool(request.form.get('can_manage_branches'))
                can_manage_menu = bool(request.form.get('can_manage_menu'))
                can_manage_offers = bool(request.form.get('can_manage_offers'))
                can_manage_users = bool(request.form.get('can_manage_users'))
                can_cancel_orders = bool(request.form.get('can_cancel_orders'))

                if username and password:
                    if User.query.filter_by(username=username).first():
                        flash("اسم المستخدم موجود بالفعل!", "danger")
                    else:
                        hashed = generate_password_hash(password)
                        new_u = User(
                            username=username, password_hash=hashed, role=role,
                            can_view_dashboard=can_view_dashboard,
                            can_view_reports=can_view_reports,
                            can_manage_branches=can_manage_branches,
                            can_manage_menu=can_manage_menu,
                            can_manage_offers=can_manage_offers,
                            can_manage_users=can_manage_users,
                            can_cancel_orders=can_cancel_orders,
                            can_manage_settings = bool(request.form.get('can_manage_settings'))
                            
                        )
                        db.session.add(new_u)
                        db.session.commit()
                        flash("تم إضافة المستخدم وصلاحياته بنجاح!", "success")

        elif action == 'add_banner':
            if current_user.role != 'admin' and not current_user.can_manage_offers:
                flash("غير مصرح لك بإدارة العروض.", "danger")
            else:
                file = request.files.get('banner_image')
                if file and allowed_file(file.filename):
                    filename = secure_filename(f"banner_{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}")
                    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
                    db.session.add(RestaurantBanner(image_name=filename))
                    db.session.commit()
                    flash("تم إضافة صورة للواجهة الافتتاحية!", "success")

        elif action == 'add_offer':
            if current_user.role != 'admin' and not current_user.can_manage_offers:
                flash("غير مصرح لك بإدارة العروض.", "danger")
            else:
                file = request.files.get('offer_image')
                if file and allowed_file(file.filename):
                    filename = secure_filename(f"offer_{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}")
                    file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
                    db.session.add(SpecialOffer(image_name=filename))
                    db.session.commit()
                    flash("تم إضافة صورة العرض بنجاح!", "success")

        elif action == 'update_payment':
            pay_num = request.form.get('payment_number', '').strip()
            pay_setting = Setting.query.filter_by(key='payment_number').first()
            if not pay_setting:
                db.session.add(Setting(key='payment_number', value=pay_num))
            else:
                pay_setting.value = pay_num
            db.session.commit()
            flash("تم تحديث رقم المحفظة العام!", "success")

    report_branch_id = request.args.get('branch_id', type=int)
    report_date = request.args.get('date', '').strip()
    report_status = request.args.get('status', '').strip()
    report_date_from = request.args.get('date_from', '').strip()
    report_date_to = request.args.get('date_to', '').strip()
    report_phone = request.args.get('phone', '').strip()

    reports_query = Order.query
    if report_branch_id:
        reports_query = reports_query.filter(Order.branch_id == report_branch_id)
    if report_status:
        reports_query = reports_query.filter(Order.status == report_status)
    if report_phone:
        reports_query = reports_query.filter(Order.customer_phone.ilike(f"%{report_phone}%"))

    if report_date_from:
        try:
            date_from_obj = datetime.strptime(report_date_from, '%Y-%m-%d').date()
            reports_query = reports_query.filter(db.func.date(Order.created_at) >= date_from_obj)
        except ValueError:
            pass

    if report_date_to:
        try:
            date_to_obj = datetime.strptime(report_date_to, '%Y-%m-%d').date()
            reports_query = reports_query.filter(db.func.date(Order.created_at) <= date_to_obj)
        except ValueError:
            pass
    if report_date:
        try:
            target_date = datetime.strptime(report_date, '%Y-%m-%d').date()
            reports_query = reports_query.filter(db.func.date(Order.created_at) == target_date)
        except ValueError:
            pass

    reports_orders = reports_query.order_by(Order.created_at.desc()).all()

    branches = Branch.query.all()
    banners = RestaurantBanner.query.all()
    offers_list = SpecialOffer.query.all()
    users = User.query.all()
    categories = Category.query.all()
    all_items = MenuItem.query.all()
    payment_number = Setting.query.filter_by(key='payment_number').first()
    pay_val = payment_number.value if payment_number else ""
    
    return render_template(
        'admin_settings.html', 
        branches=branches, 
        banners=banners, 
        offers=offers_list,
        users=users, 
        categories=categories, 
        all_items=all_items, 
        pay_val=pay_val,
        reports_orders=reports_orders,
        system_start_date=system_start_date  # تمرير متغير تاريخ البداية بنجاح
    )

@app.route('/edit_branch/<int:branch_id>', methods=['POST'])
def edit_branch(branch_id):
    branch = Branch.query.get_or_404(branch_id)
    
    branch.name = request.form.get('branch_name')
    branch.phone = request.form.get('branch_phone')
    branch.wallet_number = request.form.get('branch_wallet')
    
    # التقاط الخانة الموحدة للإحداثيات عند التعديل
    raw_coords = request.form.get('branch_coords', '').strip()
    if raw_coords:
        try:
            parts = [p.strip() for p in raw_coords.split(',')]
            branch.latitude = float(parts[0])
            branch.longitude = float(parts[1])
        except (ValueError, IndexError):
            flash("صيغة الإحداثيات غير صحيحة أثناء التعديل.", "danger")
            return redirect(url_for('admin_settings'))
            
    db.session.commit()
    flash("تم تحديث بيانات الفرع بنجاح", "success")
    return redirect(url_for('admin_settings'))
    
@app.route('/admin/delete_branch/<int:branch_id>')
@login_required
def delete_branch(branch_id):
    if current_user.role != 'admin' and not current_user.can_manage_branches:
        flash("غير مصرح لك بحذف الفروع.", "danger")
        return redirect(url_for('admin_settings'))
    
    branch = db.session.get(Branch, branch_id)
    if branch:
        db.session.delete(branch)
        db.session.commit()
        flash("تم حذف الفرع بنجاح!", "success")
    return redirect(url_for('admin_settings'))

# --- Excel Export & Import Routes ---
@app.route('/admin/export_reports_excel')
@login_required
def export_reports_excel():
    if current_user.role != 'admin' and not current_user.can_view_reports:
        return "غير مصرح", 403

    branch_id = request.args.get('branch_id', type=int)
    date_str = request.args.get('date', '').strip()
    status = request.args.get('status', '').strip()

    reports_query = Order.query
    if branch_id:
        reports_query = reports_query.filter(Order.branch_id == branch_id)
    if status:
        reports_query = reports_query.filter(Order.status == status)
    if date_str:
        try:
            target_date = datetime.strptime(date_str, '%Y-%m-%d').date()
            reports_query = reports_query.filter(db.func.date(Order.created_at) == target_date)
        except ValueError:
            pass

    orders = reports_query.order_by(Order.created_at.desc()).all()

    data = []
    for order in orders:
        data.append({
            'رقم الطلب': order.id,
            'التاريخ والوقت': order.created_at.strftime('%Y-%m-%d %H:%M') if order.created_at else '',
            'الفرع': order.branch.name if order.branch else 'غير محدد',
            'اسم العميل': order.customer_name,
            'رقم العميل': order.customer_phone,
            'الإجمالي': order.total_price,
            'الحالة': order.status,
            'كود الاستلام': order.pickup_code or '',
            'سبب الإلغاء/التعديل': order.edit_reason or '',
            'سبب الرفض': order.reject_reason or ''
        })

    df = pd.DataFrame(data)
    file_path = os.path.join(app.config['UPLOAD_FOLDER'], "orders_report.xlsx")
    df.to_excel(file_path, index=False)
    return send_file(file_path, as_attachment=True, download_name=f"تقرير_الطلبات_{datetime.now().strftime('%Y%m%d')}.xlsx")

@app.route('/admin/export_excel/<int:branch_id>')
@login_required
def export_excel(branch_id):
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        return "غير مصرح", 403
    branch = db.session.get(Branch, branch_id)
    if not branch:
        flash("الفرع غير موجود", "danger")
        return redirect(url_for('admin_settings'))

    data = []
    for cat in branch.categories:
        for item in cat.items:
            data.append({
                'ID': item.id,
                'المجموعة': cat.name,
                'الصنف': item.name,
                'السعر': item.price,
                'الصورة': item.image
            })
    
    df = pd.DataFrame(data)
    file_path = os.path.join(app.config['UPLOAD_FOLDER'], f"menu_branch_{branch_id}.xlsx")
    df.to_excel(file_path, index=False)
    return send_file(file_path, as_attachment=True, download_name=f"منيو_{branch.name}.xlsx")

@app.route('/admin/import_excel/<int:branch_id>', methods=['POST'])
@login_required
def import_excel(branch_id):
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        return "غير مصرح", 403
    file = request.files.get('file')
    if file and file.filename != '':
        try:
            df = pd.read_excel(file)
            for _, row in df.iterrows():
                cat_name = str(row.get('المجموعة', '')).strip()
                item_name = str(row.get('الصنف', '')).strip()
                price = float(row.get('السعر', 0))
                img_name = str(row.get('الصورة', 'default_food.png')).strip()
                if not img_name or img_name == 'nan':
                    img_name = 'default_food.png'
                
                if cat_name and item_name:
                    category = Category.query.filter_by(name=cat_name, branch_id=branch_id).first()
                    if not category:
                        category = Category(name=cat_name, branch_id=branch_id)
                        db.session.add(category)
                        db.session.commit()
                    
                    menu_item = MenuItem.query.filter_by(name=item_name, category_id=category.id).first()
                    if menu_item:
                        menu_item.price = price
                        menu_item.image = img_name
                    else:
                        db.session.add(MenuItem(name=item_name, price=price, image=img_name, category_id=category.id))
            db.session.commit()
            flash("تم استيراد المنيو بنجاح!", "success")
        except Exception as e:
            flash(f"حدث خطأ أثناء استيراد الملف: {e}", "danger")
    return redirect(url_for('admin_settings'))


# --- Item Management Routes ---
@app.route('/admin/add_item', methods=['POST'])
@login_required
def add_item():
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        flash("غير مصرح لك بإضافة أصناف.", "danger")
        return redirect(url_for('admin_settings'))

    category_id = request.form.get('category_id', type=int)
    name = request.form.get('item_name', '').strip()
    price = request.form.get('item_price', type=float)
    file = request.files.get('item_image')

    image_name = 'default_food.png'
    if file and file.filename != '':
        image_name = secure_filename(f"item_{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}")
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], image_name))

    if category_id and name and price is not None:
        new_item = MenuItem(name=name, price=price, image=image_name, category_id=category_id)
        db.session.add(new_item)
        db.session.commit()
        flash("تم إضافة الصنف بنجاح!", "success")
    return redirect(url_for('admin_settings'))

@app.route('/admin/edit_item/<int:item_id>', methods=['POST'])
@login_required
def edit_item(item_id):
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        flash("غير مصرح لك بتعديل الأصناف.", "danger")
        return redirect(url_for('admin_settings'))

    item = db.session.get(MenuItem, item_id)
    if item:
        item.name = request.form.get('item_name', '').strip()
        item.price = request.form.get('item_price', type=float)
        file = request.files.get('item_image')
        if file and file.filename != '':
            image_name = secure_filename(f"item_{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}")
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], image_name))
            delete_uploaded_file(item.image)
            item.image = image_name
        db.session.commit()
        flash("تم تعديل الصنف بنجاح!", "success")
    return redirect(url_for('admin_settings'))

@app.route('/admin/delete_item/<int:item_id>')
@login_required
def delete_item(item_id):
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        flash("غير مصرح لك بحذف الأصناف.", "danger")
        return redirect(url_for('admin_settings'))

    item = db.session.get(MenuItem, item_id)
    if item:
        delete_uploaded_file(item.image)
        db.session.delete(item)
        db.session.commit()
        flash("تم حذف الصنف بنجاح!", "success")
    return redirect(url_for('admin_settings'))

# --- Category Management Routes ---
@app.route('/admin/edit_category/<int:category_id>', methods=['POST'])
@login_required
def edit_category(category_id):
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        flash("غير مصرح لك بتعديل المجموعات.", "danger")
        return redirect(url_for('admin_settings'))

    category = db.session.get(Category, category_id)
    if category:
        cat_name = request.form.get('category_name', '').strip()
        if cat_name:
            category.name = cat_name
            db.session.commit()
            flash("تم تعديل اسم المجموعة بنجاح!", "success")
    return redirect(url_for('admin_settings'))

@app.route('/admin/delete_category/<int:category_id>')
@login_required
def delete_category(category_id):
    if current_user.role != 'admin' and not current_user.can_manage_menu:
        flash("غير مصرح لك بحذف المجموعات.", "danger")
        return redirect(url_for('admin_settings'))

    category = db.session.get(Category, category_id)
    if category:
        db.session.delete(category)
        db.session.commit()
        flash("تم حذف المجموعة وجميع الأصناف التابعة لها بنجاح!", "success")
    return redirect(url_for('admin_settings'))

# --- User Management Routes ---
@app.route('/admin/edit_user/<int:user_id>', methods=['POST'])
@login_required
def edit_user(user_id):
    if current_user.role != 'admin' and not current_user.can_manage_users:
        flash("غير مصرح لك بتعديل المستخدمين.", "danger")
        return redirect(url_for('admin_settings'))

    user = db.session.get(User, user_id)
    if user:
        user.username = request.form.get('username', '').strip()
        password = request.form.get('password', '').strip()
        if password:
            user.password_hash = generate_password_hash(password)
        
        user.role = request.form.get('role', 'staff')
        user.can_view_dashboard = bool(request.form.get('can_view_dashboard'))
        user.can_view_reports = bool(request.form.get('can_view_reports'))
        user.can_manage_branches = bool(request.form.get('can_manage_branches'))
        user.can_manage_menu = bool(request.form.get('can_manage_menu'))
        user.can_manage_offers = bool(request.form.get('can_manage_offers'))
        user.can_manage_users = bool(request.form.get('can_manage_users'))
        user.can_manage_settings = bool(request.form.get('can_manage_settings'))
        user.can_cancel_orders = bool(request.form.get('can_cancel_orders'))
        user.can_manage_system_date = bool(request.form.get('can_manage_system_date'))
        user.can_export_menu = bool(request.form.get('can_export_menu'))
  
        db.session.commit()
        flash("تم تحديث صلاحيات وبيانات المستخدم بنجاح!", "success")
    return redirect(url_for('admin_settings'))

@app.route('/admin/delete_user/<int:user_id>')
@login_required
def delete_user(user_id):
    if current_user.role != 'admin' and not current_user.can_manage_users:
        flash("غير مصرح لك بحذف المستخدمين.", "danger")
        return redirect(url_for('admin_settings'))

    user = db.session.get(User, user_id)
    if user:
        if user.id == current_user.id:
            flash("لا يمكنك حذف الحساب الخاص بك وأنت مسجل الدخول به!", "danger")
        else:
            db.session.delete(user)
            db.session.commit()
            flash("تم حذف المستخدم بنجاح!", "success")
    return redirect(url_for('admin_settings'))


# --- دالة مسح صور التحويلات (يتم وضعها في آخر الملف بشكل مستقل تماماً) ---
def delete_transfer_file(filename):
    if filename:
        file_path = os.path.join(app.config['TRANSFERS_FOLDER'], filename)
        if os.path.exists(file_path):
            try:
                os.remove(file_path)
            except OSError:
                pass

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        # إنشاء مستخدم مشرف افتراضي إذا لم يكن موجوداً
        admin_user = User.query.filter_by(username='admin').first()
        if not admin_user:
            hashed_pw = generate_password_hash('admin123')
            admin_user = User(
                username='admin',
                password_hash=hashed_pw,
                role='admin',
                can_view_dashboard=True,
                can_view_reports=True,
                can_manage_branches=True,
                can_manage_menu=True,
                can_manage_offers=True,
                can_manage_users=True,
                can_cancel_orders=True
            )
            db.session.add(admin_user)
            db.session.commit()
    app.run(host='0.0.0.0', port=6500, debug=True)