<?php

namespace App\Http\Controllers;

use App\Models\License as LicenseModel;
use Illuminate\Http\Request;
use Inertia\Inertia;

class LicenseController extends Controller
{
    public function licenseSettings()
    {
        $checkData = $this->sca_dochecklicense();

        $licenseRecords = LicenseModel::all();
        $licenseData = [];
        foreach ($licenseRecords as $record) {
            $licenseData[$record->settings] = $record->value;
        }
        $licenseKey = $licenseData['license'] ?? '';

        return Inertia::render('admin/Settings/license', [
            'licenseKey' => $licenseKey,
            'licenseData' => $checkData,
        ]);
    }

    public function updateLicenseSettings(Request $request)
    {
        $request->validate([
            'license' => 'required|string',
        ]);

        $license = $request->license;
        // In update mode, we check without a local key initially or we can just call sca_checklicense directly
        $checkData = $this->sca_checklicense($license, "");

        if (isset($checkData['status']) && $checkData['status'] == 'Active') {
            $localkey = $checkData['localkey'] ?? '';

            LicenseModel::truncate();
            LicenseModel::insert([
                ['settings' => 'license', 'value' => $license],
                ['settings' => 'localkey', 'value' => $localkey],
            ]);

            return redirect()->back()->with('success', 'License saved Successfully');
        } else {
            LicenseModel::truncate();
            $desc = $checkData['description'] ?? 'INVALID OR EXPIRED LICENSE';
            return redirect()->back()->with('error', $desc);
        }
    }

    public function sca_dochecklicense()
    {
        $licensdata = LicenseModel::all();
        $settings = array();
        foreach ($licensdata as $ld) {
            $settings[$ld->settings] = $ld->value;
        }

        $license = (isset($settings['license']) && !empty($settings['license'])) ? $settings['license'] : "";
        $localkey = (isset($settings['localkey']) && !empty($settings['localkey'])) ? $settings['localkey'] : "";

        $checkinglicense = $this->sca_checklicense($license, $localkey);

        if (isset($checkinglicense["status"]) && $checkinglicense["status"] == "Active") {
            if (isset($checkinglicense["localkey"]) && !empty($checkinglicense["localkey"])) {
                $savelocal = $checkinglicense["localkey"];
                LicenseModel::updateOrCreate(
                    ['settings' => 'localkey'],
                    ['value' => $savelocal]
                );
            }
        }
        return $checkinglicense;
    }

    public function sca_checklicense($licensekey = "", $localkey = "")
    {
        $whmcsurl = "https://www.whmcssmarters.com/clients/";
        $licensing_secret_key = "scapanel49302sdf3oa";
        $localkeydays = 14;
        $allowcheckfaildays = 5;
        $check_token = time() . md5(mt_rand(1000000000, 9999999999) . $licensekey);
        $checkdate = date("Ymdhis");
        $domain = $_SERVER['SERVER_NAME'];
        $usersip = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : (isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : '127.0.0.1');
        $dirpath = base_path(); // Adapted for Laravel root directory
        $verifyfilepath = 'modules/servers/licensing/verify.php';
        $localkeyvalid = false;

        if ($localkey) {
            $localkey = str_replace("\n", '', $localkey); # Remove the line breaks
            $localdata = substr($localkey, 0, strlen($localkey) - 32); # Extract License Data
            $md5hash = substr($localkey, strlen($localkey) - 32); # Extract MD5 Hash
            if ($md5hash == md5($localdata . $licensing_secret_key)) {
                $localdata = strrev($localdata); # Reverse the string
                $md5hash = substr($localdata, 0, 32); # Extract MD5 Hash
                $localdata = substr($localdata, 32); # Extract License Data
                $localdata = base64_decode($localdata);
                $localkeyresults = unserialize($localdata);
                $originalcheckdate = $localkeyresults['checkdate'];
                if ($md5hash == md5($originalcheckdate . $licensing_secret_key)) {
                    $localexpiry = date("Ymdhis", mktime(date("h"), date("i"), date("s"), date("m"), date("d") - $localkeydays, date("Y")));
                    if ($originalcheckdate > $localexpiry) {
                        $localkeyvalid = true;
                        $results = $localkeyresults;
                        $validdomains = explode(',', $results['validdomain']);
                        if (!in_array($_SERVER['SERVER_NAME'], $validdomains)) {
                            $localkeyvalid = false;
                            $localkeyresults['status'] = "Invalid";
                            $results = array();
                        }
                        $validips = explode(',', $results['validip']);
                        if (!in_array($usersip, $validips)) {
                            $localkeyvalid = false;
                            $localkeyresults['status'] = "Invalid";
                            $results = array();
                        }
                        $validdirs = explode(',', $results['validdirectory']);
                        if (!in_array($dirpath, $validdirs)) {
                            $localkeyvalid = false;
                            $localkeyresults['status'] = "Invalid";
                            $results = array();
                        }
                    }
                }
            }
        }

        if (!$localkeyvalid) {
            $responseCode = 0;
            $postfields = array(
                'licensekey' => $licensekey,
                'domain' => $domain,
                'ip' => $usersip,
                'dir' => $dirpath,
            );
            if ($check_token)
                $postfields['check_token'] = $check_token;
            $query_string = '';
            foreach ($postfields as $k => $v) {
                $query_string .= $k . '=' . urlencode($v) . '&';
            }
            if (function_exists('curl_exec')) {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $whmcsurl . $verifyfilepath);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
                curl_setopt($ch, CURLOPT_TIMEOUT, 30);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                $data = curl_exec($ch);
                $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);
            } else {
                $responseCodePattern = '/^HTTP\/\d+\.\d+\s+(\d+)/';
                $fp = @fsockopen($whmcsurl, 80, $errno, $errstr, 5);
                if ($fp) {
                    $newlinefeed = "\r\n";
                    $header = "POST " . $whmcsurl . $verifyfilepath . " HTTP/1.0" . $newlinefeed;
                    $header .= "Host: " . $whmcsurl . $newlinefeed;
                    $header .= "Content-type: application/x-www-form-urlencoded" . $newlinefeed;
                    $header .= "Content-length: " . @strlen($query_string) . $newlinefeed;
                    $header .= "Connection: close" . $newlinefeed . $newlinefeed;
                    $header .= $query_string;
                    $data = $line = '';
                    @stream_set_timeout($fp, 20);
                    @fputs($fp, $header);
                    $status = @socket_get_status($fp);
                    while (!@feof($fp) && $status) {
                        $line = @fgets($fp, 1024);
                        $patternMatches = array();
                        if (!$responseCode && preg_match($responseCodePattern, trim($line), $patternMatches)) {
                            $responseCode = (empty($patternMatches[1])) ? 0 : $patternMatches[1];
                        }
                        $data .= $line;
                        $status = @socket_get_status($fp);
                    }
                    @fclose($fp);
                }
            }

            if ($responseCode != 200) {
                $localexpiry = date("Ymdhis", mktime(date("h"), date("i"), date("s"), date("m"), date("d") - ($localkeydays + $allowcheckfaildays), date("Y")));
                if (isset($originalcheckdate) && $originalcheckdate > $localexpiry) {
                    $results = $localkeyresults;
                } else {
                    $results = array();
                    $results['status'] = "Invalid";
                    $results['description'] = "Remote Check Failed";
                    return $results;
                }
            } else {
                preg_match_all('/<(.*?)>([^<]+)<\/\\1>/i', $data, $matches);
                $results = array();
                foreach ($matches[1] as $k => $v) {
                    $results[$v] = $matches[2][$k];
                }
            }

            if (!is_array($results)) {
                die("Invalid License Server Response");
            }

            if (isset($results['md5hash'])) {
                if ($results['md5hash'] != md5($licensing_secret_key . $check_token)) {
                    $results['status'] = "Invalid";
                    $results['description'] = "MD5 Checksum Verification Failed";
                    return $results;
                }
            }

            if (isset($results['status']) && $results['status'] == "Active") {
                $results['checkdate'] = $checkdate;
                $data_encoded = serialize($results);
                $data_encoded = base64_encode($data_encoded);
                $data_encoded = md5($checkdate . $licensing_secret_key) . $data_encoded;
                $data_encoded = strrev($data_encoded);
                $data_encoded = $data_encoded . md5($data_encoded . $licensing_secret_key);
                $data_encoded = wordwrap($data_encoded, 80, "\n", true);
                $results['localkey'] = $data_encoded;
            }
            $results['remotecheck'] = true;
        }

        return $results;
    }
}
