<?php

namespace App\Http\Controllers\Api\cms;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\cms\PlacedDepartureOrder;
use App\Models\cms\Order;
use App\Models\cms\ContainerOwner;
use App\Models\cms\ContainerDetail;
use App\Models\cms\LogisticProvider;
use App\Models\cms\Masters\ContainerType;
use App\Models\cms\Masters\VehicleType;
use App\Models\cms\Yard;
use App\Service\cms\PreArrivalService;
use App\Service\cms\DocumentService;
use App\Service\cms\PreDepartureService;
use App\Service\cms\ContainerDetailsService;
use Carbon\Carbon;
use DB;

class DepartureController extends Controller
{
    public function index(Request $request)
    {
        try {
            // Base query for 'departure' orders with approved = 0 and status = 0
            $pre_arrival = PlacedDepartureOrder::with([
                'orders',
                'orders.container_owner:id,company_name',
                'entrybyid'
            ])
                ->where('order_type', 'departure')
                ->where('approved', 0)
                ->where('status', 0);

            // Filtering by 'container_id'
            if (!empty($request->container_id)) {
                $pre_arrival->where('container_id', $request->container_id);
            }

            // Filtering by 'date'
            if (!empty($request->custom_date)) {
                $pre_arrival->whereDate('date', $request->custom_date);
            }

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

            // Searching based on 'search' keyword ( container_id,)
            if (!empty($request->search)) {
                $search = $request->search;
                $pre_arrival->where(function ($query) use ($search) {
                    $query->whereExists(function ($subQuery) use ($search) {
                        $subQuery->select(DB::raw(1))
                            ->from('container_details')
                            ->whereRaw('FIND_IN_SET(container_details.id, placed_departure_order.container_detail_ids)')
                            ->where('container_details.container_id', 'like', '%' . $search . '%');
                    });
                });
            }

            // Counting total records
            $count = $pre_arrival->count();

            // Pagination parameters
            $noOfRec = $request->noofrec ?? 100;  // Default to 100 records per page
            $currentPage = $request->currentpage ?? 1;  // Default to page 1

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

            // Apply pagination
            $pre_arrival = $pre_arrival->skip($noOfRec * ($currentPage - 1))
                ->take($noOfRec)
                ->get();

            // Adding container details
            foreach ($pre_arrival as $departure) {
                if (!empty($departure->container_detail_ids)) {
                    // Fetch container details based on IDs
                    $container_details = ContainerDetail::whereIn('id', explode(',', $departure->container_detail_ids))
                        ->select('id', 'container_id')
                        ->get();

                    // Attach container details to the departure object
                    $departure['container_details'] = $container_details;
                } else {
                    $departure['container_details'] = collect();
                }
            }

            // Return JSON response with required structure
            return response()->json([
                'success' => true,
                'total' => $count,
                'data' => $pre_arrival,
            ], 200);
        } catch (\Exception $e) {
            // Handle errors
            return response()->json([
                'success' => false,
                'message' => 'Error occurred while processing the request',
                'error' => $e->getMessage(),
            ], 500);
        }
    }


    public function details(Request $request)
    {
        try {
            // Validate the request
            $validator = validator($request->all(), [
                'id' => 'required',
            ]);

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

            // Fetch the departure record with related orders and documents
            $departure = PlacedDepartureOrder::with('items','orders','logistic_provider','vendor','driver','vehicle')->findOrFail($request->id);

            // Get container details with images for 'departure'
                $container_details = ContainerDetail::whereIn('id', explode(',', $departure->container_detail_ids))
                ->with([
                    'container_owner',
                    'container_types',
                    'logisticProvider',
                    'vehicleMaster',
                    'yard'
                ])
                ->get();

            return response()->json([
                'success' => true,
                'message' => 'Departure details fetched successfully',
                'data' => [
                    'pre_arrival' => $departure,
                    'container_details' => $container_details
                ]
            ], 200);

        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            // Handle record not found
            return response()->json([
                'success' => false,
                'message' => 'Departure record not found',
            ], 404);
        } catch (\Exception $e) {
            // Handle unexpected errors
            return response()->json([
                'success' => false,
                'message' => 'An unexpected error occurred',
                'error' => $e->getMessage(),
            ], 500);
        }
    }


    public function store(Request $request)
    {
        try {
            // Get today's date
            $today = new Carbon();
            $request['date'] = $today->format('Y-m-d');

            // Creation of Services
            $containerDetailService = new ContainerDetailsService;

            $orders = [];
            $prearrival = null;
            $arrived = null;
            $pre_departure = null;
            $departure = null; // Initialize departure variable

            // Pre Arrival Order Type
            if ($request['order_type'] == 'pre_arrival') {
                $order_container_id = $containerDetailService->createOrderContainer($request);

                $prearrival = new PreArrivalService;
                $prearrival = $prearrival->savePreArrival($request);
                $prearrival['container_detail_ids'] = implode(',', $order_container_id);
                $prearrival->update();

                // Save Documents
                // $documentService->addDocument($request, $prearrival['id'], 'pre_arrival');

                $orders[] = $prearrival;
            }

            // Arrival Order Type
            if ($request['order_type'] == 'arrival') {
                if (!isset($request['order_container_id'])) {
                    $order_container_id = $containerDetailService->createOrderContainer($request);
                }

                $arrived = new PreArrivalService;
                $arrived = $arrived->saveArrival($request);
                $arrived['container_detail_ids'] = implode(',', $request['order_container_id'] ?? $order_container_id);
                $arrived->update();

                // $documentService->addDocument($request, $arrived['id'], 'arrival');

                $orders[] = $arrived;
            }

            // Pre-Departure Order Type
            if ($request['order_type'] == 'pre_departure') {
                $pre_departure = new PreDepartureService;

                if (isset($request['order_container_id'])) {
                    $order_container_id = $containerDetailService->updateContainerDetail($request);

                    foreach ($request['order_container_id'] as $key => $value) {
                        $container_detail = ContainerDetail::where('id', $request['order_container_id'][$key])->first();
                        $container_detail['status'] = "ongoing";
                        $container_detail->update();
                    }
                } else {
                    $order_container_id = $containerDetailService->createOrderContainer($request);
                }

                $pre_departure = $pre_departure->savePreDeparture($request);
                $pre_departure['container_detail_ids'] = implode(',', $request['order_container_id']);
                $pre_departure->update();

                // $documentService->addDocument($request, $pre_departure['id'], 'pre_departure');

                $orders[] = $pre_departure;
            }

            // Departure Order Type
            if ($request['order_type'] == 'departure') {
                $departure = new PreDepartureService;

                if (isset($request['order_container_id'])) {
                    $order_container_id = $containerDetailService->updateContainerDetail($request);

                    foreach ($request['order_container_id'] as $key => $value) {
                        $container_detail = ContainerDetail::where('id', $request['order_container_id'][$key])->first();
                        $container_detail['status'] = "process";
                        $container_detail->update();
                    }
                } else {
                    $order_container_id = $containerDetailService->createOrderContainer($request);
                }

                $departure = $departure->saveDeparture($request);
                $departure['container_detail_ids'] = implode(',', $request['order_container_id']);
                $departure->update();

                // $documentService->addDocument($request, $departure['id'], 'departure');

                $orders[] = $departure;
            }

            return response()->json([
                'success' => true,
                'total' => $departure ? 1 : 0, // Return count based on departure data
                'data' => [
                    'departure' => $departure // Include departure data in response
                ]
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error occurred while processing the request',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function edit($id)
    {
        $departures = PlacedDepartureOrder::with('orders')->where('id', $id)->first();

        $container_details = ContainerDetail::whereIn('id', explode(',', $departures['container_detail_ids']))
            
            ->get();

        $containerOwners = ContainerOwner::where('status', 0)->get();

        $containertype = ContainerType::where('status', 0)->get();

        $logisticProviders = LogisticProvider::where('status', 0)->get();

        $vehicleMaster = VehicleType::where('status', 0)->get();

        return view('departures.edit', compact('departures', 'containerOwners', 'containertype', 'logisticProviders', 'vehicleMaster', 'container_details'));
    }


    public function filter(Request $request)
    {
        $pre_arrival = PlacedDepartureOrder::where('approved', 1)->where('order_type', 'departures')
            ->with('orders', 'orders.container_owner:id,company_name');

        if ($request['date'] != '' && isset($request['date']) && $request['date'] != null) {
            $pre_arrival = $pre_arrival->whereDate('date', $request['date']);
        }
        if ($request['container_id'] != '' && isset($request['container_id']) && $request['container_id'] != null) {
            $pre_arrival = $pre_arrival->where('container_id', $request['container_id']);
        }
        if ($request['container_status'] != '' && isset($request['container_status']) && $request['container_status'] != null) {
            // $pre_arrival=$pre_arrival->where('container_status',$request['container_status']);
            $pre_arrival = $pre_arrival->whereHas('orders', function ($query) use ($request) {
                $query->where('container_status', $request['container_status']);
            });
        }
        if ($request['container_condition'] != '' && isset($request['container_condition']) && $request['container_condition'] != null) {
            $pre_arrival = $pre_arrival->whereHas('orders', function ($query) use ($request) {
                $query->where('container_condition', $request['container_condition']);
            });
        }

        $pre_arrival = $pre_arrival->get();

        return view('departures.index', compact('pre_arrival'));
    }

    public function sendForDepartureApproval(Request $request)
    {
        $validator = validator($request->all(), [
            'id' => 'required',
        ]);

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

        // Fetch the departure record
        $departure = PlacedDepartureOrder::where('id', $request->id)->first();

        // Update the status to 1 (approved)
        $departure['status'] = 1;
        // $departure['reporting_id'] = $user['reporting_id'];
        $departure->update();

        return response()->json([
            'success' => true,
            'message' => 'Departure approved successfully',
        ], 200);
    }

}
