<?php

declare(strict_types=1);

namespace App\Extensions\Twig;

use App\Entity\Comptabilites\Currencies\Currencies;
use App\Entity\Parametres\Parametres;
use App\Services\ContextService;
use App\Services\Helpers\Chiffreenlettre;
use NumberToWords\Exception\InvalidArgumentException;
use NumberToWords\Exception\NumberToWordsException;
use Symfony\Component\HttpFoundation\RequestStack;
use Twig\TwigFilter;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class CurrenciesExtension extends AbstractExtension
{
    /**
     * CartExtension constructor.
     * @param RequestStack $requestStack
     * @param ContextService $contextService
     * @param Chiffreenlettre $chiffreenlettre
     */
    public function __construct(
        private RequestStack $requestStack,
        private ContextService $contextService,
        private Chiffreenlettre $chiffreenlettre
    ) {}

    /**
     * @return TwigFunction[]
     */
    public function getFunctions(): array
    {
        return [
            new TwigFunction('reduction', [$this, 'getReduction'], ['is_safe' => ['html']]),
            new TwigFunction('tocurrency', [$this, 'getToCurrency']),
            new TwigFunction('currency', [$this, 'getCurrency'])
        ];
    }

    /**
     * @param float $price
     * @param float $pricepromo
     * @return string
     */
    public function getReduction(float $price, float $pricepromo): string
    {
        $reduction = $price - $pricepromo;
        $percent = ceil(($reduction * 100) / $price);
        return '<small style="font-size: 13px;display: inline">-' . $percent . '%</small>';
    }

    /**
     * @param ?int $number
     * @param string|null $devise
     * @return string
     * @throws InvalidArgumentException
     * @throws NumberToWordsException
     */
    public function getToCurrency(?int $number = 0, ?string $devise = 'XOF'): string
    {
        if ($number === null) {
            $number = 0;
        }
        return $this->chiffreenlettre->tocurrency($number, $devise);
    }


    /**
     * @return TwigFilter[]
     */
    public function getFilters(): array
    {
        return [
            new TwigFilter('devise', [$this, 'getPriceDevise'], ['is_safe' => ['html']]),
            new TwigFilter('francs', [$this, 'getPriceDeviseSimple'], ['is_safe' => ['html']]),
            new TwigFilter('currency_conversion', [$this, 'getCurrencyConversion'], ['is_safe' => ['html']]),
            new TwigFilter('towords', [$this, 'geToWords'])
        ];
    }

    /**
     * @param float|null $price
     * @return string|null
     */
    // public function getCurrencyConversion(?float $price = 0): ?string
    // {
    //     $session = $this->requestStack->getSession();

    //     /** @var Parametres $parametre */
    //     $parametre = $this->contextService->get()['app'];

    //     /** @var Currencies $currencySession */
    //     $currencySession = $session->get('_currencie');

    //     /** @var Currencies $defaultCurrencie */
    //     $defaultCurrencie = $parametre->getCurrencies();
    //     if ($price === null) {
    //         return 0 . ' <small style="font-size: 13px;">' . ($defaultCurrencie->getLeftSymbol() ?: $defaultCurrencie->getRightSymbol()) . '</small>';
    //     }

    //     $total = ceil($currencySession->getExchangedValue() * $price);

    //     /** @var int $decimalPlace */
    //     $decimalPlace = $currencySession->getDecimalPlace();

    //     /** @var string $decimalSymbol */
    //     $decimalSymbol = $currencySession->getDecimalSymbol();

    //     /** @var string $thousandsSeparator */
    //     $thousandsSeparator = $currencySession->getThousandsSeparator();
    //     if ($currencySession->getLeftSymbol()) {
    //         $symbol = $currencySession->getLeftSymbol();
    //     } else {
    //         $symbol = $currencySession->getRightSymbol();
    //     }
    //     return number_format($total, $decimalPlace, $decimalSymbol, $thousandsSeparator) . ' <small style="font-size: 13px;">' . $symbol . '</small>';
    // }

    public function getCurrencyConversion(?float $price = 0): ?string
    {
        $session = $this->requestStack->getSession();

        // Récupération sécurisée du paramètre
        $context = $this->contextService->get();
        $parametre = $context['app'] ?? null;

        // Si aucun paramètre, retourner 0 avec symbole générique
        if (!$parametre) {
            return 0 . ' <small style="font-size: 13px;">F CFA</small>';
        }

        /** @var Currencies $currencySession */
        $currencySession = $session->get('_currencie') ?? $parametre->getCurrencies();

        /** @var Currencies $defaultCurrencie */
        $defaultCurrencie = $parametre->getCurrencies();

        if ($price === null) {
            return 0 . ' <small style="font-size: 13px;">' . ($defaultCurrencie->getLeftSymbol() ?: $defaultCurrencie->getRightSymbol()) . '</small>';
        }

        $total = ceil($currencySession->getExchangedValue() * $price);

        $decimalPlace = $currencySession->getDecimalPlace();
        $decimalSymbol = $currencySession->getDecimalSymbol();
        $thousandsSeparator = $currencySession->getThousandsSeparator();
        $symbol = $currencySession->getLeftSymbol() ?: $currencySession->getRightSymbol();

        return number_format($total, $decimalPlace, $decimalSymbol, $thousandsSeparator) . ' <small style="font-size: 13px;">' . $symbol . '</small>';
    }


    public function getCurrency(): ?string
    {
        $session = $this->requestStack->getSession();

        /** @var Parametres $parametre */
        $parametre = $this->contextService->get()['app'];
        if ($session->get('_currencie')) {
            /** @var Currencies $currencySession */
            $currencySession = $session->get('_currencie');
            return $currencySession->getCurrencyCode();
        } else {
            /** @var Currencies $defaultCurrencie */
            $defaultCurrencie = $parametre->getCurrencies();
            return $defaultCurrencie->getCurrencyCode();
        }
    }

    public function getPriceDevise(int $price): string
    {
        return number_format($price, 0, ' ', ' ') . ' <small style="font-size: 13px;">F CFA</small>';
    }

    public function getPriceDeviseSimple(int $price): string
    {
        return number_format($price, 0, ' ', ' ') . ' <small style="font-size: 13px;">F CFA</small>';
    }

    /**
     * @param int $number
     * @return string
     * @throws InvalidArgumentException
     * @throws NumberToWordsException
     */
    public function geToWords(int $number): string
    {
        return $this->chiffreenlettre->towords($number);
    }
}
