<?php

namespace Velis\Mvc\Controller;

use Velis\App;
use Velis\Filter;
use Velis\Http\Response;
use Velis\Output;

/**
 * This trait may be used for controllers with JSON data exchange only
 * @author Olek Procki <olo@velis.pl>
 */
trait JsonAwareTrait
{
    /**
     * Http response
     */
    protected $responseData = [
        'code'    => '',
        'message' => '',
        'error'   => '',
    ];

    /**
     * Controller initialization appending filter with data sent with raw json
     */
    public function onConstruct()
    {
        parent::onConstruct();

        $this->noRender();

        if (strpos($this->request->getContentType(), 'application/json') !== false) {
            if ($rawBody = $this->request->getJsonRawBody(true)) {
                $filter = $this->_filter->getRawCopy();
                $this->_filter = new Filter(array_merge($filter, $rawBody));
            }
        }

        $revNo = getenv('JS_REVISION_NO') ?: App::$config->js->revisionNo;

        $this->response->setContentType('application/json');
        $this->response->setHeader('X-Revision-No', $revNo);
    }

    /**
     * responseSuccess
     *
     * @param mixed $data
     * @param string
     * @return Response
     */
    private function responseSuccess($data = null, $message = '')
    {
        if ($data) {
            $this->responseData['result'] = $data;
        }

        $this->responseData['code'] = 200;
        $this->responseData['message'] = $message;

        return $this->send();
    }

    /**
     * responseDeny
     *
     * @param string $message
     * @param string $redirect
     * @return Response
     */
    public function responseDeny($message = 'Permission denied', $redirect = '')
    {
        $this->responseData['code']     = 403;
        $this->responseData['redirect'] = $redirect;
        $this->responseData['error']    = $message;

        return $this->send();
    }

    /**
     * responseNotFound
     *
     * @param string
     * @return Response
     */
    public function responseNotFound($message = 'Not found')
    {
        $this->responseData['code']  = 404;
        $this->responseData['error'] = $message;

        return $this->send();
    }

    /**
     * @param string $message
     * @param int $code
     * @return Response
     */
    public function responseError($message = 'Error', $code = 500, $data = null)

    {
        if ($data) {
            $this->responseData['result'] = $data;
        }

        $this->responseData['code']  = $code;
        $this->responseData['error'] = $message;

        return $this->send();
    }

    /**
     * Sends response
     */
    private function send()
    {
        if (App::devMode()) {
            $dbProfiler = App::$di['db']->getProfiler();
            $dbProfilerInfo = $dbProfiler->flushAllRows();
            $this->responseData['profiler'] = $dbProfilerInfo;
        }

        $response = Output::jsonEncode($this->responseData);

        $this->response
            ->setStatusCode($this->responseData['code'])
            ->setContent($response)
        ;

        return $this->response;
    }
}
