<?php

namespace App\Helpers;

class ApiRespond
{
    private $errorMessages;

    private $successMessages;

    public function __construct()
    {
        $this->errorMessages = [
            'default' => __('general.errorMessages.default'),
            'update' => __('general.errorMessages.update'),
            'create' => __('general.errorMessages.create'),
            'delete' => __('general.errorMessages.delete')
        ];
        $this->successMessages = [
            'default' => __('general.successMessages.default'),
            'update' => __('general.successMessages.update'),
            'create' => __('general.successMessages.create'),
            'delete' => __('general.successMessages.delete')
        ];
    }

    private $status;
    private $message;
    private $code = 200;
    private $data = [];

    private function getCallerAttribute()
    {
        /**
         * debug_backtrace - generates a PHP backtrace. (returns everything to the last trace). 
         *  - first argument takes true/false that tells if it should provide an object of the backtrace object. (We dont need it here)
         *  - second argument takes an integer that is the limit of backtraces returned. (default 0, returns all)
         */

        $calledClass = debug_backtrace(0, 2)[1]['file'];
        $arr = explode(DIRECTORY_SEPARATOR, $calledClass);
        $className = str_replace("Controller.php", "", end($arr));
        return $className;
    }

    private function getCallerClass()
    {
        $obj  = debug_backtrace(0, 2)[1]['file'];

        preg_match("/app\/Http\/Controllers\/.*/", $obj, $matches);
        $relativeControllerNamespace = ucfirst(str_replace(".php", "", $matches[0]));
        $relativeControllerNamespace = str_replace("/", "\\", $relativeControllerNamespace);

        //call the function to initialize the messages that should be read from the language files
        //according to the selected locale. The locale is setup in middleware, thus the 
        //messages couldn't have been set in the controller's constructor
        if (method_exists($relativeControllerNamespace, 'initMessages')) {
            $relativeControllerNamespace::initMessages();
        }

        // $arr = explode(DIRECTORY_SEPARATOR, $obj);
        return  $relativeControllerNamespace;
    }

    public function message($message)
    {
        $this->message = $this->status
            ? ($this->getCallerClass()::$successMessages[$message]  ?? $this->successMessages['default'])
            : ($this->getCallerClass()::$errorMessages[$message] ?? $this->errorMessages['default']);
        return $this;
    }

    public function success()
    {
        $this->status = true;
        $this->message = $this->successMessages['default'];
        return $this;
    }

    public function error()
    {
        $this->status = false;
        $this->message = $this->errorMessages['default'];
        return $this;
    }

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

    public function updatedMessage()
    {
        $this->message = str_replace(":attribute", strtolower($this->getCallerAttribute()), $this->status ? $this->successMessages['update']  : $this->errorMessages['update']);
        return $this;
    }

    public function deletedMessage()
    {
        $this->message = str_replace(":attribute", strtolower($this->getCallerAttribute()), $this->status ? $this->successMessages['delete']  : $this->errorMessages['update']);
        return $this;
    }

    public function createdMessage()
    {
        $this->message = str_replace(":attribute", strtolower($this->getCallerAttribute()), $this->status ? $this->successMessages['create']  : $this->errorMessages['create']);
        return $this;
    }

    public function customMessage($message)
    {
        $this->message = $message;
        return $this;
    }

    public function code($code)
    {
        $this->code = $code;
        return $this;
    }

    public function send()
    {
        return response()->json(
            [
                'success' => $this->status,
                'message' => $this->message,
                'data' => $this->data
            ],
            $this->code
        );
    }
}
