<?php

namespace CouponsPlus\App\Data\Store;

use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\Original\Environment\Env;
use CouponsPlus\App\Data\Store\Abilities\Storable;
use CouponsPlus\App\Data\Store\Abilities\Deletable;

#[\AllowDynamicProperties]
Abstract class Storer implements Storable
{
    abstract protected function getPostFieldName() : string;
    abstract protected function storeData();

    public function canBeStored() : bool
    {
        // should be isset 
        // checks if the variable is set
        // and that the nonce is valid.
        return (!empty(
                    sanitize_text_field(wp_unslash($_POST[$this->getPostFieldName()] ?? ''))
                ) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST[$this->getNonceMeta()->get('fieldName')] ?? '')), $this->getNonceMeta()->get('id')));
    }

    /**
     * Can be overridden by child classes if needed.
     */
    protected function getNonceMeta() : Collection
    {
        return new Collection([
            'fieldName' => Env::getWithPrefix('dashboard_nonce'),
            'id' => 'coupons-plus-dashboard'
        ]);   
    }

    protected function getData()
    {
        if ((empty(
            sanitize_text_field(wp_unslash($_POST[$this->getPostFieldName()] ?? ''))
            ) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST[$this->getNonceMeta()->get('fieldName')] ?? '')), $this->getNonceMeta()->get('id')))) {
            return null;
        }
        // before data is used it's checked for validity in static::canBeStored()
        // the aforementioned method checks both that the variable is set and that the
        // nonce is valid.
        return sanitize_text_field(wp_unslash($_POST[$this->getPostFieldName()] ?? ''));
    }
    
    public function store(): void
    {
        if ($this->canBeStored()) {
            $this->storeData();
        } else {
            // cannot be stored, so can it be removed?
            if (is_a($this, Deletable::class, true) && $this->canBeDeleted()) {
                $this->delete();
            }
        }
    }
}