<?php

namespace App\Http\Middleware;

use App\Models\SecuritySetting;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class FileUploadProtection
{
    protected function getAllowedMimes(): array
    {
        $mimes = SecuritySetting::getValue('file', 'allowed_mimes');

        return $mimes ? json_decode($mimes, true) : [
            'image/jpeg',
            'image/png',
            'image/gif',
            'application/pdf',
            'application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        ];
    }

    protected function getMaxFileSize(): int
    {
        return (int) SecuritySetting::getValue('file', 'max_file_size', 10485760);
    }

    protected function getDangerousExtensions(): array
    {
        $extensions = SecuritySetting::getValue('file', 'dangerous_extensions');

        return $extensions ? json_decode($extensions, true) : [
            'php', 'php3', 'php4', 'php5', 'php7', 'phtml',
            'asp', 'aspx', 'jsp', 'jspx',
            'exe', 'dll', 'so', 'sh', 'bat', 'cmd',
        ];
    }

    public function handle(Request $request, Closure $next): Response
    {
        if ($request->hasFile('file')) {
            $file = $request->file('file');

            // بررسی نوع فایل
            if (! in_array($file->getMimeType(), $this->getAllowedMimes())) {
                $this->logViolation($request, 'invalid_mime', $file->getMimeType());

                return response()->json([
                    'message' => 'نوع فایل مجاز نیست.',
                    'error_code' => 'invalid_file_type',
                ], 400);
            }

            // بررسی سایز فایل
            if ($file->getSize() > $this->getMaxFileSize()) {
                $this->logViolation($request, 'file_too_large', $file->getSize());

                return response()->json([
                    'message' => 'حجم فایل بیش از حد مجاز است.',
                    'error_code' => 'file_too_large',
                ], 400);
            }

            // بررسی پسوند فایل
            $extension = strtolower($file->getClientOriginalExtension());
            if (in_array($extension, $this->getDangerousExtensions())) {
                $this->logViolation($request, 'dangerous_extension', $extension);

                return response()->json([
                    'message' => 'پسوند فایل مجاز نیست.',
                    'error_code' => 'dangerous_extension',
                ], 400);
            }

            // بررسی محتوای فایل
            if ($this->containsMaliciousContent($file)) {
                $this->logViolation($request, 'malicious_content', null);

                return response()->json([
                    'message' => 'فایل حاوی محتوای مخرب است.',
                    'error_code' => 'malicious_content',
                ], 400);
            }
        }

        return $next($request);
    }

    protected function containsMaliciousContent($file): bool
    {
        $content = file_get_contents($file->getRealPath());

        // بررسی وجود کد PHP
        if (preg_match('/<\?php/i', $content)) {
            return true;
        }

        // بررسی وجود اسکریپت‌های مخرب
        $dangerousPatterns = [
            '/<script/i',
            '/javascript:/i',
            '/vbscript:/i',
            '/onload=/i',
            '/onerror=/i',
        ];

        foreach ($dangerousPatterns as $pattern) {
            if (preg_match($pattern, $content)) {
                return true;
            }
        }

        return false;
    }

    protected function logViolation(Request $request, string $type, $details = null): void
    {
        Log::warning('تلاش آپلود فایل غیرمجاز', [
            'ip' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'type' => $type,
            'details' => $details,
            'file_name' => $request->file('file') ? $request->file('file')->getClientOriginalName() : null,
        ]);
    }
}
