<?php

namespace App\Http\Controllers;

use App\Models\Inventory;
use App\Models\Product;
use App\Models\Stock;
//use function GuzzleHttp\Promise\all;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Mockery\Exception;
use phpDocumentor\Reflection\Types\Void_;

class StockController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Application|Factory|View|Response
     */
    public function member_all_stocks()
    {
        $stocks = Stock::all();

        return view('stock.index', compact('stocks'));
    }


    public function member_new_stock()
    {
        $products = Product::all()->sortBy('name');

        return view('stock.new', compact('products'));
    }

    public function member_add_inventory()
    {
        $products = Product::all()->sortBy('name');

        return view('stock.create', compact('products'));
    }


    public function member_save_stock(Request $request)
    {
        $request->validate([
            'product_id' =>'required:integer',
            'quantity' =>'required:integer',
        ]);

        $product_id = $request->product_id;
        $quantity = $request->quantity;

        $inventory = Inventory::where('product_id', $product_id)->first();

        if ($inventory)
        {
            $inventory->quantity += $quantity;

            try{
                $inventory->save();
                return redirect()->route('member_unit_inventory', auth()->user()->role_id)->with('success', 'Inventory Added successfully');
            }catch (Exception $exception){
                return redirect()->back()->with('fail', 'the stock was not updated, contact admin');
            }

        }
        $products = Product::all()->sortBy('name');
        return view('stock.create', compact('products'));
    }


    //Assigning inventory
    public function assign()
    {
        $products = Product::all();
        $stores = Store::all();

//        dd($stocks);
        return view('inventories.assign', ['products' => $products, 'stores' => $stores]);
    }


    // Saving the inventory

    public function saveAssignedInventory(Request $request)
    {
        $this->validate($request, [
            'quantity' => 'required',
            'productID' => 'required',
            'storeID' => 'required',
        ]);

        $couldDeduct = $this->checkAvailability($request->input('productID'), $request->input('quantity'));

        if ($couldDeduct === 'success') {
            $assignedStock = Inventory::where('store_id', $request->storeID)
                ->where('product_id', $request->productID)->first();

            if ($assignedStock == null) {
                $assignedStock = new Inventory([
                    'store_id' => $request->input('storeID'),
                    'product_id' => $request->input('productID'),
                    'old_stock' => 0,
                    'new_stock' => $request->input('quantity'),
                    'total_stock' => $request->input('quantity'),
                    'created_by' => Auth::user()->id,
                ]);

                $this->deductStock($request->input('productID'), $request->input('quantity'));

            } else {
                $assignedStock->store_id = $request->input('storeID');
                $assignedStock->product_id = $request->input('productID');
                $assignedStock->old_stock = $assignedStock->total_stock;
                $assignedStock->new_stock = $request->input('quantity');
                $assignedStock->total_stock = $assignedStock->old_stock + $request->input('quantity');

                $deduct = $this->deductStock($request->input('productID'), $request->input('quantity'));
            }

            $assignedStock->save();

//            dd($assignedStock);


            return redirect()->back()->with('success', 'New ' . $request->quantity . 'Stock  Assigned to ' . $assignedStock->store['name'] . ' TOTAL = ' . $assignedStock->total_stock);

        } else {
            return redirect()->back()->with('failed', 'Quantity Assigned is more than Stock Available: AVAILABLE = ' . $couldDeduct);
        }
    }


    public function checkAvailability($productID, $quantity): string
    {
        $stock = Stock::where('product_id', $productID)->first();
        if ($stock != null && $stock->quantity >= $quantity) {
            return 'success';
        } else {
            return 'failed';
        }
    }


    public function deductStock($stockID, $quantity): string
    {
        $stock = Stock::where('product_id', $stockID)->first();

        if ($stock != null) {

            $stock->quantity = $stock->quantity - $quantity;

            $stock->save();

//

            return 'success';
        } else {
            return 'fail';
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Factory|Application|View
     */
    public function create()
    {
        $stocks = Product::all();
        $suppliers = Supplier::all();
        $stores = Store::all();

        return view('stock.create', compact('stocks', 'suppliers', 'stores'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param Request $request
     * @return RedirectResponse
     */
    public function store(Request $request): RedirectResponse
    {

        $item = Stock::where('product_id', $request->product)->first();
        if ($item === null) {

            $oldStock = 0;
            $lastCost = null;
            $lastSales = null;

            $stock = new Stock([
                'product_id' => $request->product,
                'supplier_id' => $request->supplier,
                'old_stock' => $oldStock,
                'new_stock' => $request->quantity,
                'cost_price' => $request->costPrice,
                'last_sales_price' => $lastSales,
                'last_cost_price' => $lastCost,
                'sales_price' => $request->sales_price,
                'vat' => $request->vat,
                'quantity' => $oldStock + $request->quantity,
                'expiry_date' => $request->expiry,
                'reorder_level' => $request->reorder,
                'created_by' => Auth::user()->id,
                'updated_by' => Auth::user()->id
            ]);

            $stock->save();

            return redirect()->back()->with('success', 'Stock  Created Successfully');

        } else {
            $oldStock = $item->quantity;
            $lastCost = $item->cost_price;
            $lastSales = $item->sales_price;

            $item->supplier_id = $request->supplier;
            $item->old_stock = $oldStock;
            $item->new_stock = $request->quantity;
            $item->quantity = $oldStock + $request->quantity;
            $item->cost_price = $request->costPrice;
            $item->sales_price = $request->sales_price;
            $item->last_cost_price = $lastCost;
            $item->last_sales_price = $lastSales;
            $item->vat = $request->vat;
            $item->updated_by = Auth::user()->id;

            $item->save();
            return redirect()->back()->with('success', 'Stock  Updated Successfully');
        }
    }

    /**
     * Display the specified resource.
     *
     * @param Stock $stock
     * @return void
     */
    public function show(Stock $stock)
    {

        dd($stock);
//        return view('stock.show');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param Stock $stock
     * @return Response
     */
    public function edit(Stock $stock): Response
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param Request $request
     * @param Stock $stock
     * @return Response
     */

    public function update(Request $request, Stock $stock): Response
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param Stock $stock
     * @return Response
     */
    public function destroy(Stock $stock): Response
    {
    }

}
