<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Log\Logger;
use Illuminate\Support\Arr;
use Log;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
use Symfony\Component\HttpKernel\Exception\HttpException;
use View;

/**
 * Class Handler
 * @package App\Exceptions
 */
class Handler extends ExceptionHandler
{
	/**
	 * A list of the exception types that are not reported.
	 *
	 * @var array
	 */
	protected $dontReport = [
	];

	/**
	 * A list of the inputs that are never flashed for validation exceptions.
	 *
	 * @var array
	 */
	protected $dontFlash = [
		'password',
		'password_confirmation',
	];

	/**
	 * @param Exception $exception
	 *
	 * @return mixed|void
	 * @throws Exception
	 */
	public function report(Exception $exception)
	{
		parent::report($exception);

		if (!env('LOG_SLACK_ENABLED', true)) {
			return;
		}

		if (!$this->shouldntReport($exception)) {
			/** @var Logger $channel */
			$channel = Log::channel('slack');
			$channel->critical($exception);

            $channel = Log::channel('database');
            $channel->critical($exception);
		}

        return;
	}

	/**
	 * @param Request $request
	 * @param Exception|HttpException $exception
	 *
	 * @return Response|SymfonyResponse
	 */
	public function render($request, $exception)
	{
        if ($request->ajax() || $request->wantsJson()) {

			if ($exception instanceof  AuthenticationException) {
			    $json = [
			        'success' => false,
                    'error' => [
                        'code' => 401,
                        'message' => $exception->getMessage()
                    ]
                ];
            } else {
                $json = [
                    'success' => false,
                    'error'   => [
                        'code'      => 500,
                        'exception' => get_class($exception),
                        'message'   => $exception->getMessage(),

                        'file'  => $exception->getFile(),
                        'line'  => $exception->getLine(),
                        'trace' => collect($exception->getTrace())->map(function ($trace) {
                            return Arr::except($trace, ['args']);
                        })->all(),
                    ],
                ];
            }

			return response()->json($json, 500);
		}

		return parent::render($request, $exception);
	}

	/**
	 * Rewrite errors view folder
	 *
	 * @return void
	 */
	protected function registerErrorViewPaths()
	{
		/** @TODO: Errors folder ??? 404 */
		$paths = collect(config('view.paths'));

		View::replaceNamespace('errors', $paths->map(function ($path) {
			return "{$path}/_errors";
		})->push(__DIR__ . '/views')->all());
	}

	/**
	 * Convert an authentication exception into a response.
	 *
	 * @param  Request $request
	 * @param  AuthenticationException $exception
	 */
	protected function unauthenticated($request, AuthenticationException $exception)
	{
		return $request->expectsJson()
            ? response()->json(['message' => $exception->getMessage()], 401)
            : redirect()->guest($exception->redirectTo());
	}
}
