<?php

namespace RTMCustomMails\EmailSections;

use DateTime;
use Jawira\CaseConverter\Convert;
use RTMCustomMails\Util;
use Symfony\Component\VarDumper\VarDumper;
use Timber\Twig_Filter;
use Timber\Twig_Function;
use Twig\Environment;
use Twig\TwigTest;
use WC_Order;
use WordpressModels\Traits\SingletonTrait;

/**
 *
 */
class TwigFunctions
{
    use SingletonTrait;

    public function __construct()
    {
        add_filter('timber/twig/functions', [$this, 'addTwigFunctions']);
        add_filter('timber/twig/filters', [$this, 'addTwigFilters']);
    }

    /**
     * @param Environment $twig
     * @return Environment
     */
    public function addTwigFunctions($twig): Environment
    {
        $twig->addFunction(new Twig_Function('order_payment_link',
            [$this, 'orderPaymentLink'],
            ['is_safe' => true]));

        $twig->addFunction(new Twig_Function('link',
            [$this, 'link'],
            ['is_safe' => true]));

        $twig->addFunction(new Twig_Function('lost_password_link',
            [$this, 'lostPasswordLink'],
            ['is_safe' => true, 'needs_context' => true]));

        $twig->addFunction(new Twig_Function('my_account_link',
            [$this, 'myAccountLink'],
            ['is_safe' => true]));
        $twig->addFunction(new Twig_Function('format_date_short',
            [$this, 'formatDateShort'],
            ['is_safe' => true]));

        $twig->addFunction(new Twig_Function('format_date_long',
            [$this, 'formatDateLong'],
            ['is_safe' => true]));

        $twig->addFunction(new Twig_Function('wc_price',
            'wc_price',
            ['is_safe' => true]));

        $twig->addFunction(new Twig_Function('get_email_by_id', [Util::class, 'getEmailById']));

        $twig->addFunction(new Twig_Function('add_query_arg', 'add_query_arg'));
        $twig->addFunction(new Twig_Function('remove_query_arg', 'remove_query_arg'));
        $twig->addFunction(new Twig_Function('wp_editor', 'wp_editor'));

        if (WP_DEBUG) {
            $twig->addFunction(new Twig_Function('dd',
                'dd',
                ['is_safe' => true]));
            $twig->addFunction(new Twig_Function('vdump',
                [VarDumper::class, 'dump'],
                ['is_safe' => true]));
        }

        $twig->addTest(new TwigTest('array', 'is_array'));

        return $twig;
    }

    /**
     * @param $twig
     * @return mixed
     */
    public function addTwigFilters($twig): mixed
    {
        $twig->addFilter(new Twig_Filter('as_date', fn(string $string) => new DateTime($string)));
        $twig->addFilter(new Twig_Filter('wptexturize', 'wptexturize'));
        $twig->addFilter(new Twig_Filter('ucfirst', 'ucfirst'));

        $twig->addFilter(new Twig_Filter('integer', 'intval'));
        $twig->addFilter(new Twig_Filter('int', 'intval'));
        $twig->addFilter(new Twig_Filter('string', 'strval'));
        $twig->addFilter(new Twig_Filter('str', 'strval'));
        $twig->addFilter(new Twig_Filter('xor', fn($first, $second) => $first xor $second));

        $twig->addFilter(new Twig_Filter('toCase', [$this, 'convertCase']));

        return $twig;
    }

    public function convertCase($string, $toCase)
    {
        return (new Convert($string))->{'to' . ucfirst($toCase)}();
    }

    /**
     * @param $text
     * @return string
     */
    public function myAccountLink($text = 'My Account'): string
    {
        return $this->link(get_permalink(get_option('woocommerce_myaccount_page_id')), $text);
    }

    /**
     * @param WC_Order $order
     * @param $text
     * @param $attributes
     * @return string
     */
    public function orderPaymentLink(WC_Order $order, $text = 'pay', $attributes = []): string
    {
        $attr = '';
        foreach ($attributes as $key => $val) {
            $attr .= $key . '="' . esc_attr($val) . '" ';
        }
        return "<a href=\"" . esc_url($order->get_checkout_payment_url()) . "\"" . $attr . ">" . esc_html($text) . "</a>";
    }

    /**
     * @param $url
     * @param $text
     * @param $class
     * @return string
     */
    public function link($url, $text = null, $class = []): string
    {
        $text = $text ?? $url;
        $attr = $class ? ' class="' . join(' ', $class) . '"' : '';
        return "<a href='$url'$attr>$text</a>";
    }

    /**
     * @param $context
     * @param $text
     * @return string
     */
    public function lostPasswordLink($context, $text = 'link'): string
    {
        return esc_url(
            add_query_arg([
                'key' => $context['reset_key'],
                'id' => $context['user_id']
            ],
                wc_get_endpoint_url('lost-password', '', wc_get_page_permalink('myaccount'))));
    }

    /**
     * @param $date_time
     * @param $with_time
     * @return mixed|string
     */
    public function formatDateShort($date_time, $with_time = false): mixed
    {
        return $date_time ? $date_time->format('d-m-Y' . ($with_time ? ' H:i:s' : '')) : '';
    }

    /**
     * @param $dateTime
     * @param $with_time
     * @return mixed|string
     */
    public function formatDateLong($dateTime, $with_time = false): mixed
    {
        return $dateTime ? $dateTime->format('d l Y' . ($with_time ? ' H:i:s' : '')) : '';
    }

}