<?php



namespace Tartan\Auth\Model;

use Phalcon\Http\Client\Exception;
use Phalcon\Mvc\Model\Behavior\Timestampable;
use Phalcon\Mvc\Model\Validator\InclusionIn;
use Phalcon\Mvc\Model;

class TempCodes extends Model
{
    const CONFIRM = 'confirmation';
    const FORGOT  = 'forgotpassword';

    public $id;
    public $element_id;
    public $code;
    public $reason;
    public $created_at;
    public $expired_at;

    public function initialize ()
    {
	    $this->setSource("tartan_temp_codes");

        $this->addBehavior(new Timestampable(
            array(
                'beforeCreate' => array(
                    'field'  => 'created_at',
                    'format' => 'Y-m-d H:i:s'
                ),
                'beforeUpdate' => array(
                    'field'  => 'updated_at',
                    'format' => 'Y-m-d H:i:s'
                ),
            )
        ));

        $this->skipAttributes(
            [
                'updated_at',
                'created_at'
            ]
        );
    }

    public function validation ()
    {
        $this->validate(new InclusionIn([
            "field"  => "reason",
            "domain" => ["confirmation", "forgotpassword"]
        ]));

        return $this->validationHasFailed() != true;
    }

    public function beforeValidationOnCreate ()
    {
        $this->code = sha1(base64_encode(openssl_random_pseudo_bytes(80)) . microtime() . uniqid());

        if (empty($this->expired_at)) {
            $this->expired_at = date('Y-m-d H:i:s', strtotime('+24 hours')); // 24 hours
        }
    }

    public function afterValidation ()
    {
    }

    /**
     * Send a confirmation e-mail to the user after create the account
     */
    public function afterCreate ()
    {
    }

    public function getId ()
    {
        return $this->id;
    }

    public function setId ($id)
    {
        $this->id = $id;

        return $this;
    }

    public function setCode ($code)
    {
        $this->code = $code;

        return $this;
    }

    public function getCode ()
    {
        return $this->code;
    }

    public function getElementId ()
    {
        return $this->element_id;
    }

    public function getCreatedAt ()
    {
        return $this->created_at;
    }

    public function getExpiredAt ()
    {
        return $this->expired_at;
    }

    public function generateCode ($elementId, $reason, $expiredAt = null)
    {
        // Check for existing code
        $existCodes = TempCodes::find([
            'element_id = :id: AND reason = :reason:',
            'bind' => ['id' => $elementId, 'reason' => $reason]
        ]);


        // Return existing code
        foreach ($existCodes as $tc) {
            if (strtotime($tc->expired_at) > time() + 600) { // Give user 10 minutes for activation
                return $tc->code;
            }
            $tc->delete(); // delete expired code
        }

        // Create New Code
        $this->element_id = $elementId;
        $this->reason     = $reason;
        $this->expired_at = $expiredAt;
        $loop             = false;
        $i                = 0;
        do {
            $loop = $this->save();
        } while ($loop == false && $i++ <= 3);

        if ($loop) {
            return $this->getCode();
        }
        else {
            throw new Exception($this->getMessages()[0]);
        }
    }
}