<?php

namespace App\Http\Controllers\Api\Purchase;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Service\ActivityService;
use App\Service\StaticMaster;
use App\Models\GRN;
use App\Models\GRNItems;
use App\Models\PurchaseOrderItem;
use App\Models\GRNCharge;
use App\Service\GRNItemService;
use App\Service\GRNChargesService;
use App\Service\SequenceService;
use Auth;
use Log;

class GRNController extends Controller
{
    // Creating a new Grn And Update GRn
    public function createUpdateGrn(Request $request){

        $validator=validator($request->all(),[
            'purchase_from'=>'required|string',
            'fy'=>'required',
            'total'=>'required',
            'transaction_date'=>'required',
            'vendor_id'=>'required',
            'is_purchase_order'=>'required'
        ]);

        if ($validator->fails()) { 
            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];
        } else {

            $data=[
                'purchase_from',
                'grn_no',
                'transaction_date',
                'reference',
                'vendor_id',
                'currency',
                'currency_symbol',
                'tracking_details',
                'is_purchase_order',
                'purchase_order_id',
                'fy',
                'vendor_name',
                'display_name',
                'phone',
                'email',
                'address',
                'delivery_address',
                'subtotal',
                'discount',
                'shipping_charge',
                'adjustment_charge',
                'total_grn_charges',
                'charges',
                'total',
                'terms_and_condition',
                'vendor_note',
                'upload_image',
                'status',
                'exchange_rate'
            ];
            
            
            foreach ($data as $key => $value) {
                if(isset($request[$value]) && $request[$value]!=null && $request[$value]!=''){
                    $obj[$value]=$request[$value];
                }

                if($request[$value]==''){
                    $obj[$value]=null;
                }

                if($request[$value]==0){
                    $obj[$value]=0;
                }
            }

            // Serivces to record items
            $grn_items=new GRNItemService;
            $grn_charges=new GRNChargesService;

            $obj['transaction_type']=StaticMaster::$GRN_PURCHASE_TYPE;

            $transaction=[];

            if($request['id']>0){

                try{
                    //Check if id is already exists
                    $transaction=GRN::findOrFail($request['id']);
                    $obj['grn_no']=$request['grn_no'];
                    $transaction->update($obj);

                    // Creating Activities
                    $activity=new ActivityService;
                    $activity->activityCreateUpdate('GRN',$transaction['id'],'Updated');

                    // Deleting all the records in items table
                    $item=GRNItems::where('transaction_id',$request['id'])->delete();

                    // Deleting all the records in items table
                    $charge=GRNCharge::where('grn_id',$request['id'])->delete();

                    // Creating items
                    $grn_items->saveItems($request,$transaction);

                    // Creating grn charges
                    $grn_charges->savecharges($request,$transaction);

                } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
                    // Return error message in JSON if ID not found
                    return response()->json(['message' => 'Invalid Id to update '], 404);
                }


            }else{
                $transaction=GRN::create($obj);

                $transaction['grn_no']=$request['grn_no'];
                // $transaction['exchange_rate']=$currency_convert->getlatestCurrency($request['currency']);
                $transaction->update();

                // Creating Activities
                $activity=new ActivityService;
                $activity->activityCreateUpdate('GRN',$transaction['id'],'Created');


                $module='grn';
                // Update Sequence Number
                $sequence=new SequenceService;
                $sequence->updateSequence($module);

                // Creating items
                $grn_items->saveItems($request,$transaction);

                // Creating grn charges
                $grn_charges->savecharges($request,$transaction);
            }    

            return response()->json(['status'=>200,'message'=>'Transaction Created Successfully','transaction'=>$transaction],200);
        }

    }


    public function grnList(Request $request){

        $user=Auth::user();
        $validator=validator($request->all(),[

            'fy'=>'required',

        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];

        } else {
    
            $grn= GRN::where('organisation_id',$user['active_organisation'])
                ->where('rolledback',0)
                ->with("items","vendor","charges_type","purchase_order:id,purchase_order_id")
                // ->where('warehouse_id',$request['warehouse_id'])
                ->where('fy',$request['fy']);

                if ($request['status']!='' && isset($request['status'])) {

                    $grn=$grn->where('status',$request['status']);
    
                }
                if($request['search']!=null && $request['search']!=''){
    
                    // $searchTerm = $request['search'];
    
                    $grn = $grn->where(function ($query) use ($request) {
    
                        $query->where('grn_no', 'LIKE', '%' . $request['search'] . '%')
    
                            ->orWhere('reference', 'LIKE', '%' . $request['search'] . '%')
    
                            ->orWhere('display_name', 'LIKE', '%' . $request['search'] . '%')
    
                            // ->orWhere('mobile_no', 'LIKE', '%' . $request['search'] . '%')
    
                            ->orWhere('phone', 'LIKE', '%' . $request['search'] . '%')
    
                            ->orWhere('email', 'LIKE', '%' . $request['search'] . '%');
                    });
    
                }

                        // get custom_date data by transaction_date

            if ($request['custom_date']!='' && isset($request['custom_date'])) {

                $customDate = $request->custom_date;

                $grn = $grn->whereDate('transaction_date', $customDate);

            }
    
                    // get last modified data by updated_at
    
            if ($request['updated_at']!='' && isset($request['updated_at'])) {

                $grn=$grn->orderBy('updated_at');

            }

            if ($request['vendor_id']!=0 && $request['vendor_id']!='' && isset($request['vendor_id'])) {
    
                $grn = $grn->where('vendor_id',$request['vendor_id']);

            }

                // get fromDate toDate data by created_at

            if ($request['from_date']!='' && isset($request['to_date'])) {

                $fromDate = $request->from_date;

                $toDate = $request->to_date;

                // 'fromDate' and 'toDate'

                $grn = $grn->whereBetween('transaction_date', [$fromDate, $toDate]);

            }

                
            $count=$grn->count();

            if(isset($request['sort_by']) && $request['sort_by']!='' && $request['sort_by']!=null){
                
                $sort_order=$request['sort_order']==1?'asc':'desc';

                $grn = $grn->orderby($request['sort_by'],$sort_order);

            }else{
                $grn = $grn->orderby('id','desc');
            }
        
            $grn=$grn->skip($request['noofrec']*($request['currentpage']-1))->take($request['noofrec']??100)->get();

            $response=[
                'message'=>'GRN List Fetched Successfully',
                'success'=>true,
                'count'=>$count,
                'grn'=>$grn
            ];

            return response()->json($response);
        }
    }


    public function details(Request $request)
    {
        // Validate Item
        $user=Auth::user();

        $validator=validator($request->all(),[
            'id'=>'required'
        ]);

        if ($validator->fails()) { 
            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];
        } else {

            $grn = GRN::where('id',$request['id'])->where('organisation_id',$user['active_organisation'])
                ->with('items','vendor','items.item','activity','charges_type','charges_type.account:id,account_name','purchase_order',
                'charges_type.vendor')
                ->first();

            $response=[
                'bgrnill'=>$grn,
                'message'=>"GRN details fetch successfully",
                'success'=>true
            ];

            return response()->json($response);
        }

    }
    

    public function statusGrn(Request $request){
        // Validate Item
        $status_change='';

        $validator=validator($request->all(),[

            'id'=>'required',
            'status'=>'required'

        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];

        } else {

            $transaction = GRN::findOrFail($request->id);

            $transaction['status']=$request['status'];

             //GRN Approved
            if($request['status']==1){

                $status_change='Approved';
                $transaction['is_approved']=1;

                // Update All GRn Items Status to Approved
                $ob['is_approved']=1;

                $grn_items=GRNItems::where('transaction_id',$transaction['id'])
                    ->where('is_disabled',0)->get();

                $purchase_item=PurchaseOrderItem::where('transaction_id',$transaction['purchase_order_id'])
                    ->where('is_disabled',0)->get();

                foreach ($grn_items as $key => $item) {

                    // Updating GRN Quantity of all items of Purchase Order
                    if($transaction['is_purchase_order']==1 && $transaction['is_approved']==0){  //Checking is transaction recorded from the purchase order

                        foreach ($purchase_item as $key => $value) {

                            if($value['item_id']==$item['item_id']){

                                // Updating GRN Quantity in Purchase
                                $value['gr_qty']= $value['gr_qty'] + $item['gr_qty'];
                            }

                            $value->update();
                        }

                    }

                    // Updating Approved on all items of grn
                    $item->update($ob);
                }

                //GRN charge Service
                $grn_charge_service=new GRNChargesService;
                $grn_charge_service->chargesApprove($transaction);

            }

            // GRN Rejected
            if($request['status']==2){

                $status_change='Declined';
                $transaction['is_approved']=0;

            }

            // GRN Draft
            if($request['status']==0){
                
                $status_change='Draft';
            }

            $transaction->update();  

            $response=[ 

                'success'=>true,
    
                'message'=>'GRN '.$status_change.' Updated Successfully'
    
            ];

            return response()->json($response);

        }
    }

    public function destroy(Request $request)
    {

        $user=Auth::user();

        $validator=validator($request->all(),[
            'id'=>'required'
        ]);

        if ($validator->fails()) { 

            return [
                'success' => false, 
                'message' => $validator->errors()->first()
            ];

        } else {

            try{
                $grn = GRN::findOrFail($request['id']);

            } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
                // Return error message in JSON if ID not found
                return response()->json(['message' => 'Invalid Id to delete '], 404);
            }

            if($grn['is_approved']==0){

                $grn['rolledback']=1;

                $grn->update();

                $grn_items=GRNItems::where('transaction_id',$grn['id'])->get();
                
                foreach ($grn_items as $value){
                    $value['is_disabled'];

                    $value->update();
                }

                $response=[
                    'success'=>true,
                    'message'=>'GRN deleted Successfully'
                ];

            }else{

                $response=[
                    'success'=>false,
                    'message'=>'GRN is Approved. You can\'t delete this bill.'
                ];

            }

            return response()->json($response);
        }
    }
}
