<?php

namespace Amsgames\LaravelShop\Core;

/**
 * This file is part of LaravelShop,
 * A shop solution for Laravel.
 *
 * @author Alejandro Mostajo
 * @copyright Amsgames, LLC
 * @license MIT
 * @package Amsgames\LaravelShop
 */

use JsonSerializable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Amsgames\LaravelShop\Contracts\PaymentGatewayInterface;

abstract class PaymentGateway implements PaymentGatewayInterface, Arrayable, Jsonable, JsonSerializable
{
    /**
     * Gateway Id, set by shop.
     *
     * @var mixed
     */
    protected $id;

    /**
     * Gateway generated transaction id.
     *
     * @var mixed
     */
    protected $transactionId;

    /**
     * Gateway generated transaction id.
     *
     * @var string
     */
    protected $detail = null;

    /**
     * Gateway generated token.
     *
     * @var mixed
     */
    protected $token = null;

    /**
     * Success call back url.
     *
     * @var mixed
     */
    protected $callbackSuccess = '';

    /**
     * Fail call back url.
     *
     * @var mixed
     */
    protected $callbackFail = '';

    /**
     * Status code after placing order successfully.
     *
     * @var string
     */
    protected $statusCode = 'completed';

    /**
     * Constructor.
     *
     * @param mixed $if Gateway id.
     */
    public function __construct($id = '')
    {
        $this->id            = $id;
        $this->transactionId = uniqid();
        $this->token         = uniqid();
    }
    
    /**
     * Called on cart checkout.
     *
     * @param Order $order Order.
     */
    public function onCheckout($cart)
    {
    }

    /**
     * Called by shop when payment gateway calls callback url.
     * Success result
     *
     * @param Order $order Order.
     * @param mixed $data  Callback data.
     *
     * @return string
     */
    public function onCallbackSuccess($order, $data = null)
    {
    }

    /**
     * Called by shop when payment gateway calls callback url.
     * Failed result
     *
     * @param Order $order Order.
     * @param mixed $data  Callback data.
     *
     * @return string
     */
    public function onCallbackFail($order, $data = null)
    {
    }

    /**
     * Sets callback urls
     *
     * @param Order $order Order.
     */
    public function setCallbacks($order)
    {
        $this->callbackSuccess = route(config('shop.callback_route'), [
            'status'    => 'success',
            'id'        => $order->id,
            'token'     => $this->token,
        ]);

        $this->callbackFail    = route(config('shop.callback_route'), [
            'status'    => 'fail',
            'id'        => $order->id,
            'token'     => $this->token,
        ]);
    }

    /**
     * Returns transaction token.
     *
     * @return mixed.
     */
    public function getTransactionToken()
    {
        return $this->token;
    }

    /**
     * Returns the transaction ID generated by the gateway.
     * i.e. PayPal's transaction ID.
     *
     * @return mixed
     */
    public function getTransactionId()
    {
        return $this->transactionId;
    }

    /**
     * Returns a 1024 length string with extra detail of transaction.
     *
     * @return string
     */
    public function getTransactionDetail()
    {
        return $this->detail;
    }

    /**
     * Returns transaction status code.
     *
     * @return string
     */
    public function getTransactionStatusCode()
    {
        return $this->statusCode;
    }

    /**
     * Convert the model instance to an array.
     *
     * @return array
     */
    public function toArray()
    {
        return ['id' => $this->id];
    }

    /**
     * Convert the model instance to JSON.
     *
     * @param  int  $options
     * @return string
     */
    public function toJson($options = 0)
    {
        return json_encode($this->jsonSerialize(), $options);
    }

    /**
     * Convert the object into something JSON serializable.
     *
     * @return array
     */
    public function jsonSerialize()
    {
        return $this->toArray();
    }

    /**
     * Convert the model to its string representation.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->toJson();
    }


}