<?php

namespace App\Http\Controllers\Api\cms;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

use App\Models\cms\Block;
use App\Models\cms\Yard;
use App\Models\cms\ContainerOwner;
use App\Models\cms\PreArrivalDeparture;
use App\Models\cms\Masters\ContainerType;
use App\Models\cms\ContainerDetail;
use App\Service\cms\OrderService;
use Illuminate\Support\Facades\Session;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Log;

class BlockController extends Controller
{
    public function index(Request $request)
    {
        $blocks = Block::with('entrybyid:id,name', 'yard:id,yard_name'); // Assuming 'yard' is a relationship defined on the Block model.

        // Filtering based on 'id'
        if (!empty($request->id) && $request->id > 0) {
            $blocks->where('id', $request->id);
        }

        // Filtering based on 'block_id'
        if (!empty($request->block_id)) {
            $blocks->where('block_id', $request->block_id);
        }

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

        // Filtering based on 'status' (only 0 or 1)
        if (isset($request->status) && in_array($request->status, [0, 1])) {
            $blocks->where('status', $request->status);
        }

        // Searching based on 'search' keyword
        if (!empty($request->search)) {
            $search = $request->search;
            $blocks->where(function ($query) use ($search) {
                $query->where('block_name', 'LIKE', "%{$search}%")
                    ->orWhere('block_id', 'LIKE', "%{$search}%")
                    ->orWhere('id', 'LIKE', "%{$search}%")
                    ->orWhereHas('entrybyid', function ($query) use ($search) {
                        $query->where('name', 'LIKE', "%{$search}%");
                    })
                    ->orWhereHas('yard', function ($query) use ($search) {
                        $query->where('yard_name', 'LIKE', "%{$search}%");
                    });
            });
        }

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

        // Pagination with 'noofrec' and 'currentpage'
        $noOfRec = $request->noofrec ?? 100;
        $currentPage = $request->currentpage ?? 1;

        $blocks = $blocks->orderBy('id', 'DESC')
            ->skip($noOfRec * ($currentPage - 1))
            ->take($noOfRec)
            ->get();

        // Adding yard_name and yard_id to each block result
        $blocks = $blocks->map(function ($block) {
            $block->yard_name = $block->yard->yard_name ?? null;  // Add yard_name if related yard exists
            $block->yard_id = $block->yard->id ?? null;  // Add yard_id if related yard exists
            return $block;
        });

        // Response structure
        return response()->json([
            'success' => true,
            'total' => $count,
            'data' => $blocks,
        ]);
    }


    public function store(Request $request)
    {
        // Validate Input Data
        $validator = validator($request->all(), [
            'yard_id' => 'required|integer|exists:yards,id',
            'block_name' => 'required|string|max:255',
            'capacity' => 'required|integer|min:1'
        ]);

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

        try {
            $containers_types = [];

            // Initialize container_types and stored_containers if not set
            $container_types = $request->input('container_types', []);
            $stored_containers = $request->input('stored_containers', []);

            // Check the total size capacity of the containers
            $total_capacity = 0;
            foreach ($container_types as $key => $value) {
                if (isset($value)) {
                    // $container_type = ContainerType::findOrFail($value);
                    Log::info($value['max_stored_containers']);
                    if ($value['type_size'] == 40) {
                        $total_capacity += $value['max_stored_containers'] ?? 0;
                    } else if ($value['type_size'] == 20) {
                        $total_capacity += ($value['max_stored_containers']  ?? 0) / 2;
                    }
                    Log::info($total_capacity);
                }
            }

            Log::info("Actual Capacity : " . $request['capacity']);
            Log::info("Took Capacity : " . $total_capacity);
            if (intval($request['capacity']) < $total_capacity) {
                return response()->json([
                    'success' => false,
                    'message' => 'You cannot add container types exceeding the capacity.',
                ]);
            }

            // Prepare containers_types array
            foreach ($container_types as $key => $value) {
                if (isset($value)) {
                    $containers_types[] = [
                        'id' => $key + 1,
                        'container_type' => $value['container_type']??0,
                        'capacity' => $stored_containers[$key] ?? 0,
                        'stored_containers' => $stored_containers[$key] ?? 0,
                    ];
                }
            }

            // Create and Save Block
            $block = new Block;
            $block->yard_id = $request->input('yard_id');
            $block->block_name = $request->input('block_name');
            $block->container_types = json_encode($request['container_types']);
            $block->area = $request->input('area');
            $block->area_unit = $request->input('area_unit');
            $block->capacity = $request->input('capacity');
            $block->description = $request->input('description');
            $block->available_space = $request->input('capacity') ?? 0;
            $block->status = 1;   // setting by default active
            $block->save();

            // Update Block ID
            $block->block_id = 'BLK000' . $block->id;
            $block->update();

            return response()->json([
                'success' => true,
                'message' => 'Block created successfully.',
                'data' => [
                    'block' => $block,
                ],
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'An error occurred while creating the block. ' . $e->getMessage(),
            ], 500);
        }
    }

    public function update(Request $request)
    {
        $user = Auth::user();

        // Validate the request
        $validator = validator($request->all(), [
            'id' => 'required|integer',
            'block_name' => 'required|string|max:255',
            'capacity' => 'required|integer',
        ]);

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

            // Find the Block by ID
        $block = Block::where('id',$request['id'])->first();

        if(!$block){
            return response()->json([
                'success' => false,
                'message' => 'Block not found',
                'data' => null
            ]);
        }

        // Calculate total capacity
        $container_types = $request->input('container_types', []);
        $stored_containers = $request->input('stored_containers', []);
        $containers_types = [];
        $total_capacity = 0;

        foreach ($container_types as $key => $value) {
                if (isset($value)) {
                    // $container_type = ContainerType::findOrFail($value);
                    Log::info($value['max_stored_containers']);
                    if ($value['type_size'] == 40) {
                        $total_capacity += $value['max_stored_containers'] ?? 0;
                    } else if ($value['type_size'] == 20) {
                        $total_capacity += ($value['max_stored_containers']  ?? 0) / 2;
                    }
                    Log::info($total_capacity);
                }
            }

        if (intval($request['capacity']) < $total_capacity) {
            return response()->json([
                'success' => false,
                'message' => 'You cannot add container types exceeding the block capacity.',
            ], 200);
        }

        // Update Block details
        $blockData = [
            'block_name' => $request['block_name'],
            'container_types' => json_encode($request['container_types']),
            'capacity' => $request['capacity'],
        ];

        $block->update($blockData);

        // Optionally update Block ID
        $block['block_id'] = 'BLK000' . $block->id;
        $block->update();

        return response()->json([
            'success' => true,
            'message' => 'Block updated successfully',
            'data' => $block,
        ], 200);

    }


    // Details of a block 123456    
    public function show(Request $request)
    {
        // Retrieve blockId from the input
        $blockId = request()->input('block_id');

        // Ensure the blockId is provided
        if (!$blockId) {
            return response()->json(['error' => 'Block ID is required'], 400);
        }

        // Fetch the necessary data
        $containersType = ContainerType::where('status', 0)->get();
        $block = Block::findOrFail($blockId);

        // Fetch the yard name using the yard_id from the block
        $yardName = Yard::find($block->yard_id)->yard_name ?? null;

        // Add yard_name to the block data
        $block->yard_name = $yardName;

        $containers = ContainerDetail::with('container_types', 'container_owner')
            ->where('did_no', '=', null)
            ->where('status', '!=', 'completed')
            ->where('block_id', $blockId)
            ->count();

        $containerOwners = ContainerOwner::all();

        // Return data as JSON, including the yard name in the block
        return response()->json([
            'block' => $block,
            'no_of_containers' => $containers
        ]);
    }



    public function containers(Request $request)
    {

        $containers = ContainerDetail::where('block_id', $request['id'])
            ->with('container_types', 'container_owner')
            ->where('did_no', '=', null)
            ->where('status', '!=', 'completed');

        if (isset($request['container_id']) && $request['container_id'] != null) {
            $containers = $containers->where('container_id', $request['container_id']);
        }

        if (isset($request['container_owner_id']) && $request['container_owner_id'] != null) {
            $containers = $containers->where('container_owner_id', $request['container_owner_id']);
        }

        if (!empty($request->search)) {

            $containers = $containers->where(function ($query) use ($request) {

                $query->where('container_id', 'LIKE', '%' . $request['search'] . '%')
                    ->orWhere('container_condition', 'LIKE', '%' . $request['search'] . '%')
                    ->orWhereHas('container_owner', function ($query) use ($request) 
                        {
                            $query->where('display_name', 'LIKE', '%' . $request['search'] . '%');
                        });

            });
        }

        if (isset($request['container_status']) && $request['container_status'] != null) {
            $containers = $containers->where('container_status', $request['container_status']);
        }

        if (isset($request['container_condition']) && $request['container_condition'] != null) {
            $containers = $containers->where('container_condition', $request['container_condition']);
        }
        $containers = $containers->get();

        // dd($containers);

        return response()->json([
            'success' => true,
            'message' => 'success',
            'data' => $containers
        ]);
    }


    public function destroy(Request $request)
    {
        $user = Auth::user();

        // Validate the request
        $validator = validator($request->all(), [
            'id' => 'required|exists:blocks,id', // Validate ID exists in Block table
        ]);

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

        try {
            // Find the Block by ID or fail
            $block = Block::findOrFail($request->input('id'));

            // Delete the block record
            $block->delete();

            return response()->json([
                'success' => true,
                'message' => 'Block deleted successfully.',
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid ID to delete.',
            ], 404);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'An error occurred while deleting the block.',
            ], 500);
        }
    }


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

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

        try {
            // Find the Block record by ID or throw a ModelNotFoundException
            $block = Block::where('id', $request->input('id'))->firstOrFail();

            // Toggle the status and set the message
            if ($block->status == 1) {
                $block->status = 0;
                $msg = "Inactive Successfully";
            } else {
                $block->status = 1;
                $msg = "Active Successfully";
            }

            // Save the updated status
            $block->save();

            return response()->json([
                'success' => true,
                'message' => $msg
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            // Return error message if the record is not found
            return response()->json([
                'success' => false,
                'message' => 'Invalid ID to update'
            ], 404);
        } catch (\Exception $e) {
            // Handle any other exceptions
            return response()->json([
                'success' => false,
                'message' => 'An error occurred while updating the status',
                'error' => $e->getMessage()
            ], 500);
        }
    }


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

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

            // Get the id from the request
            $yardId = $request->input('id');

            // Fetch blocks associated with the yard
            $blocks = Block::where('yard_id', $yardId)->get();

            return response()->json([
                'success' => true,
                'message' => 'Blocks fetched successfully',
                'data' => $blocks
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Yard not found for the given ID'
            ], 404);
        } catch (\Exception $e) {
            // Handle any unexpected errors
            return response()->json([
                'success' => false,
                'message' => 'An error occurred while fetching the blocks',
                'error' => $e->getMessage()
            ], 500);
        }
    }




    // public function containers(Request $request)
    // {

    //     $containers = ContainerDetail::where('order_id', '>', 0)
    //         ->with('container_types', 'container_owner')
    //         ->where('did_no', '=', null)
    //         ->where('status', '!=', 'completed');

    //     if (isset($request['container_id']) && $request['container_id'] != null) {
    //         $containers = $containers->where('container_id', $request['container_id']);
    //     }

    //     if (isset($request['container_owner_id']) && $request['container_owner_id'] != null) {
    //         $containers = $containers->where('container_owner_id', $request['container_owner_id']);
    //     }

    //     if (isset($request['container_status']) && $request['container_status'] != null) {
    //         $containers = $containers->where('container_status', $request['container_status']);
    //     }

    //     if (isset($request['container_condition']) && $request['container_condition'] != null) {
    //         $containers = $containers->where('container_condition', $request['container_condition']);
    //     }
    //     $containers = $containers->get();

    //     // dd($containers);

    //     return response()->json([
    //         'success' => true,
    //         'message' => 'success',
    //         'data' => $containers
    //     ]);
    // }



    public function filter(Request $request)
    {

        $blocks = Block::query();

        if (isset($request['yardid']) && $request['yardid'] != 0 && $request['yardid'] != '') {
            $blocks = $blocks->where('yard_id', $request['yardid']);
        }

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

        $blocks = $blocks->get();

        $yards = Yard::where('status', 0)->get();

        $currentRoute = \Route::currentRouteName();

        return response()->json([
            'success' => true,
            'message' => 'success',
            'blocks' => $blocks,
            'yards' => $yards,
        ]);
    }


    public function filterWithYards(Request $request)
    {
        try {
            // Validate the input
            $request->validate([
                'id' => 'nullable|integer',
                'status' => 'nullable|string|max:255'
            ]);

            // Retrieve input values
            $id = $request->input('id');
            $status = $request->input('status');

            // Initialize the query
            $blocks = Block::query();

            if (!empty($id)) {
                $blocks = $blocks->where('yard_id', $id);
            }

            if (!empty($status)) {
                $blocks = $blocks->where('status', $status);
            }

            $blocks = $blocks->get();

            // Retrieve yards with status 0
            $yards = Yard::where('status', 0)->get();

            $currentRoute = \Route::currentRouteName();

            return response()->json([
                'success' => true,
                'message' => 'Data retrieved successfully.',
                'blocks' => $blocks,
                'yards' => $yards,
                'currentRoute' => $currentRoute,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'An error occurred while processing your request.',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

}
