<?php

namespace App\Providers;

use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        // تسجيل الخدمات المخصصة
        $this->app->singleton('taxi.service', function ($app) {
            return new \App\Services\TaxiService();
        });

        $this->app->singleton('restaurant.service', function ($app) {
            return new \App\Services\RestaurantService();
        });

        $this->app->singleton('gas.service', function ($app) {
            return new \App\Services\GasService();
        });

        $this->app->singleton('payment.service', function ($app) {
            return new \App\Services\PaymentService();
        });

        $this->app->singleton('notification.service', function ($app) {
            return new \App\Services\NotificationService();
        });
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // خريطة morph لعلاقة owner في PartnerWallet (restaurant / gas_office / driver)
        Relation::morphMap([
            'restaurant' => \App\Models\Restaurant::class,
            'gas_office' => \App\Models\GasOffice::class,
            'driver' => \App\Models\User::class,
        ]);

        // إعداد Schema للتوافق مع MySQL القديم
        Schema::defaultStringLength(191);

        // إضافة قواعد التحقق المخصصة
        $this->addCustomValidationRules();

        // إعداد مراقبة الاستعلامات في بيئة التطوير
        if (config('app.debug')) {
            $this->enableQueryLogging();
        }

        // إعداد مراقبة الأخطاء
        $this->setupErrorHandling();

        // إعداد مراقبة الأداء
        $this->setupPerformanceMonitoring();
    }

    /**
     * إضافة قواعد التحقق المخصصة
     */
    private function addCustomValidationRules(): void
    {
        // التحقق من رقم الهاتف
        Validator::extend('phone_number', function ($attribute, $value, $parameters, $validator) {
            return preg_match('/^[0-9+\-\s()]+$/', $value);
        }, 'رقم الهاتف غير صحيح');

        // التحقق من رقم الهوية
        Validator::extend('national_id', function ($attribute, $value, $parameters, $validator) {
            return preg_match('/^[0-9]{10}$/', $value);
        }, 'رقم الهوية يجب أن يكون 10 أرقام');

        // التحقق من رقم السيارة
        Validator::extend('plate_number', function ($attribute, $value, $parameters, $validator) {
            return preg_match('/^[0-9]{3}[A-Z]{3}$/', $value);
        }, 'رقم اللوحة يجب أن يكون 3 أرقام متبوعة بـ 3 أحرف');

        // التحقق من إحداثيات GPS
        Validator::extend('gps_coordinates', function ($attribute, $value, $parameters, $validator) {
            return is_numeric($value) && $value >= -180 && $value <= 180;
        }, 'إحداثيات GPS غير صحيحة');
    }

    /**
     * تفعيل تسجيل الاستعلامات في بيئة التطوير
     */
    private function enableQueryLogging(): void
    {
        DB::listen(function ($query) {
            $sql = $query->sql;
            $bindings = $query->bindings;
            $time = $query->time;

            if ($time > 100) { // تسجيل الاستعلامات البطيئة
                Log::warning("Slow query detected: {$sql}", [
                    'bindings' => $bindings,
                    'time' => $time . 'ms'
                ]);
            }

            if (config('app.debug')) {
                Log::info("Query executed: {$sql}", [
                    'bindings' => $bindings,
                    'time' => $time . 'ms'
                ]);
            }
        });
    }

    /**
     * إعداد معالجة الأخطاء
     */
    private function setupErrorHandling(): void
    {
        // تسجيل الأخطاء غير المعالجة
        set_exception_handler(function ($exception) {
            Log::error('Unhandled exception: ' . $exception->getMessage(), [
                'file' => $exception->getFile(),
                'line' => $exception->getLine(),
                'trace' => $exception->getTraceAsString()
            ]);
        });

        // تسجيل الأخطاء
        set_error_handler(function ($severity, $message, $file, $line) {
            if (!(error_reporting() & $severity)) {
                return;
            }

            Log::error("PHP Error: {$message}", [
                'severity' => $severity,
                'file' => $file,
                'line' => $line
            ]);
        });
    }

    /**
     * إعداد مراقبة الأداء
     */
    private function setupPerformanceMonitoring(): void
    {
        // مراقبة استخدام الذاكرة
        if (function_exists('memory_get_usage')) {
            $memoryUsage = memory_get_usage(true);
            $memoryLimit = ini_get('memory_limit');

            if ($memoryUsage > 100 * 1024 * 1024) { // أكثر من 100MB
                Log::warning('High memory usage detected', [
                    'usage' => $this->formatBytes($memoryUsage),
                    'limit' => $memoryLimit
                ]);
            }
        }

        // مراقبة وقت الاستجابة
        $startTime = microtime(true);

        app()->terminating(function () use ($startTime) {
            $executionTime = (microtime(true) - $startTime) * 1000;

            if ($executionTime > 1000) { // أكثر من ثانية واحدة
                Log::warning('Slow response time detected', [
                    'execution_time' => round($executionTime, 2) . 'ms'
                ]);
            }
        });
    }

    /**
     * تنسيق البايتات إلى وحدات مقروءة
     */
    private function formatBytes($bytes, $precision = 2): string
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];

        for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
            $bytes /= 1024;
        }

        return round($bytes, $precision) . ' ' . $units[$i];
    }
}
