<?php


namespace App\Models\StockManagement\Traits;


use App\Exceptions\Stocks\StockCannotAjustableException;
use App\Models\StockManagement\Adjustment;
use App\Models\StockManagement\AdjustmentOperation;
use App\Models\StockManagement\AdjustmentReason;
use App\Models\StockManagement\Stock;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

trait Ajustable{

    public function adjustments(){
        return $this->hasMany(Adjustment::class,Stock::FK_ID);
    }


    public function adjust($data){
        $stock_id = $this->id;
        $qty_adjusted = (float) $data["qty_adjusted"];
        $operation_code = $data["operation_code"];
        $operation = AdjustmentOperation::find($operation_code);
        $errors = ["fieldErrors" => [],"messages" => []];

        $stock_table = (new Stock)->getTable();
        $stock = Stock::whereId($stock_id)->lockForUpdate()->firstOrFail();

        $data["qty_before"] = $stock->qty;

        $inputs = [
            'qty_adjusted' =>  ['required', "numeric"],
            'qty_before' =>    ['nullable', "numeric" ],
            'info' =>    ['nullable'],
            'stock_id' =>     ['required' , "exists:$stock_table,id,deleted_at,NULL"],
             "reason_code" => ['required' , "string", Rule::in(AdjustmentReason::all()->pluck("id")->toArray())],
             "operation_code" => ['required' , "string", Rule::in(AdjustmentOperation::all()->pluck("id")->toArray())],
            'comment' => ['required',"min:2"],
        ];
        $validation_attributes = [
            'stock_id' => __("Stock Id"),
            'qty_adjusted' => __("Adjusted Qty"),
            'qty_before' => __("Stock Qty"),
            'info' => __("Stock Qty"),
            "reason_code" => __("Reason"),
            "operation_code" => __("Operation"),
            'comment' => __("Comment"),
        ];
        if ($operation_code == AdjustmentOperation::INPUT){
            $inputs['qty_adjusted'][] = "max:$stock->qty ";
            if ($stock->qty <= 0){
                $inputs['qty_before'][] = "min:1";
            }
        }
        $is_success = false;
        $data['stock_id'] = $stock_id;
        $validation = Validator::make($data,$inputs,[],$validation_attributes); // (boolean)

        //validations Ok!
        if ($validation->passes()) {
            try {

                $data['created_by'] = auth()->id();

                //Qté restante avant l'ajustement
                $data['qty_before'] = $stock->qty;

                $adjuster = $data['adjuster'] ?? null;
                if (filled($adjuster)){
                    $data['adjuster_id'] = $adjuster->getKey();
                    $data['adjuster_type'] = $adjuster->getMorphClass();
                }

                $action = $operation->action; // 'increment'
                //met a jour le stock en fonction de l'opération
                $stock->{$action}('qty' , $qty_adjusted); // $stock->increment('qty',200);

                //Qte restante après l'ajustement
                $data['qty_after'] = $stock->qty;

                unset($data['adjuster']);

                //enregistre l'ajustement
                $adjustment = $stock->adjustments()->create($data);// App\Models\Adjustment

                $is_success = ($adjustment); // true
            }catch (\Exception $exception){
                $errors['exception'] = $exception;
                write_log("stocks/adjustments/create",$exception,"error");
            }
        }else{
            $validationErrors = $validation->errors();
            $errors['messages'] = $validationErrors->all();
           // dd($validationErrors->messages(),$data,$inputs);

            foreach ($validationErrors->messages() as $name => $error ) {
                $errors['fieldErrors'][] = [ "name" => $name,"status" => $error[0] ];
            }
        }
        return [
            "success" => $is_success,
            "errors" => $errors
        ];
    }

}
