<?php

namespace ModStart\Core\Input;

use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Log;
use ModStart\Core\Exception\BizException;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\View;

class Response
{
    /**
     * 从另外一个接口返回data数据
     * 如果ret是一个标准错误会抛出BizException异常，该异常会被同一捕获
     * 如果ret是一个JsonResponse，会尝试获取实际值
     *
     * @param $ret
     * @param $key
     * @return mixed
     * @throws BizException
     */
    public static function tryGetData($ret, $key = null)
    {
        if ($ret instanceof JsonResponse) {
            $ret = $ret->getData(true);
        }
        if (!isset($ret['code'])) {
            BizException::throws('ERROR_RESPONSE');
        }
        if ($ret['code']) {
            BizException::throws($ret['msg']);
        }
        if (null !== $key) {
            if (!isset($ret['data'][$key])) {
                BizException::throws('data not exists ' . $key);
            }
            return $ret['data'][$key];
        }
        return isset($ret['data']) ? $ret['data'] : null;
    }

    public static function isSuccess($result)
    {
        if ($result instanceof JsonResponse) {
            $result = $result->getData(true);
        }
        return (isset($result['code']) && 0 === $result['code']);
    }

    public static function isError($result)
    {
        return !self::isSuccess($result);
    }

    public static function generate($code, $msg, $data = null, $redirect = null)
    {
        if (null === $redirect) {
            if ($_redirect = trim(Input::get('_redirect'))) {
                $redirect = $_redirect;
            }
        }
        $response = [
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
            'redirect' => $redirect,
        ];
        if (null === $data) {
            unset($response['data']);
        }
        if (null === $redirect) {
            unset($response['redirect']);
        }
        return $response;
    }

    public static function generateSuccessPaginate($page, $pageSize, $paginateData)
    {
        return self::generateSuccessPaginateData($page, $pageSize, $paginateData['records'], $paginateData['total']);
    }

    public static function generateSuccessPaginateData($page, $pageSize, $records, $total, $maxRecords = -1)
    {
        return self::generateSuccessData([
            'page' => $page,
            'pageSize' => $pageSize,
            'records' => $records,
            'total' => $total,
            'maxRecords' => $maxRecords,
        ]);
    }

    public static function generateSuccessData($data)
    {
        return self::generate(0, 'ok', $data);
    }

    public static function generateSuccess($msg = 'ok')
    {
        return self::generate(0, $msg);
    }

    public static function generateError($msg = 'error', $data = null, $redirect = null)
    {
        return self::generate(-1, $msg, $data, $redirect);
    }

    public static function jsonSuccessData($data)
    {
        return self::json(0, 'ok', $data);
    }

    public static function jsonSuccess($msg = 'ok')
    {
        return self::json(0, $msg);
    }

    public static function jsonError($msg = 'error')
    {
        return self::json(-1, $msg);
    }

    public static function jsonException(\Exception $e)
    {
        return self::jsonError($e->getMessage());
    }

    public static function json($code, $msg, $data = null, $redirect = null)
    {
        $response = [
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
            'redirect' => $redirect,
        ];
        if (null === $redirect) {
            unset($response['redirect']);
        }
        return \Illuminate\Support\Facades\Response::json($response);
    }

    public static function jsonFromGenerate($ret)
    {
        if ($ret instanceof JsonResponse) {
            return $ret;
        }
        if ($ret['code']) {
            return self::json($ret['code'], $ret['msg'], isset($ret['data']) ? $ret['data'] : null, isset($ret['redirect']) ? $ret['redirect'] : null);
        }
        if (!isset($ret['msg'])) {
            $ret['msg'] = null;
        }
        return self::json($ret['code'], $ret['msg'], isset($ret['data']) ? $ret['data'] : null, isset($ret['redirect']) ? $ret['redirect'] : null);
    }

    public static function jsonIfGenerateSuccess($ret, $msg = 'ok', $data = null, $redirect = null)
    {
        if ($ret['code']) {
            return self::json($ret['code'], $ret['msg'], empty($ret['data']) ? null : $ret['data'], empty($ret['redirect']) ? null : $ret['redirect']);
        }
        return self::json(0, $msg, $data, $redirect);
    }

    public static function jsonRaw($data)
    {
        return \Illuminate\Support\Facades\Response::json($data);
    }

    public static function jsonp($data, $callback = null)
    {
        if (empty($callback)) {
            $callback = \Illuminate\Support\Facades\Input::get('callback', null);
        }
        if (empty($callback)) {
            return \Illuminate\Support\Facades\Response::json($data);
        }
        return \Illuminate\Support\Facades\Response::jsonp($callback, $data);
    }

    public static function sendIfGenerateSuccess($ret, $msg = 'ok', $data = null, $redirect = null)
    {
        if ($ret['code']) {
            return self::send($ret['code'], $ret['msg'], empty($ret['data']) ? null : $ret['data'], empty($ret['redirect']) ? null : $ret['redirect']);
        }
        return self::send(0, $msg, $data, $redirect);
    }

    public static function sendFromGenerate($ret)
    {
        return self::send($ret['code'], empty($ret['msg']) ? null : $ret['msg'], empty($ret['data']) ? null : $ret['data'], empty($ret['redirect']) ? null : $ret['redirect']);
    }

    public static function sendError($msg, $data = null, $redirect = null)
    {
        return self::send(-1, $msg, $data, $redirect);
    }

    public static function sendException(\Exception $e)
    {
        return self::sendError($e->getMessage());
    }

    public static function page404()
    {
        if (\Illuminate\Support\Facades\Request::ajax()) {
            return self::json(-1, L('Page Not Found'));
        } else {
            return abort(404, L('Page Not Found'));
        }
    }

    public static function pagePermissionDenied($msg = null)
    {
        if (\Illuminate\Support\Facades\Request::ajax()) {
            return self::json(-1, $msg ? $msg : L('No Permission'));
        } else {
            return abort(403, $msg ? $msg : L('No Permission'));
        }
    }

    public static function quit($code, $msg, $data = null, $redirect = null)
    {
        $response = [
            'code' => $code,
            'msg' => $msg,
            'redirect' => $redirect,
            'data' => $data
        ];
        if (null === $redirect) {
            unset($response['redirect']);
        }
        if (\Illuminate\Support\Facades\Request::ajax()) {
            header('Content-Type: application/json; charset=UTF-8');
            echo json_encode($response);
        } else {
            header('Content-Type: text/html; charset=UTF-8');
            echo View::make('modstart::core.msg.msg', $response)->render();
        }
        exit();
    }

    public static function redirect($redirect)
    {
        return self::send(0, null, null, $redirect);
    }

    public static function send($code, $msg, $data = null, $redirect = null)
    {
        if (\Illuminate\Support\Facades\Request::ajax()
            || Request::headerGet('is-ajax', false)
            || (($headerAccept = Request::headerGet('accept')) && $headerAccept == 'application/json')
        ) {
            return self::json($code, $msg, $data, $redirect);
        } else {
            if (empty($msg) && $redirect) {
                return app('redirect')->away($redirect);
            }
            $response = [
                'code' => $code,
                'msg' => $msg,
                'redirect' => $redirect,
                'data' => $data
            ];
            if (null === $redirect) {
                unset($response['redirect']);
            }
            return view('modstart::core.msg.msg', $response);
        }
    }

    public static function download($filename, $content, $headers = [], $filenameFallback = null)
    {
        $response = new \Illuminate\Http\Response($content);
        $disposition = $response->headers->makeDisposition(
            \Symfony\Component\HttpFoundation\ResponseHeaderBag::DISPOSITION_ATTACHMENT,
            $filename,
            $filenameFallback
        );
        $response->headers->set('Content-Disposition', $disposition);
        foreach ($headers as $k => $v) {
            $response->headers->set($k, $v);
        }
        return $response;
    }

    public static function raw($content, $headers = [])
    {
        $response = new \Illuminate\Http\Response($content);
        foreach ($headers as $k => $v) {
            $response->headers->set($k, $v);
        }
        return $response;
    }
}
