<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class SecureFileAccess
{
    protected $sensitiveExtensions = [
        'php', 'php3', 'php4', 'php5', 'php7', 'phtml',
        'asp', 'aspx', 'jsp', 'jspx',
        'exe', 'dll', 'so', 'sh',
        'env', 'config', 'ini',
        'log', 'sql', 'bak',
        'htaccess', 'htpasswd',
        'git', 'svn',
    ];

    protected $sensitivePaths = [
        'storage/logs',
        'storage/framework',
        'vendor',
        'node_modules',
        '.git',
        '.env',
        'config',
    ];

    public function handle(Request $request, Closure $next): Response
    {
        $path = $request->path();
        $extension = pathinfo($path, PATHINFO_EXTENSION);

        // بررسی پسوند فایل
        if ($this->isSensitiveExtension($extension)) {
            abort(403, 'دسترسی به این نوع فایل مجاز نیست.');
        }

        // بررسی مسیر فایل
        if ($this->isSensitivePath($path)) {
            abort(403, 'دسترسی به این مسیر مجاز نیست.');
        }

        // بررسی دسترسی به فایل‌های آپلود شده
        if ($this->isUploadedFile($path)) {
            if (! $this->hasFileAccessPermission($path)) {
                abort(403, 'شما مجوز دسترسی به این فایل را ندارید.');
            }
        }

        // بررسی دسترسی به فایل‌های خصوصی
        if ($this->isPrivateFile($path)) {
            if (! Auth::check()) {
                abort(401, 'برای دسترسی به این فایل باید وارد شوید.');
            }
            if (! $this->hasPrivateFileAccessPermission($path)) {
                abort(403, 'شما مجوز دسترسی به این فایل را ندارید.');
            }
        }

        return $next($request);
    }

    protected function isSensitiveExtension(?string $extension): bool
    {
        if (empty($extension)) {
            return false;
        }

        return in_array(strtolower($extension), $this->sensitiveExtensions);
    }

    protected function isSensitivePath(string $path): bool
    {
        foreach ($this->sensitivePaths as $sensitivePath) {
            if (str_starts_with($path, $sensitivePath)) {
                return true;
            }
        }

        return false;
    }

    protected function isUploadedFile(string $path): bool
    {
        return str_starts_with($path, 'uploads/');
    }

    protected function isPrivateFile(string $path): bool
    {
        return str_starts_with($path, 'private/');
    }

    protected function hasFileAccessPermission(string $path): bool
    {
        // اینجا می‌توانید منطق بررسی دسترسی به فایل‌های آپلود شده را پیاده‌سازی کنید
        // مثلاً بررسی مالک فایل، دسته‌بندی فایل، و غیره
        return true; // فعلاً برای مثال
    }

    protected function hasPrivateFileAccessPermission(string $path): bool
    {
        // اینجا می‌توانید منطق بررسی دسترسی به فایل‌های خصوصی را پیاده‌سازی کنید
        // مثلاً بررسی نقش کاربر، دسترسی‌های اختصاصی، و غیره
        return true; // فعلاً برای مثال
    }
}
