<?php

namespace App\Classes\Modules\Billplzs\DataTransferObjects;

use Illuminate\Http\Request;
use App\Classes\General\Interfaces\DataTransferObject;
use function PHPSTORM_META\map;

class BillplzXSignatureObject implements DataTransferObject
{

    /** @var string */
    private $billPlzId;

    /** @var string */
    private $status;

    /** @var array */
    private $billPlzConstructArray;

    /** @var string */
    private $billPlzConstructString;

    /** @var string  */
    private $billPlzComputedXSignature;

    /** @var string */
    private $type;

    /** @var Request  */
    private $request;

    /** @var string  */
    private $requestXSignature;

    public function __construct(Request $request)
    {

        $this->type = $request->exists('billplz') ? 'redirect' : 'callback';

        $this->request = $this->type === 'redirect' ? $request->input('billplz') : $request;

        $this->billPlzId = $this->request['id'];

        $this->status = $this->request['transaction_status'];

        $this->requestXSignature = $this->request['x_signature'];

        $this->_constructBillplzArray()->_natSortBillplzArray()->_constructBillplzString()->_computeBillplzXSignature();
    }

    private function _constructBillplzArray(){

        $this->billPlzConstructArray = collect($this->request)->forget('x_signature')->map(function($item, $key){
            return $this->type === 'redirect' ? 'billplz'.$key.$item : $key.$item;
        })->toArray();

        return $this;
    }

    private function _natCaseSortBillplzArray(){
        natcasesort($this->billPlzConstructArray);
        return $this;
    }

    private function _natSortBillplzArray(){
        natsort($this->billPlzConstructArray);
        return $this;
    }

    private function _constructBillplzString(){
        $this->billPlzConstructString = implode('|', $this->billPlzConstructArray);
        return $this;
    }

    private function _computeBillplzXSignature(){
        $this->billPlzComputedXSignature = hash_hmac('sha256', $this->billPlzConstructString, config('billplz.x_signature_key'));
        return $this;
    }

    public function getBillPlzId(): string
    {
        return $this->billPlzId;
    }

    public function getStatus(): string
    {
        return $this->status;
    }

    /**
     * @return array
     */
    public function getBillPlzConstructArray(): array
    {
        return $this->billPlzConstructArray;
    }

    /**
     * @return string
     */
    public function getBillPlzConstructString(): string
    {
        return $this->billPlzConstructString;
    }

    /**
     * @return string
     */
    public function getBillPlzComputedXSignature(): string
    {
        return $this->billPlzComputedXSignature;
    }

    public function isValidSignature(): bool
    {
        return $this->billPlzComputedXSignature === $this->requestXSignature ? true : false;
    }

}