<?php

namespace CouponsPlus\App\Conditions\BuiltIn\Conditions;

use CouponsPlus\App\Conditions\Condition;
use CouponsPlus\App\Coupon\Coupon;
use CouponsPlus\App\Coupon\CouponRegistry;
use CouponsPlus\App\Coupon\CouponOffersTracker;
use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\Original\Collections\Mapper\Types;

#[\AllowDynamicProperties]
Class PaymentMethod extends Condition
{
    /** @var Coupon */
    protected /*Coupon*/ $coupon;

    const TYPE = 'PaymentMethod';
    
    static public function getName() : string
    {
        return __('Payment Methods', 'coupons-plus-for-woocommerce');
    }

    static public function getDescription() : string
    {
        return '';
    }

    static public function getUseCases(): Collection
    {
        return new Collection([
            __('5% off when paying with cash', 'coupons-plus-for-woocommerce'),
            __('Free shipping when paying with PayPal', 'coupons-plus-for-woocommerce'),
        ]);
    } 
    
    public static function getOptions() : Collection
    {
        return new Collection([
            'ids' => Types::COLLECTION, //payment method ids/slugs (string)
            'inclusionType' => Types::STRING()->allowed([
                                                __('Eligible', 'coupons-plus-for-woocommerce') => 'allowed',
                                                __('Not Eligible', 'coupons-plus-for-woocommerce') => 'forbidden'
                                               ])
                                              ->withDefault('allowed')
        ]);
    }
    
    public function setExtraData($data)
    {
        $this->coupon = CouponRegistry::getInstance()->get($data);
    }

    protected function test() : bool
    {
        // things to consider:
        // #when autoapply, dont show error messages
        // #when applying before selecting a payment methid like just adding a new product in the cart, show error message that a payment method needs be selected
        // #tiered offers, only add the error once (if they fail on all contexts, dont add thre or more errors!)

        (string) $selectedPaymentMethod = WC()->session->get('chosen_payment_method');

        if ($selectedPaymentMethod === null && !$this->coupon->autoApplyingIsEnabled()) {
            (array) $data = [
                'type' => static::TYPE,
                'code' => $this->coupon->code()->get()
            ];
            (string) $type = 'error';

            (boolean) $thisErrorHasAlreadyBeeAdded = Collection::create(wc_get_notices($type))->filter(function(array $notice) : bool {
                (object) $noticeObject = new Collection($notice);
                
                if (is_array($noticeObject->get('data'))) {
                    (string) $type = $noticeObject->get('data')['type'] ?? '';
                    (string) $code = $noticeObject->get('data')['code'] ?? '';

                    return $type === static::TYPE && $code === $this->coupon->code()->get();
                }

                return false;
            })->haveAny();

            if (!$thisErrorHasAlreadyBeeAdded) {
                wc_add_notice(
                    $mesage = __('You need to select a payment method first for this coupon.', 'coupons-plus-for-woocommerce'), 
                    $type,
                    $data
                );
            }

            return false;
        }

        (boolean) $selectedPaymentMethodExistsInOptions = $this->options->ids->contain($selectedPaymentMethod);

        return $this->options->inclusionType->is('allowed')? $selectedPaymentMethodExistsInOptions : !$selectedPaymentMethodExistsInOptions;
    }
}