<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class UserException extends Exception
{
    protected $errors;
    protected $status_code;
    protected $headers;
    protected $data;
    public static $errorList = [];

    //
    public function __construct(int $code = 1, $message = 'error', $errors = [], int $status_code = 400, array $headers = [], array $data = [])
    {
        parent::__construct();
        $code = sprintf("%03d", $code);
        $code = ($this->getCodePrefix() . $code);
        $this->status_code = $status_code;
        $this->code = (int)($code);
        $this->message = $this->getDefaultMessage($code, $message);
        $this->errors = $errors;
        $this->headers = $headers;
        $this->data = $data;
    }

    public function getCodePrefix(): int
    {
        return 1;
    }

    public static function invalid($request, $exception)
    {
        $data = [
            'errors' => $exception->errors,
            'message' => $exception->getMessage(),
            'code' => $exception->getCode(),
            'status_code' => $exception->getStatusCode(),
            'data' => $exception->getData(),
        ];
        return response()->json($data, $exception->getStatusCode(),
            $exception->getHeaders());
    }

    public function getDefaultMessage($code, $message = '')
    {
        if (filled($message)) {
            return $message;
        }
        return self::$errorList[$code] ?? ($this->message ?? '');
    }

    public static function render(Request $request, self $exception)
    {
        return $request->expectsJson() ? self::invalidJson($exception) : self::invalid($request, $exception);
    }

    public function getStatusCode(): int
    {
        return $this->status_code;
    }

    public function getData()
    {
        return $this->data;
    }

    public function getHeaders(): array
    {
        return $this->headers;
    }

    /**
     * 无效json
     *
     * @param  $exception
     * @param string $lang
     * @return \Illuminate\Http\JsonResponse
     */
    public static function invalidJson(self $exception)
    {
        $data = [
            'errors' => $exception->errors,
            'message' => $exception->getMessage(),
            'code' => $exception->getCode(),
            'status_code' => $exception->getStatusCode(),
            'data' => $exception->getData(),
        ];
        if (app()->environment(['local'])) {
            $data['trace'] = $exception->getTrace();
            $data['time'] = microtime(true) - LARAVEL_START;
        }
        return response()->json($data, $exception->getStatusCode(),
            $exception->getHeaders());
    }
}
