<?php

namespace App\Http\Middleware;

use App\Facades\CommonService;
use App\Models\AccessLog;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class AfterMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        try {
            $user_id = auth()->id();
            if ($user_id >5233000000) {
                $user_id = $user_id - 5233000000;
            }

            if ($request->method() == "GET") return $response;
            $params = $request->all();
            $headers = $request->header();
            $data = [
                'user_id' => $user_id,
                'method' => $request->method(),
                'route' => $request->getPathInfo(),
                'client_ip' => $this->get_ip_address(),
                'params' => $params ? json_encode($params) : '',
                'user_agent' => $request->userAgent(),
                'headers' => $headers ? json_encode($headers) : '',
                'channel' => $this->channel(),
                'time' => round(microtime(true) - LARAVEL_START, 3)
            ];
            $suffix = $this->getSuffix();
            AccessLog::suffix($suffix)->create($data);
        }catch (\Exception $e) {
            Log::info($e->getMessage());
        }
        return $response;
    }

    public function getSuffix()
    {
        $year = date("Y");
        $quarter = CommonService::getQuarter(date("m"));
        return $year.$quarter;
    }

    public function channel()
    {
        if (request()->is("api/admin/*")) return "Admin";
        if (request()->is("api/h5/*")) return "H5";
        if (request()->is("api/app/*")) return "APP";
        if (request()->is("api/*")) return "小程序";
        return "其他";
    }

    public function get_ip_address() {
        // Check for shared Internet/ISP IP
        if (!empty($_SERVER['HTTP_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
            return $_SERVER['HTTP_CLIENT_IP'];
        }

        // Check for IP passed in via HTTP_X_FORWARDED_FOR header
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            // Check if multiple IP addresses exist in this header
            $ip_addresses = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

            foreach ($ip_addresses as $ip) {
                if ($this->validate_ip($ip)) {
                    return $ip;
                }
            }
        }

        // Check for IP passed in via REMOTE_ADDR header
        if ($this->validate_ip($_SERVER['REMOTE_ADDR'])) {
            return $_SERVER['REMOTE_ADDR'];
        }

        // Return unreliable IP address since all else failed
        return $_SERVER['REMOTE_ADDR'];
    }

    function validate_ip($ip) {
        if (strtolower($ip) === 'unknown') {
            return false;
        }

        // Generate IPv4 network address
        $ipv4_network = ip2long('0.0.0.0/24');

        // Generate IPv6 network address
        $ipv6_network = inet_pton('::ffff:0.0.0.0') . '/96';

        // Check if IP address is IPv4
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
            // Convert IP to IPv4 network address
            $ip_network = ip2long($ip) & ~((1 << (32 - 24)) - 1);

            return $ip_network === $ipv4_network;
        }

        // Check if IP address is IPv6
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
            // Convert IP to IPv6 network address
            $ip_network = inet_pton($ip) & ~((1 << (128 - 96)) - 1);

            return $ip_network === $ipv6_network;
        }

        return false;
    }
}


