<?php

namespace App\Http\Controllers\Api\Trip;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Trip\TripBooking;
use App\Models\Trip\TripContainer;
use App\Models\Trip\TripItem;
use App\Models\Trip\TripDeliveryPoint;
use App\Models\Trip\TripPickupPoint;
use App\Models\Trip\TripExpense;
use App\Models\Trip\TripStatus;
use App\Models\cms\ContainerDetail;
use App\Models\cms\PreArrivalDeparture;
use App\Models\cms\CmsItemDetail;

use Carbon\Carbon;
use Log;
use App\Service\Trip\TripService;
use App\Service\SequenceService;

class TripBookingController extends Controller
{
    // Create Trip Booking
    public function tripBookingCreate(Request $request)
    {
        $validator=validator($request->all(),[
            'trip_date_time'=>'required',
            'customer_type'=>'required',
            'logistics_provider_id'=>'required',
            'driver_id'=>'required',
            'vehicle_id'=>'required',
        ]);

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

        } else {

            $obj['trip_booking_no'] = $request['trip_booking_no'] ?? null;
            $obj['trip_date_time'] = $request['trip_date_time'] ?? null;  // Date
            $obj['trip_type'] = $request['trip_type'] ?? 0;  // 1 =arrival 2=departure

            $obj['customer_type'] = $request['customer_type'] ?? null;  // 1=in=bond, 2=out-bond
            $obj['customer_id'] = $request['customer_id'] ?? 0;  // Customer ID
            $obj['purchase_order_id'] = $request['purchase_order_id'] ?? 0;  // Purchase Order ID
            $obj['referal'] = $request['referal'] ?? null;  
            $obj['attachments'] = $request['attachments'] ?? null;  
            $obj['documents'] = $request['documents'] ?? null;  

            // Consigment Type
            $obj['consignment_type'] = $request['consignment_type'] ?? null;  // 1=ship, 2=road , 3=air , 4=rail
            $obj['consignment_json'] = $request['consignment_json'] ?? null;  // Consignment ID

            // Logistics Provider
            $obj['logistics_provider_id'] = $request['logistics_provider_id'] ?? 0;
            $obj['driver_id'] = $request['driver_id'] ?? null;
            $obj['driver_license_no'] = $request['driver_license_no'] ?? null;

            // Vehicle Details
            $obj['vehicle_type'] = $request['vehicle_type'] ?? null;
            $obj['vehicle_id'] = $request['vehicle_id'] ?? null;
            $obj['starting_point'] = $request['starting_point'] ?? null;

            if($request['id']>0){
                $trip_booking = TripBooking::find($request['id']);

                // Delete Containers
                TripContainer::where('trip_booking_id', $trip_booking['id'])->delete();

                // Delete Items
                TripItem::where('trip_booking_id', $trip_booking['id'])->delete();

                // Delete Delivery Point
                TripDeliveryPoint::where('trip_booking_id', $trip_booking['id'])->delete();

                // Delete Pickup Point
                TripPickupPoint::where('trip_booking_id', $trip_booking['id'])->delete();

                // Delete Expenses
                TripExpense::where('trip_booking_id', $trip_booking['id'])->delete();

                $trip_booking->update($obj);
                
            }else{
                $trip_booking = TripBooking::create($obj);

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

                // Create Trip Status
                $obj1['trip_booking_id']=$trip_booking['id']??0;
                $obj1['status']=$request['status']??'Pending';   // from the masters trip booking status
                $obj1['date_time']=$request['trip_date_time']??null;
                $obj1['remark']=$request['remark']??null;

                $trip_booking_status=TripStatus::create($obj1);
            }
            

            // Calling Service
            $trip_service = new TripService;

            // If Container
            if ($request['is_container'] == 1) {
                $obj['is_container'] = 1;  // Container ID

                $trip_service->containersCreateUpdate($request,$trip_booking);
            }

            // Create Trip Items
            if (!empty($request['item_details'])) {
                $trip_service->tripItemsCreate($request, $trip_booking);
            }

            // Create Delivery Point
            if (!empty($request['delivery_point_details'])) {
                $trip_service->tripDeliveryPointCreate($request, $trip_booking);
            }

            // Create Trip Pickup Point
            if (!empty($request['pickup_point_details'])) {
                $trip_service->tripPickupPointCreate($request, $trip_booking);
            } 

            // Create Expenses
            if (!empty($request['trip_expenses'])) {
                $trip_service->tripExpensesCreate($request, $trip_booking);
            } 

            $response=[
                'success'=>true,
                'message'=>$request['id']>0? "Trip Booking Updated Successfully":"Trip Booking Created Successfully",
                'data'=>$trip_booking
            ];

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

    // Trip Booking List
    public function tripBookingList(Request $request)
    {
        $trip_booking = TripBooking::with('customer','logistics_provider:id,display_name','vehicle');

        if(isset($request['status']) && $request['status']!=''){
            $trip_booking=$trip_booking->where('status',$request['status']);
        }

        // Searching based on 'search' keyword (pid_no or container_id)
        if (!empty($request->search)) {
            $search = $request->search;

            $trip_booking->where(function ($query) use ($search) {
                $query->where('trip_booking_no', 'like', '%' . $search . '%')
                    ->orWhere('status', 'like', '%' . $search . '%');
                    // ->orWhereHas('container_details', function ($q) use ($search) {
                    //     $q->where('container_id', 'like', '%' . $search . '%');
                    // });
            });
        }

         // Filtering based on 'date'
        if (!empty($request->custom_date)) {
            $trip_booking->whereDate('trip_date_time', $request->custom_date);
        }

        // Filtering based on from date to date
        if (!empty($request->fromDate) && !empty($request->toDate)) {
            $trip_booking->whereBetween('trip_date_time', [$request->fromDate, $request->toDate]);
        }

        $count=$trip_booking->count();

        
            // Sorting functionality
        if (!empty($request->sort_by)) {
            $sortOrder = ($request->sort_order == 1) ? 'asc' : 'desc';

            $trip_booking->orderBy($request->sort_by, $sortOrder);
        } else {
            $trip_booking->orderBy('id', 'desc');
        }

        $trip_booking =$trip_booking->skip($request['noofrec']*($request['currentpage']-1))->take($request['noofrec']??100)
            ->get();

        return response()->json([
            'success' => true,
            'count' => $count,
            'message' => 'Trip Booking Lists',
            'data' => $trip_booking
        ], 200);
    }

    // Trip Booking Details
    public function tripBookingDetails(Request $request)
    {

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

        //Inout 1 = payment rec , 2= payment made

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

            $trip_booking = TripBooking::with('customer','logistics_provider','driver','vehicle','purchase_order')
                ->where('id',$request['id'])
                ->first();

            if($trip_booking){

                $containers = TripContainer::with('container_owner','container_types')
                    ->where('trip_booking_id',$trip_booking['id'])
                    ->get();

                $trip_items = TripItem::with('items')
                    ->where('trip_booking_id',$trip_booking['id'])
                    ->get();

                $trip_delivery_points = TripDeliveryPoint::with('city:id,name','state:id,name','country:id,name')
                    ->where('trip_booking_id',$trip_booking['id'])
                    ->get();

                $trip_pickup_points = TripPickupPoint::with('city:id,name','state:id,name','country:id,name')
                    ->where('trip_booking_id',$trip_booking['id'])
                    ->get();

                $trip_expenses = TripExpense::with('account:id,account_name','vendor:id,display_name','customer:id,display_name','paid_by:id,account_name')
                    ->where('trip_booking_id',$trip_booking['id'])
                    ->get();

                $trip_status = TripStatus::where('trip_booking_id',$trip_booking['id'])
                    ->get();

                $trip_booking['containers'] = $containers;
                $trip_booking['trip_items'] = $trip_items;
                $trip_booking['trip_delivery_points'] = $trip_delivery_points;
                $trip_booking['trip_pickup_points'] = $trip_pickup_points;
                $trip_booking['trip_expenses'] = $trip_expenses;
                $trip_booking['trip_status'] = $trip_status;

                return response()->json([
                    'success' => true,
                    'message' => 'Trip Booking Details',
                    'data' => $trip_booking
                ], 200);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => 'Trip Booking Not Found',
                    'data' => []
                ], 200);
            }
        }
    }

    //Create Trip Status History
    public function tripBookingStatus(Request $request){

        $validator=validator($request->all(),[
            'trip_booking_id'=>'required',
            'date_time'=>'required',
            'status'=>'required',
        ]);

        //Inout 1 = payment rec , 2= payment made

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

            $trip_booking = TripBooking::where('id',$request['trip_booking_id'])
                ->first();

            if(!$trip_booking){
                return response()->json([
                    'success' => false,
                    'message' => 'Trip Booking Not Found',
                    'data' => []
                ], 200);
            }

            $trip_booking['status'] = $request['status'] ?? null;
            $trip_booking->update();

            // Update Booked Trip Status , if it is for megamarket then create pre arrival after booking
            if($trip_booking['status'] == 'Booked' && $trip_booking['trip_type'] == 1){

                //Create Pre Arrival Containers
                $trip_container=TripContainer::where('trip_booking_id',$trip_booking['id'])
                    ->where('is_megamarket',1)
                    ->get();

                $trip_item=TripItem::where('trip_booking_id',$trip_booking['id'])
                    ->where('is_megamarket',1)
                    ->get();
                    
                $sequence=new SequenceService();

                //Create Pre Arrival
                $pre['pre_arrival_id'] = $sequence->getSequence('pre_arrival');
                $pre['trip_booking_id'] = $trip_booking['id'];
                $today = new Carbon();
                $pre['date'] = $today->format('Y-m-d');
                $pre['order_type'] = "pre_arrival";
                $pre['logistic_provider_id'] = $trip_booking['logistics_provider_id'] ?? 0;
                $pre['documents'] = $trip_booking['documents'] ?? null;

                $prearrival = PreArrivalDeparture::create($pre);

                //Create Pre Arrival Containers
                if($trip_container->count() > 0  || $trip_item->count() > 0){

                    $order_container_id = [];
                    // For Container
                    if($trip_container->count() > 0){
                        foreach($trip_container as $key => $value){

                            $obj = [];
                            //Create Pre Arrival Containers
                            $obj['container_owner_id'] = $value['container_owner_id'] ?? 0;
                            $obj['container_id'] = $value['container_id'] ?? null;
                            $obj['container_type'] = $value['container_type'] ?? 0;
                            $obj['internal_dimension'] = $value['internal_dimension'] ?? null;
                            $obj['door_opening'] = $value['door_opening'] ?? null;
                            $obj['cubic_capacity'] = $value['cubic_capacity'] ?? null;
                            $obj['cargo_weight'] = $value['cargo_weight'] ?? null;
                            $obj['container_status'] = $value['container_status'] ?? null;
                            $obj['container_condition'] = $value['container_condition'] ?? null;
                            $obj['order_status']= "pre_arrival";
                            $obj['images'] = $value['images'] ?? null;
                            $obj['attachments'] = $value['attachments'] ?? null;
                            $obj['status'] = "pending";

                            $containerDetail = ContainerDetail::create($obj);

                            Log::info($containerDetail);

                            array_push($order_container_id, $containerDetail['id']);
                        }
                    }

                    // Use object property syntax
                    $prearrival->container_detail_ids = implode(',', $order_container_id);
                    $prearrival->vendor_id = $trip_booking['customer_id'] ?? 0;

                    $prearrival->update();
                }

                //Creating Cms Items From Trip Items
                if($trip_item->count() > 0){
                    foreach($trip_item as $key => $value_item){

                        $obj = [];
                        //Create Pre Arrival Containers
                        $obj['item_name']=$value_item['item_name'];
                        $obj['item_id']=$value_item['item_id']??0;
                        $obj['quantity']=$value_item['quantity']??0;
                        $obj['unit']=$value_item['unit'];
                        $obj['tax_rate']=$value_item['tax_rate']??0;
                        $obj['tax_amount']=$value_item['tax_amount']??0;
                        $obj['item_remark']=$value_item['item_remark'];
        
                        $obj['order_type']="pre_arrival";
                        $obj['transaction_id']=$prearrival['id'];
                        
                        $item=CmsItemDetail::create($obj);
                    }
                }
            }

            $obj1['trip_booking_id']=$request['trip_booking_id']??0;

            $obj1['status']=$request['status']??null;   // from the masters trip booking status
            $obj1['date_time']=$request['date_time']??null;
            $obj1['remark']=$request['remark']??null;

            $trip_booking=TripStatus::create($obj1);
            
                
            return response()->json([
                'success' => true,
                'message' => 'Trip Booking Status Created Successfully',
                'data' => $trip_booking
            ], 200);
        }

    }

    // Delete Trip Booking
    public function tripBookingdelete(Request $request)
    {
        $validator=validator($request->all(),[
            'id'=>'required'
        ]);

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

            $trip_booking = TripBooking::find($request['id']);

            if($trip_booking){

                if($trip_booking->status == 'Pending'){

                    $containers = TripContainer::with('container_owner','container_types')
                        ->where('trip_booking_id',$trip_booking['id'])
                        ->delete();

                    $trip_items = TripItem::with('items')
                        ->where('trip_booking_id',$trip_booking['id'])
                        ->delete();

                    $trip_delivery_points = TripDeliveryPoint::with('city:id,name','state:id,name','country:id,name')
                        ->where('trip_booking_id',$trip_booking['id'])
                        ->delete();

                    $trip_pickup_points = TripPickupPoint::with('city:id,name','state:id,name','country:id,name')
                        ->where('trip_booking_id',$trip_booking['id'])
                        ->delete();

                    $trip_expenses = TripExpense::with('account:id,account_name','vendor:id,display_name','customer:id,display_name','paid_by:id,account_name')
                        ->where('trip_booking_id',$trip_booking['id'])
                        ->delete();

                    $trip_status = TripStatus::where('trip_booking_id',$trip_booking['id'])
                        ->delete();

                    $trip_booking->delete();
                    
                } else {

                    return response()->json([
                        'success' => false,
                        'message' => 'Trip Booking Cannot be Deleted'
                    ], 200);
                }
                
                return response()->json([
                    'success' => true,
                    'message' => 'Trip Booking Deleted Successfully'
                ], 200);
            } else {
                return response()->json([
                    'success' => false,
                    'message' => 'Trip Booking Not Found'
                ], 200);
            }
        }
    }
    
}
