<?php

namespace App\Livewire\Dashboard;

use Illuminate\Support\Facades\Session;
use Livewire\Component;

class Bulk extends Component
{
    public $bulkEmails = [];

    public $bulkCount = 1;

    public function mount(): void
    {
        $subscriptionCheck = auth()->user()->subscribedToProduct(config('app.plans')[0]['product_id']);
        Session::put('isSubscribed', $subscriptionCheck);
    }

    public function generateBulk(): void
    {
        $this->validate([
            'bulkCount' => 'required|integer|min:1|max:500',
        ]);

        if (count($this->bulkEmails) > 0) {
            $this->bulkEmails = [];
        }

        for ($i = 0; $i < $this->bulkCount; $i++) {
            $this->bulkEmails[] = $this->randomEmail();
        }
    }

    public function downloadBulk()
    {
        // Ensure there's something to download
        if (empty($this->bulkEmails) || ! is_array($this->bulkEmails)) {
            return;
        }

        $filename = 'bulk_emails_'.now()->format('Ymd_His').'.txt';
        $content = implode(PHP_EOL, $this->bulkEmails);

        return response()->streamDownload(function () use ($content): void {
            echo $content;
        }, $filename);
    }

    private function randomEmail(): string
    {
        $domain = $this->getRandomDomain();
        if ($domain == 'gmail.com' || $domain == 'googlemail.com') {
            $uname = $this->getRandomGmailUser();
            $uname_len = strlen((string) $uname);
            $len_power = $uname_len - 1;
            $combination = 2 ** $len_power;
            $rand_comb = mt_rand(1, $combination);
            $formatted = implode(' ', str_split((string) $uname));
            $uname_exp = explode(' ', $formatted);

            $bin = intval('');
            for ($i = 0; $i < $len_power; $i++) {
                $bin .= mt_rand(0, 1);
            }
            $bin = explode(' ', implode(' ', str_split(strval($bin))));

            $email = '';
            for ($i = 0; $i < $len_power; $i++) {
                $email .= $uname_exp[$i];
                if ($bin[$i] !== '' && $bin[$i] !== '0') {
                    $email .= '.';
                }
            }
            $email .= $uname_exp[$i];
            $gmail_rand = mt_rand(1, 10);
            if ($gmail_rand > 5) {
                $email .= '@gmail.com';
            } else {
                $email .= '@googlemail.com';
            }

            return $email;
        }
        return $this->generateRandomUsername().'@'.$domain;
    }

    private function generateRandomUsername(): string
    {
        $start = json_decode((string) config('app.settings.configuration_settings'))->random_username_length_min ?? 0;
        $end = json_decode((string) config('app.settings.configuration_settings'))->random_username_length_max ?? 0;
        if ($start == 0 && $end == 0) {
            return $this->generatePronounceableWord();
        }

        return $this->generatedRandomBetweenLength($start, $end);
    }

    private function generatedRandomBetweenLength($start, $end): string
    {
        $length = random_int($start, $end);

        return $this->generateRandomString($length);
    }

    private function getRandomDomain()
    {
        $domains = json_decode((string) config('app.settings.configuration_settings'))->premium_domains ?? [];
        $count = count($domains);

        return $count > 0 ? $domains[random_int(1, $count) - 1] : '';
    }

    private function getRandomGmailUser()
    {
        $gmailusername = json_decode((string) config('app.settings.configuration_settings'))->premium_gmailUsernames ?? [];
        $count = count($gmailusername);

        return $count > 0 ? $gmailusername[random_int(1, $count) - 1] : '';
    }

    private function generatePronounceableWord(): string
    {
        $c = 'bcdfghjklmnprstvwz'; // consonants except hard to speak ones
        $v = 'aeiou';              // vowels
        $a = $c.$v;                // both
        $random = '';
        for ($j = 0; $j < 2; $j++) {
            $random .= $c[random_int(0, strlen($c) - 1)];
            $random .= $v[random_int(0, strlen($v) - 1)];
            $random .= $a[random_int(0, strlen($a) - 1)];
        }

        return $random;
    }

    private function generateRandomString(int $length = 10): string
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[random_int(0, $charactersLength - 1)];
        }

        return $randomString;
    }

    public function render()
    {
        if (Session::get('isSubscribed')) {
            return view('livewire.dashboard.bulk')->layout('components.layouts.dashboard');
        }
        return view('livewire.dashboard.not-subscribed')->layout('components.layouts.dashboard');
    }
}
