<?php

namespace App\Http\Controllers\StockManagement;

use App\Exceptions\ServerStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\StockManagement\CRUDStockRequest;
use App\Models\ProductManagement\Category;
use App\Models\ProductManagement\Product;
use App\Models\StockManagement\AdjustmentOperation;
use App\Models\StockManagement\AdjustmentReason;
use App\Models\StockManagement\Stock;
use App\Models\StockManagement\Warehouse;
use App\Models\UserManagement\Admin;
use App\Models\UserManagement\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Yajra\DataTables\DataTables;


class StockController extends Controller{


    public function index(){
        $title = __("Manage Stock in Warehouses");
        $user = auth(activeGuard())->user();
        $managers = Admin::stockManagers(); // (collect) les users qui ont des permissions de gestions de stocks
        $tabs = config('stocks-management.tabs.stock'); // (array)

        $products = get_values(Product::get(),"full_name");
        $categories = Category::active()->get();
        $adjustmentsOperations = get_values(AdjustmentOperation::get(),"name","id");
        $adjustmentsReasons = get_values(AdjustmentReason::get(),"name","id");
        return view('backend.stocks.management.index',
            compact('title','tabs', "user", 'managers',"tabs",
               "adjustmentsOperations","categories","products","adjustmentsReasons"));
    }

    public function listOnWarehouse(){
//         $datas = Stock::with("product")->get();
//        return DataTables::of(Stock::with("product"))
        return datatables(Stock::with("product")->get())
            ->addIndexColumn()
            ->editColumn('qty', function ($row){
                return round($row->qty,2);
            })
            ->addColumn("action",function ($row){
                return view('backend.stocks.management.tabs.lots.blocs.datatable-actions',
                    compact("row"));
            })
            ->addColumn('user', function ($row){
                return $row->createdBy->nom_complet ?? "";
            })
            ->editColumn('expired_at', function ($row){
                return format_date($row->expired_at);
            })
            ->editColumn('product', function ($row){
                $product = $row->product;
                $category = $product->category->only(['id','name']);
                return [
                    'id' => $product->id ,
                    'name' => $product->name,
                    'fullName' => $product->fullName,
                    'category' => $category
                ];
            })
            ->addColumn('info', function ($row){
                $qty = format_amount($row->qty);
                $expired_at = format_date($row->expired_at);
                return "$row->lot_id / $qty / $expired_at";
            })
            ->only(["id","lot_id","product","qty","product_id","expired_at",'user',"action","warehouse_id","info"])
            ->make(true);
    }

    public function listGroupedByProduct(){

        $datas = Stock::with("product")
                       ->get()
                       ->groupBy("product_id")
                       ->map(function ($group){
                           $first = $group->first();
                           $product = $first->product;
                           return [
                               "product_id" => $first->product_id,
                               "name" => $product->name,
                               "qty" => $group->sum('qty'),
                               "lots_count" => count($group),
                               "category" => $product->category->name,
                           ];
                       });
        return datatables($datas)
            ->addIndexColumn()
            ->editColumn('qty', function ($row){
                return format_amount($row['qty']);
            })
           // ->only(["id","lot_id","product","qty","product_id","expired_at",'user',"action"])
            ->make(true);
    }

    /** Ajouter un lot dans un entrepot
     * @param CRUDStockRequest $request
     * @return JsonResponse
     */
    public function create(CRUDStockRequest $request){
      //  $data  = $request->get('data')[0] ?? [];
        $data  = $request->all();

        //PointDeVente ou Magasin
        $warehouse = Warehouse::findOrFail($data['warehouse_id']);
        return  DB::transaction(function () use ($data,$warehouse){
            try {

                $stock= $warehouse->stocks()
                                    ->create([
                                        "lot_id" => $data['lot_id'],
                                        "qty" => (float) $data['qty'],
                                        "expired_at" => format_date($data['expired_at'],"Y-m-d"),
                                        "product_id" => $data['product_id'],
                                    ]) ;

                $response['success'] = filled($stock);
                $response['message'] = action_message("create",$response['success']);
               return  response()->json($response,ServerStatus::SUCCESS);
            }catch (\Exception $exception){
                DB::rollBack();
                write_log("stocks/create",$exception,"error");
                return response()->json(["message" => general_error($exception)],ServerStatus::APPLICATION_ERROR);
            }
        });
    }

    public function update(Stock $stock){

    }

    public function delete(Stock $stock){}

    public function editColumn(Request $request, $column){
        $data  = $request->get('data') ?? [];

        $id = array_key_first($data);
        $data = $data[$id];
        $stock = Stock::find($id);
        $warehouse = $stock->warehouse; // PointDeVente
        $data['stock_id'] = $id;
        $stock_table = (new Stock)->getTable();
        $product_table = (new Product)->getTable();

        $rules = [
            "stock_id" => "required|exists:$stock_table,id",
        ];

        $validation_attributes = [
            'stock_id' => __("Id Stock"),
            'expired_at' => __("Date d'Expiration"),
            'product_id' => __("Id Produit"),
        ];

        $response = ["success" => false, "fieldErrors" => [],];

        $value = $data[$column];

        //si c'est la colonne 'lot_id' qu'on veut modifier
        if($column == "lot_id"){
            $rules['lot_id'] = ['required',"min:2"];

            $old_lot_id = $stock->lot_id;
            $new_lot_id = $value;
            $new_stock = $warehouse->stocks()
                                    ->firstWhere([
                                        'lot_id' => $new_lot_id,
                                        'product_id' => $stock->product_id
                                    ]) ;

//                                    ->where('lot_id',$new_lot_id)
//                                    ->where('product_id',$stock->product_id)
//                                    ->first();

            //si le nouveau lot existe déja sur le produit'
            if ($new_stock){
                $m = __("Le nouveau lot ':new' existe déjà sur le product ':product'.
                 Il est recommandé de faire plutôt un ajustement de :unit unité(s) sur le lot ':old' et un second sur le lot ':new'",
                    ['old' => $old_lot_id, "new" => $new_lot_id, "unit" => format_amount($stock->qty),
                        "product" => $stock->product->fullName,]);

                $response['fieldErrors'][] = [ "name" => $column, "status" => $m, ];
            }
        }
        elseif($column == "expired_at"){
            $rules['expired_at'] = ["required","date","date_format:d-m-Y"];
            $value = format_date($data[$column],"Y-m-d");
        }elseif ($column == "product_id"){
            $rules['product_id'] = ["required","exists:$product_table,id"];
        }

        $status = ServerStatus::SUCCESS;

        $validation = Validator::make($data,$rules,[],$validation_attributes); // (boolean)

        //validations Ok!
        if ($validation->passes()) {
            if (blank($response['fieldErrors'])){
                $response['success'] = $stock->update([$column => $value]);
            }
        }
        else{
            $response['fieldErrors'][] = [ "name" => $column, "status" => $validation->errors()->first(), ];
            $status = ServerStatus::UNPROCESSABLE_ENTITY;
        }
        return response()->json($response,$status);
    }

    public function editProductId(Request $request){
        return $this->editColumn($request,"product_id");
    }

    public function editLotId(Request $request){
        return $this->editColumn($request,"lot_id");
    }
    public function editExpiredAt(Request $request){
        return $this->editColumn($request,"expired_at");
    }
}
