<?php

namespace App\Livewire\Products;

use Barryvdh\DomPDF\Facade\Pdf;
use Exception;
use Filament\Notifications\Notification;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Validator;
use JetBrains\PhpStorm\NoReturn;
use Livewire\Component;
use Livewire\WithFileUploads;
use Symfony\Component\HttpFoundation\StreamedResponse;

class ProductsPresentationCart extends Component
{
    use WithFileUploads;

    public array $cartProducts = [];
    public int $cartProductCount = 0;
    public int $cartProductId;
    public $logo;

    protected $listeners = ['setProductsDataFromLocalStorage', 'updateCartProductCount'];

    public function mount()
    {
        $this->getAllProducts();
    }

    public function getAllProducts(): void
    {
        $this->dispatch('getAllProductsFromLocalStorage');
    }

    public function render()
    {
        return view('livewire.products.products-presentation-cart');
    }

    public function removeProductsConfirmBox($productId = null): void
    {
        if ($productId) {
            $this->cartProductId = $productId;
            $this->dispatch('open-modal', id: 'remove-product');
        } else {
            $this->dispatch('open-modal', id: 'remove-all-products');
        }
    }

    public function closeRemoveProductConfirmBox($modalCloseId): void
    {
        if ($modalCloseId == 'remove-product') {
            $this->dispatch('close-modal', id: 'remove-product');
        } else {
            $this->dispatch('close-modal', id: 'remove-all-products');
        }
    }

    #[NoReturn]
    public function removeProduct(): void
    {
        if (isset($this->cartProducts[$this->cartProductId])) {
            unset($this->cartProducts[$this->cartProductId]);
        }

        $this->dispatch('removeProductFromLocalStorage', $this->cartProducts);
        $this->dispatch('close-modal', id: 'remove-product');
        $this->updateCartProductCount();
        Notification::make()
            ->title('The product has been successfully removed from the presentation list.')
            ->seconds(2)
            ->success()
            ->send();

    }

    public function updateCartProductCount(): void
    {
        $this->getAllProducts();
    }

    public function removeAllProducts(): void
    {
        if (! empty($this->cartProducts)) {
            unset($this->cartProducts);
            $this->cartProductCount = 0;
            $this->dispatch('removeAllProductsFromLocalStorage');
            $this->dispatch('resetCartData')->to(ProductQuote::class);
            $this->dispatch('close-modal', id: 'remove-all-products');
            $this->dispatch('close-modal', id: 'product-presentation');

            Notification::make()
                ->title('All products have been successfully removed from the presentation list.')
                ->success()
                ->seconds(2)
                ->send();
        }
    }

    public function setProductsDataFromLocalStorage($products): void
    {
        $this->cartProducts = $products;
        $this->cartProductCount = count($products);
    }

    public function openModalOfGeneratePresentation(): void
    {
        $this->reset('logo');
        $this->resetValidation('logo');
        $this->resetErrorBag('logo');
        $this->dispatch('open-modal', id: 'generate-presentation');
    }

    public function generatePresentation(): StreamedResponse|Notification|RedirectResponse|null
    {
        $validator = Validator::make(
            ['logo' => $this->logo],
            ['logo' => 'required|image|mimes:jpg,jpeg,png|max:2048'],
        );

        if ($validator->fails()) {
            $this->reset('logo');
            $this->setErrorBag($validator->getMessageBag());

            return redirect()->back();
        }

        $logoName = '/product-presentation' . '.' . $this->logo->getClientOriginalExtension() ?? null;
        $this->logo->storeAs('logo', $logoName, 'public');
        try {
            if (! empty($this->cartProducts)) {
                $this->dispatch('close-modal', id: 'generate-presentation');
                $this->reset('logo');
                $pdf = Pdf::loadView('livewire.products.product-presentation-pdf', ['products' => $this->cartProducts, 'logo' => $logoName]);

                return response()->streamDownload(function () use ($pdf) {
                    echo $pdf->output();
                }, 'product_presentation_' . date('Y-m-d_H-i-s') . '.pdf');
            }
        } catch (Exception $exception) {
            return Notification::make()
                ->danger()
                ->title($exception->getMessage())
                ->send();
        }

        return null;
    }

    public function updatedLogo(): void
    {
        $this->resetValidation('logo');
        $this->resetErrorBag('logo');
    }
}