<?php

namespace Hilco\Models;

use Arr;
use Carbon\Carbon;
use Exception;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Log;
use Throwable;

/**
 * Model Class CenposAuthorization
 * @property integer id
 * @property integer stagedorder_id
 * @property string status
 * @property string auth_code
 * @property string auth_reference_num
 * @property string last_four_digits
 * @property float authorized_amount
 * @property string date_authorized
 * @property boolean onetime_auth
 * @property string void_code
 * @property string void_reference_num
 * @property string origin
 * @property StagedOrder stagedOrder
 */
class CenposAuthorization extends StagingModel {
    protected $table = "CenposAuthorizations";
    protected $fillable = [
        'status',
        'auth_code', 'auth_reference_num',
        'last_four_digits', 'authorized_amount', 'date_authorized', 'onetime_auth',
        'void_code', 'void_reference_num',
        'origin',
    ];
    const AUTH_STATUS = "AUTHORIZED";
    const VOID_STATUS = "VOID";

    /**
     * @param StagedOrder $stagedOrder
     * @param $authResponse
     * @param string $lastFour
     * @param bool $isOneTime
     * @return $this
     * @throws Exception
     * @throws Throwable
     */
    public static function createAuthRecord (StagedOrder $stagedOrder, $authResponse,
                                             string $lastFour, bool $isOneTime): CenposAuthorization {
        $createData = [
            'status'                => self::AUTH_STATUS,
            'auth_code'             => Arr::get($authResponse, 'AutorizationNumber'),
            'auth_reference_num'    => Arr::get($authResponse, 'ReferenceNumber'),
            'last_four_digits'      => $lastFour,
            'authorized_amount'     => Arr::get($authResponse, 'Amount'),
            'date_authorized'       => Carbon::now()->setTimezone("America/New_York")->toDateString(),
            'onetime_auth'          => $isOneTime ? 1 : 0,
            'origin'                => "B2B",
        ];
        $ccAuth = new CenposAuthorization($createData);
        $ccAuth->stagedOrder()->associate($stagedOrder);
        try {
            $saveResult = $ccAuth->saveOrFail();
            if (!$saveResult) {
                throw new Exception("CenposAuthorization::saveOrFail() failed, returned false.");
            }
        } catch (Throwable $t) {
            Log::error(
                "Creating CenposAuthorization record {record} for order {refNum} failed and returned false, aborting: {trace}",
                ['record' => json_encode($createData), 'refNum' => $stagedOrder->getReferenceNumber(), 'trace' => $t->getTraceAsString()]
            );
            throw $t;
        }
        return $ccAuth;
    }

    /**
     * @return BelongsTo
     */
    public function stagedOrder(): BelongsTo {
        return $this->belongsTo(StagedOrder::class, "stagedorder_id", "id");
    }

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

    /**
     * @return float
     */
    public function getAuthorizedAmount(): float {
        return $this->authorized_amount;
    }

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

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

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

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

    /**
     * @return bool
     */
    public function isOneTimeAuth(): bool {
        return $this->onetime_auth;
    }
}