<?php

namespace App\Http\History;

use App\Modules\Shared\Infraestructure\TestHandler;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Throwable;

class HistoryData
{

    /** @var int */
    public $historyTable;
    /** @var Request */
    public $request;
    /** @var int */
    public $operation;
    /** @var int */
    public $recordId;

    public $oldValue;
    /** @var int */
    public $newValue;
    /** @var int */
    public $newValueCache;

    /** @var array */
    private $params;


    public function __construct(int $historyTable)
    {
        $this->historyTable = $historyTable;
    }

    public function old(...$params)
    {
        return HistoryControllerProxy::Value_Old($this->historyTable, ...$params);
    }

    public function obtainOld(...$params)
    {
        try {
            if ($this->oldValue) {
                $this->oldValue = array_merge($this->oldValue, $this->old(...$params));
            } else {
                $this->oldValue = $this->old(...$params);
            }
            $this->params = $params;
        } catch (Throwable $ex) {
            // TestHandler::onTesting(fn () => dd($ex));
        }
        return $this;
    }

    public function obtainNew(...$params)
    {
        try {
            if ($this->newValueCache) {
                $this->newValueCache = array_merge($this->newValueCache, $this->old(...$params));
            } else {
                $this->newValueCache = $this->old(...$params);
            }
        } catch (Throwable $ex) {
        }
        return $this;
    }

    public function insertBasic(Request $request, $basic = true)
    {
        return $this->insert(
            [$request->all()],
            $request,
            0,
            $basic
        );
    }

    public function updateBasic($recordId, Request $request)
    {
        return $this->update($recordId, $this->oldValue, [$request->all()], $request);
    }

    public function deleteBasic($recordId, Request $request)
    {
        return $this->delete($recordId, $this->oldValue, $request);
    }

    public function insert($newValue, Request $request, $recordId = 0, $basic = true)
    {
        try {
            $this->request = $request;
            $this->operation = HistoryOperations::INSERT;
            if ($recordId == 0) {
                $found = DB::select('SELECT LAST_INSERT_ID() as Record_Id');
                $this->recordId = $found[0]->Record_Id;
                if ($basic) {
                    $newValue = $this->old($this->recordId);
                }
            } else {
                $this->recordId = $recordId;
            }

            $this->oldValue = json_encode([]);
            $this->newValue = json_encode($newValue);
            return HistoryControllerProxy::Insert($this);
        } catch (Throwable $ex) {
        }
    }

    public function update($recordId, $oldValue, $newValue, Request $request, $basic = true)
    {
        try {
            $this->request = $request;
            $this->operation = HistoryOperations::UPDATE;
            $this->recordId = $recordId;

            if ($basic) {
                $newValue = $this->old(...$this->params);
            }

            $this->newValue = json_encode($newValue);
            $this->oldValue = json_encode($oldValue);
            return HistoryControllerProxy::Insert($this);
        } catch (Throwable $ex) {
            // TestHandler::onTesting(fn () => dd($ex));
        }
    }

    public function delete($recordId, $oldValue, Request $request)
    {
        try {
            $this->request = $request;
            $this->operation = HistoryOperations::DELETE;
            $this->recordId = $recordId;
            $this->oldValue = json_encode($oldValue);
            $this->newValue = json_encode([]);
            return HistoryControllerProxy::Insert($this);
        } catch (Throwable $ex) {
        }
    }
}
