<?php

namespace Velis\Bpm\Workflow\Handler;

use Velis\Bpm\Workflow\Handler;
use Velis\Bpm\Workflow;
use User\User;
use Ticket\Notification;
use Velis\Lang;
use Exception;

/**
 * Ticket observer workflow handler
 * @author Olek Procki <olo@velis.pl>
 */
class TicketObserver extends Handler
{
    use TicketContextPostTrait;

    /**
     * Can be overriden by subclass
     * @var bool
     */
    protected $_sendNotification = false;

    /**
     * User array
     * @var array Velis\User
     */
    protected static $_users = [];


    /*
     * Handler execution method
     *
     * @param \Velis\Bpm\Ticket\Ticket $subject
     * @param mixed $additionalData
     */
    public function run($subject, $additionalData)
    {
        $this->_ticket = $subject;
        $this->_additionalData = $additionalData;

        if (array_key_exists($this['user_id'], self::$_users)) {
            $observer = self::$_users[$this['user_id']];
        } else {
            $observer = User::bufferedInstance($this['user_id']);
            self::$_users[$this['user_id']] = $observer;
        }

        if ($observer && !$observer->isActive()) {
            return;
        }

        if ($subject->isObserver($observer)) {
            $this->notice(
                $subject,
                $additionalData,
                'User is an observer already'
            );
        } else {
            $logId = $subject->addObserver($observer);

            if ($logId && $post = $this->_getPost()) {
                if (!$post->id()) {
                    $post->on('add', function ($post) use ($logId) {
                        $post->connectLogs([$logId]);
                    });
                } else {
                    $post->connectLogs([$logId]);
                }
            }

            if ($this->_sendNotification) {
                $observers = $subject->getObservers();
                try {
                    $notification = new Notification(
                        $subject,
                        Notification::TICKET_OBSERVER_ADDED
                    );
                    $notification->send($observers[$observer]);
                    $this->success($subject, $additionalData);
                } catch (Exception $e) {
                    $this->error($subject, $additionalData, $e);
                }
            } else {
                $this->success($subject, $additionalData);
            }
        }
    }


    /**
     * Returns parameters reflection info
     * @return array
     */
    public static function getParamsReflection()
    {
        return array(
            'user_id' => array(
                'label' => Lang::get('GENERAL_USER'),
                'type'  => Workflow::PARAM_USER
            )
        );
    }
}
