<?php

namespace App\Livewire\Dashboard;

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

class BulkGmail extends Component
{
    public $email;

    public int $quantity = 10;

    public $bulkEmails = [];

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

    public function generateBulk(): void
    {
        $this->validate([
            'email' => [
                'required',
                'email',
                'regex:/^[^@\s]+@gmail\.com$/i',
            ],
            'quantity' => 'required|integer|min:10|max:500',
        ]);

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

        $this->bulkEmails = $this->generateDotVariants(explode('@', (string) $this->email)[0], $this->quantity);
    }

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

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

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

    /**
     * @return string[]
     */
    private function generateDotVariants(string $uname, int $quantity): array
    {
        $length = strlen($uname);
        $positions = range(1, $length - 1);
        $results = [];

        // From 1 dot up to max possible
        for ($dotCount = 1; $dotCount < $length; $dotCount++) {
            $combinations = $this->combinations($positions, $dotCount);

            // Reverse each combination for right-to-left priority
            foreach (array_reverse($combinations) as $combo) {
                $dotted = '';
                $lastPos = 0;

                foreach ($combo as $pos) {
                    $dotted .= substr($uname, $lastPos, $pos - $lastPos).'.';
                    $lastPos = $pos;
                }
                $dotted .= substr($uname, $lastPos);
                $results[] = $dotted.'@gmail.com';

                if (count($results) >= $quantity) {
                    return $results;
                }
            }
        }

        return $results;
    }

    private function combinations(array $items, int $size): array
    {
        if ($size === 0) {
            return [[]];
        }

        if ($items === []) {
            return [];
        }

        $combinations = [];
        $head = $items[0];
        $tail = array_slice($items, 1);

        foreach ($this->combinations($tail, $size - 1) as $c) {
            array_unshift($c, $head);
            $combinations[] = $c;
        }

        return $this->combinations($tail, $size);
    }

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