<?php
namespace Root\Core\Base;

use Illuminate\Validation\Factory as ValidatorFactory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class Action
{
    // Validation and Runtime Errors
    protected static $validationErrors = [];
    protected static $runtimeErrors = [];
    protected static $params = [];
    protected ValidatorFactory $validator;
    protected $user;

    // Constructor for Dependency Injection (Optional)
    public function __construct() {
        $this->validator = app('validator');
        $this->user = Auth::user();
    }

    // Adds a runtime error to the class
    public function AddRuntimeError(string $key, string $message, array $params = []): bool
    {
        self::$runtimeErrors[$key] = $message;
        self::$params = array_merge(self::$params, $params);
        return false;
    }

    // Validate the request data
    public function Validate(Request $request): bool
    {
        $data = is_array($request) ? $request : $request->all();
        $validation = $this->Validator($data);
        
        if ($validation->fails()) {

            $messages = $validation->errors()->toArray();
            $flattened = [];

            foreach ($messages as $field => $msgs) {
                $flattened[$field] = $msgs[0];
            }

            self::$validationErrors = $flattened;

            return false;
        }

        foreach ($data as $key => $value) {
            $this->{$key} = $value;
        }

        return true;
    }

    // Run validation on the provided data
    protected function Validator(array $data)
    {
        return $this->validator->make(
            $data,
            $this->Rules(),
            [],
            $this->AttributesLabel()
        );
    }

    // Success response
    public function Success(array $values = [])
    {
        return response()->json(array_merge(['success' => true], $values));
    }

    // Unsuccessful response with validation and runtime errors
    public function Unsuccessful()
    {
        return response()->json([
            'success' => false,
            'validationErrors' => self::$validationErrors,
            'runtimeErrors' => self::$runtimeErrors,
            'params' => self::$params
        ]);
    }

}
