<?php

namespace App\Http\Controllers;

use App\Models\Inventory;
use App\Models\Category;
use App\Notification;
use App\Models\Product;
use App\Models\Stock_Movement;
use App\Store;
use Illuminate\Http\Request;
use DB;
use Auth;

use App\Stock;
use Illuminate\Support\Facades\Session;
use Mockery\Exception;

class InventoryController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth');
    }


    public function index()
    {
        $stores = Store::all();

        $inventories = $this->getAllInventory();

        return view('inventories.index', compact('inventories', 'stores'));
    }


    public function getAllInventory()
    {
        $inventories = DB::table('products')
            ->join('stocks', 'stocks.product_id', '=', 'products.id')
            ->select('products.id', 'products.name', 'stocks.quantity', 'stocks.old_stock', 'new_stock', 'quantity', 'reorder_level', 'expiry_date')->get();
        return $inventories;
    }


    public function storeInventory(Request $request)
    {

        $storeId = $request->storeId;

        if ($storeId === 0) {
            $inventories = $this->getAllInventory();
            return view('includes.invLoad', compact('inventories'));
        } else {
//        $inventories = Inventory::where('store_id', $storeId);
            $inventories = DB::table('inventories')
                ->where('inventories.store_id', $storeId)
                ->join('stocks', 'stocks.product_id', '=', 'inventories.product_id')
                ->join('products', 'inventories.product_id', '=', 'products.id')
                ->select('products.id', 'products.name', 'inventories.total_stock', 'inventories.old_stock', 'inventories.new_stock', 'stocks.reorder_level', 'stocks.expiry_date')->get();
        }


//        dd($inventories);

        return view('includes.storeInventory', compact('inventories'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */



    public function member_all_inventories()
    {
        if (auth()->user()->role_id == 1)
        {
            $inventories = Inventory::all()->sortBy('name');
        }else{
            $inventories = Inventory::where('category_id', auth()->user()->role_id)->get()->sortBy('name');
        }

        return view('inventories.index', compact( 'inventories'));
    }

    public function member_new_inventory ()
    {
        $categories = Category::all();
        if (auth()->user()->role_id == 1)
        {
            $products = Product::all()->sortBy('name');
        }else{
            $products = Product::where('category_id', auth()->user()->role_id)->get()->sortBy('name');
        }

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

    public function member_unit_inventory ()
    {

        if (auth()->user()->role_id == 1)
        {
            $inventories = Inventory::all();
            return view('inventories.unit', compact('inventories'));
        }else{
            $inventories = Inventory::where('category_id', auth()->user()->role_id)->get();

//            dd($inventories);

        }
        return view('inventories.unit', compact('inventories'));
    }

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

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

        $inventory = new Inventory([
           'category_id' => $category_id,
            'quantity' =>$quantity,
            'product_id' => $product_id
        ]);

        try{
            $inventory->save();
            return redirect()->back()->with('success', 'The Inventory was created Successfully');
        }catch (Exception $exception)
        {
            return redirect()->back()->with('failed', 'The Inventory was not created. Pleae, try again.');
        }




    }

    public  function member_edit_inventory(Inventory $inventory)
    {
        $products = Product::all();
        $inventory = $inventory;

        return view('inventories.edit', compact('inventory', 'products'));
    }
    public  function member_update_inventory (Request $request)
    {
        $product_id = $request->product_id;

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

        $inventory->quantity = $request->quantity;
        $inventory->save();

        return redirect()->route('member_unit_inventory', auth()->user()->role_id)->with('success', 'Inventory Updated successfully');
    }

//    public  function getStoreInventory(Request $request){
//
//        if ($request->ajax()) {
//
//            if ($request->storeId === '0')
//            {
//
//            }else{
//                $storeId = $request->storeId;
//                $inventories = Inventory::where('store_id', $storeId)->first();
//
////                dd($products);
//                return view('includes.invLoad', compact('inventories'));
//            }
//
//        }
//    }

    public function addStock()
    {
        $products = Product::all();

        return view('inventory.addStock', compact('products'));

    }

//    updating quantity
    public function updateQuantity(Request $request)
    {
        $stock = Product::where('id', $request->productID)->first();
        $total = $request->quantity + $stock->quantity;
        $stock->quantity = $total;
        $stock->save();

        return redirect()->back()->with('status', 'New Stock Added to ' . strtoupper($stock->item_name) . '; with new quantity ' . $request->quantity . ' TOTAL = ' . $total);
    }

    //Assigning inventory
    public function assignInventory()
    {
        $products = Product::all();
        $stores = Store::all();
        return view('inventory.assign', compact('products', 'stores'));
    }


    public function storeRequest()
    {
        $products = Product::all();

        $sentRequest = $this->getSentRequest();

        $receivedRequest = $this->getReceivedRequest();

        $stores = Store::all();
        return view('inventories.request', compact('products', 'stores', 'sentRequest', 'receivedRequest'));
    }

    public function getSentRequest()
    {
        $sentRequest = Stock_Movement::where('store_id', Auth::user()->store_id)
            ->where('type', 'Request')
            ->orderBy('created_at', 'asc')
            ->get();

        return $sentRequest;
    }

    public function getReceivedRequest()
    {
        $receivedRequest = Stock_Movement::where('store_id', Auth::user()->store_id)
            ->where('type', 'Request')
            ->get();

        return $receivedRequest;

    }

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

        ]);

//        $storeId =  $request->storeID;

//        dd($storeId);

        $storeRequest = new Stock_Movement([
            'product_id' => $request->productID,
            'store_id' => Auth::user()->store_id,
            'quantity' => $request->quantity,
            'type' => 'REQUEST',
            'created_by' => auth()->user()->id,
            'updated_by' => auth()->user()->id,
        ]);

        $storeRequest->save();


        if ($storeRequest !== null) {
            $notifTitle = 'Request for stock';
            $message = 'A request has been made to you for some stock. If you have it and can fulfill the request, accept it and mark it shipped after sending.';

            $this->sendNotification($storeRequest->to_store_id, $notifTitle, $message);

            return redirect()->back()->with('success', 'Request sent successfully: monitor notifications for acceptance and transfers');
        } else {
            return redirect()->back()->with('failed', 'Request failed; try again ');
        }
    }

    public function storeTransfer()
    {
        $products = Product::all();
        $stores = Store::all();
        return view('inventories.transfer', compact('products', 'stores'));
    }


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

        $storeId = Session('store_id');


        $storeTransfer = new Stock_Movement([
            'product_id' => $request->productID,
            'from_store_id' => Session('store_id'),
            'quantity' => $request->quantity,
            'type' => 'Transfer',
            'to_store_id' => $storeId,
            'created_by' => auth()->user()->id,
            'updated_by' => auth()->user()->id,
        ]);

        $deducted = $this->deductStock($request->productID, $request->quantity);
        $deductedInventory = $this->deductInventory($request->productID, $request->quantity);


        if ($deducted !== 'fail' && $deductedInventory !== 'fail') {
            $storeTransfer->save();
            $creditStock = $this->creditStock($storeTransfer->product_id, $storeTransfer->to_store_id, $storeTransfer->quantity);


            return redirect()->back()->with('success', 'Stock Transferred successfully: ship and await notifications for acceptance and delivery');
        } else {
            return redirect()->back()->with('failed', 'Transfer failed -  stock may be less in quantity or your connection; check and try again ');
        }
    }


    public function checkAvailability($productID, $quantity)
    {
        $product = Product::where('id', $productID)->first();
        if ($product != null && $product->quantity >= $quantity) {
            return 'success';
        } else {
            return $product->quantity;
        }
    }


    public function deductStock($stockID, $quantity)
    {

        $stock = Stock::where('product_id', $stockID)->first();

//        dd($stock);

        if ($stock != null) {

            $stock->quantity -= $quantity;

            $stock->save();

//

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

    public function deductInventory($stockID, $quantity)
    {

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

//        dd($inventory);

        if ($inventory != null) {

            $inventory->total_stock -= $quantity;
            $inventory->updated_by = Auth::user()->id;

            $inventory->save();

//

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

    public function creditStock($productId, $storeId, $quantity)
    {
        $stockCredit = Stock::where('store_id', $storeId)
            ->where('product_id', $productId)
            ->first();

        if (isset($stockCredit) && $stockCredit != null) {
            $stockCredit->quantity -= $quantity;
            $stockCredit->save();

            return true;
        } else {
            return false;
        }


    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */

    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Inventory $inventory
     * @return \Illuminate\Http\Response
     */
    public function show(Inventory $inventory)
    {
        //
    }

    public function sendNotification($toId, $title, $body)
    {
        $notification = new Notification([
            'from_id' => Session('store_id'),
            'to_id' => $toId,
            'title' => $title,
            'body' => $body,
            'created_by' => Auth::user()->id,
            'updated_by' => Auth::user()->id,
        ]);

        $notification->save();

        if ($notification !== null) {
            return 'success';
        } else {
            return 'fail';
        }
    }


    public  function deplete_inventory($product_id, $quantity, $inventory)
    {
//        dd($product_id, $quantity, $inventory);
        $inventory_depleted = Inventory::where('product_id', $product_id)
            ->where('category_id', auth()->user()->role_id)->first();
//        dd($inventory_depleted);

        $inventory_depleted->quantity -= $quantity;
        $inventory_depleted->save();

        return $inventory;
    }
}
