<?php
namespace App\Http\Controllers\Stock;

use App\Models\Stock\Sale;
use App\Models\Stock\Client;
use Illuminate\Http\Request;
use App\Models\Stock\Payment;
use App\Models\Stock\Product;
use App\Models\Stock\Proforma;
use App\Models\Stock\SaleItem;
use App\Models\Stock\DeriveryNote;
use App\Models\Stock\ProformaItem;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use App\Notifications\ChannelServices;
use App\Models\Stock\DeriveryNoteItems;
use Illuminate\Support\Facades\Notification;

class ProformaController extends Controller
{
    /**
     * Return proformas
     * @param Request $request
     * @return JsonResponse
     */
    public function index(Request $request, $reference = NULL)
    {
        $from = $request->input('from');
        $to = $request->input('to');
        if (empty($from)) {
            $from = date('Y-m-d');
        }
        
        $result = Proforma::select('*')->with('creator', 'client');
        if (!empty($status = \request()->query('status'))) {
            $result->where('status', $status);
        }

        if (!empty($client = $request->input('client'))) {
            $result->where('client_id', $client);
        }

        if (!empty($status = $request->input('status'))) {
            if($status!="CANCELLED"){
                $result->where('status', $status);
            }else{
                $result->withTrashed();
            }
        }
        if (empty($reference)) {
            if (empty($to)) {
                $result->where('date_initiated', $from);
            } else {
                $result->where('date_initiated', '>=', $from)
                    ->where('date_initiated', '<=', $to);
            }
        } 

        if (!empty($reference)) {
            $result->where('reference', $reference);
        }

        return response()->json([
            'status' => 1,
            'rows'   =>  $result->orderBy('status', 'ASC')
                            ->orderBy('id', 'DESC')
                            ->paginate(\request()->query('per_page') ?? 45)
        ]);
    }

    /**
     * Store Proforma Item
     * @param Request $request
     * @return JsonResponse
     */
    public function store(Request $request)
    {
        $items = json_decode($request->input('items'));
        $datas = [
            'date_initiated' =>  $request->input('date_initiated'),
            'client_id'     => is_numeric($request->input('client_id')) ? $request->input('client_id') : NULL,
            'amount'        => $request->input('amount'),
            'status'        => 'PENDING',
            'DocReference' => strtoupper($request->input('DocReference'))
        ];

        if ($request->has('proforma_id')) {
            $Proforma = Proforma::find($request->input('proforma_id'));
            $this->draftSaleItems($Proforma, 'edit');
            Proforma::where('id', $Proforma->id)->update($datas);
        }else{
            $datas = array_merge($datas, [
                'reference'   => generateRowCode(20),
                'code' => createTransactCode('PFI')
            ]);
            $Proforma = Proforma::create($datas);
        }

        foreach($items as $item){
            ProformaItem::create([
                'proforma_id' => $Proforma->id,
                'product_id'    => $item->id,
                'batch'    => $item->batch,
                'requested_qty' => $item->quantity,
                'price' => $item->private_price,
                'received_qty'  => 0
            ]);
        }
        
        $currentUser = auth()->user();
        $users = getNotifiableUsers($currentUser);
        $itemsCount = sizeof($items);
        $client = Client::find($request->input('client_id'));
        $clientName = $client ? $client->name:'Walk-In';
        $data = [
            'id'   => $Proforma->id,
            'slug' => $Proforma->reference,
            'type' => 'Proforma',
            'link' => 'proforma',
            'message' => "New Proforma from <b>{$clientName}</b> of <b>{$itemsCount}</b> items created by <b>{$currentUser->name}</b>" 
        ];
        Notification::sendNow($users, new ChannelServices($data));
        return response()->json([
            'status' => 1,
            'ref' => $Proforma->reference,
            'message' => 'Proforma created successfully'
        ]);
    }

    /**
     * Get Proforma Items
     * @param string $reference
     * @return JsonResponse
     */
    public function approveProforma($reference)
    {
        $Proforma = Proforma::where('reference', $reference)
                                    ->with('client')
                                    ->first();
        if (!$Proforma) {
            return response()->json([
                'status'  => 0,
                'message' => 'Proforma not found. Try again'
            ], 404);
        }

        $ProformaItem = ProformaItem::select('id', 'product_id', 'batch', 'requested_qty as quantity', 'price', 'received_qty')
                                      ->where('proforma_id', $Proforma->id)
                                      ->get();

        $ProformaItem2 = ProformaItem::select('id', 'product_id', 'batch', 'requested_qty as quantity', 'price', 'received_qty')
                                      ->where('proforma_id', $Proforma->id)
                                      ->get();
        $checkUpdateStatus = 0;

        foreach ($ProformaItem as $item){
            $product = Product::find($item->product_id);
            if($product->quantity<$item->quantity){
                $checkUpdateStatus +=1; 
                break;
            }else{
                $checkUpdateStatus = 0;
            }
        }

        if($checkUpdateStatus==0){
            
            $datas = [
                'date_initiated' =>  date('Y-m-d'),
                'client_id'     => $Proforma->client_id,
                'reference'   => generateRowCode(20),
                'proforma_ref'=> $Proforma->reference,
                'code' => createTransactCode('DN'),
                'amount'        => $Proforma->amount ?? 0,
                'status'        => 'PENDING'
            ];

            $DeriveryNote = DeriveryNote::create($datas);

            foreach ($ProformaItem2 as $item){
                DeriveryNoteItems::create([
                    'derivery_id' => $DeriveryNote->id,
                    'product_id'    => $item->product_id,
                    'batch'    => $item->batch,
                    'requested_qty' => $item->quantity,
                    'price' => $item->price,
                    'received_qty'  => $item->quantity
                ]);
            }

            $Proforma->status = 'ACCEPTED';
            $Proforma->save();

            return response()->json([
                'status' => 1,
                'row'    => $Proforma,
                'items'  => $ProformaItem,
                'message' => "Proforma Approved Successfuly"
            ]);

        }else{
            return response()->json([
                'status'  => 0,
                'message' => 'Proforma Can\'t be approved something went wrong! either there is over Quantities.'
            ]);
        }
    }

        /**
     * Delete Proforma Item
     * @param Modules\Api\Models\Proforma $Proforma_id
     * @return void
     */
    private function draftSaleItems(Proforma $Proforma, $action = 'edit')
    {
        $items = ProformaItem::where('proforma_id', $Proforma->id)->get();
        foreach ($items as $row) {
            if ($action == 'edit') {
                DB::table('proforma_items')->where('id', $row->id)->delete();
            }
        }
    }

    /**
     * Get Proforma Items
     * @param string $reference
     * @return JsonResponse
     */
    public function getItems($reference)
    {
        $Proforma = Proforma::where('reference', $reference)
                                    ->with('client','company')
                                    ->first();
        if (!$Proforma) {
            return response()->json([
                'status'  => 0,
                'message' => 'Proforma not found. Try again'
            ], 404);
        }

        return response()->json([
            'status' => 1,
            'row'    => $Proforma,
            'items'  => ProformaItem::select('id', 'product_id', 'batch', 'requested_qty as quantity', 'price', 'received_qty')
                                      ->where('proforma_id', $Proforma->id)
                                      ->with('product','expiry')
                                      ->get()
        ]);
    }

   /**
    * Delete Proforma
    * @param int $id
     * @return JsonResponse
    */
    public function destroy($id) 
    {
        $row = Proforma::find($id);
        if (empty($row)) {
            return response()->json([
                'status'  => 0,
                'error' => 'No records found'
            ], 404);
        }

        $items = ProformaItem::where('proforma_id', $row->id)->get();
        foreach($items as $item) {
            $item->delete();
        }

        $row->delete();
        $row->status = "CANCELLED";
        $row->save();

        return response()->json([
            'status'  => 1,
            'message'   => 'Record have deleted successfully'
        ]);
    }

    /**
     * Update Proforma status
     * @param int $id
     * @return JsonResponse
     */
    public function updateStatus($id)
    {
        $Proforma = Proforma::findOrFail($id);

        if(!empty($Proforma)) {
            $Proforma->status = "CANCELLED";
            $Proforma->save();
        }
        return response()->json([
            'status'  => 1,
            'message' => 'Status Changed Successfully'
        ]);
    }

    /**
     * Delete Single item
     * @param int itemId
     * @return JsonResponse
     */
    public function deleteItem($itemId)
    {
        $row = ProformaItem::findOrFail($itemId);
        if (!$row) {
            return response()->json([
                'status' => 0,
                'error'  => 'Item not found'
            ], 404);
        }
        $Proforma = Proforma::find($row->proforma_id);
        $Proforma->amount -= ($row->price * $row->requested_qty);
        $Proforma->save();

        $row->delete();

        return response()->json([
            'status' => 1,
            'message'  => 'Deleted successfully'
        ]);
    }
}