<?php

namespace App\Http\Controllers;

use Http;
use Illuminate\Http\Request;
use MongoDB\Client as MongoDBClient;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use MongoDB\Client as MongoClient;

class VirtualWallController extends Controller
{
    protected $mongoDB;

    public function __construct(MongoDBClient $mongoDB)
    {
        $this->middleware('auth');
        $this->mongoDB = $mongoDB;
    }

    public function index($region_id = null)
    {
        if ($region_id !== null) {
            $region_id = $region_id;
        }


        $collection = $this->mongoDB->dataprocess->cameras;
        $collection_reg = $this->mongoDB->dataprocess->regions;

        $collection_alarm_count = $this->mongoDB->dataprocess->stream_alarm_counts;


        $match = [
            'user_id' => auth()->user()->uuid,
            'is_virtial_wall' => 1,
        ];

        if ($region_id !== null) {
            $match['region_id'] = new \MongoDB\BSON\ObjectID($region_id);
        }

        $pipeline = [
            [
                '$match' => $match
            ],
            [
                '$lookup' => [
                    'from' => 'steaming_info', // The collection to join
                    'localField' => '_id', // Field from the 'cameras' collection
                    'foreignField' => 'camera_id', // Field from the 'other_collection'
                    'as' => 'joined_data' // Alias for the joined data
                ]
            ],
            [
                '$lookup' => [
                    'from' => 'stream_alarm_counts', // The collection to join
                    'localField' => '_id', // Field from the 'cameras' collection
                    'foreignField' => 'camera_id', // Field from the 'stream_alarm_counts' collection
                    'as' => 'alarm_counts' // Alias for the joined data
                ]
            ],
            [
                '$sort' => ['_id' => -1]
            ],
            [
                '$limit' => 8 // Limit the results to the latest 8 documents
            ]
        ];


        $pipeline_reg = [
            [
                '$match' => [
                    'status' => 1, // Assuming you want active regions
                    'uuid' => auth()->user()->uuid,
                ]
            ],
            [
                '$sort' => ['created_at' => -1] // Sort by creation date, newest first
            ],
            [
                '$project' => [
                    '_id' => 1,
                    'region' => 1,
                    'status' => 1,
                    'created_at' => 1,
                    'uuid' => 1
                ]
            ]
        ];


        $cameras = json_encode($collection->aggregate($pipeline)->toArray());
        $regions = $collection_reg->aggregate($pipeline_reg)->toArray();

        return [$cameras, $regions];
        // return view("virtualwall.view_virtial_wall",compact('cameras'));
    }



    public function get_cameras_stream()
    {
        $collection_preset = $this->mongoDB->dataprocess->presets;
        try {
            $collection_preset = $this->mongoDB->dataprocess->presets;

            $pipeline_preset = [
                [
                    '$match' => [
                        'user_id' => auth()->user()->uuid,
                    ]
                ],
                [
                    '$sort' => ['created_at' => -1]
                ],
                [
                    '$lookup' => [
                        'from' => 'regions',
                        'let' => ['region_id' => ['$toObjectId' => '$region']],
                        'pipeline' => [
                            [
                                '$match' => [
                                    '$expr' => ['$eq' => ['$_id', '$$region_id']]
                                ]
                            ],
                            [
                                '$project' => [
                                    'region' => 1,
                                    '_id' => 0
                                ]
                            ]
                        ],
                        'as' => 'region_details'
                    ]
                ],
                [
                    '$addFields' => [
                        'region_details' => ['$arrayElemAt' => ['$region_details', 0]],
                        'preset_ids' => [
                            '$map' => [
                                'input' => '$presets',
                                'as' => 'preset',
                                'in' => [
                                    '$cond' => [
                                        'if' => ['$eq' => [['$type' => '$$preset'], 'object']],
                                        'then' => ['$substr' => ['$$preset.preset', 11, 24]],
                                        'else' => ['$substr' => ['$$preset', 2, 24]]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ],
                [
                    '$addFields' => [
                        'preset_ids_debug' => '$preset_ids'
                    ]
                ],
                [
                    '$lookup' => [
                        'from' => 'cameras',
                        'let' => ['camera_ids' => '$preset_ids'],
                        'pipeline' => [
                            [
                                '$match' => [
                                    '$expr' => [
                                        '$in' => [
                                            ['$toString' => '$_id'],
                                            '$$camera_ids'
                                        ]
                                    ]
                                ]
                            ],
                            [
                                '$project' => [
                                    'cameraname' => 1,
                                    '_id' => 1
                                ]
                            ],
                            [
                                '$group' => [
                                    '_id' => null,
                                    'cameras' => [
                                        '$push' => '$$ROOT'
                                    ]
                                ]
                            ],
                            [
                                '$project' => [
                                    'cameras' => [
                                        '$map' => [
                                            'input' => '$$camera_ids',
                                            'as' => 'id',
                                            'in' => [
                                                '$arrayElemAt' => [
                                                    [
                                                        '$filter' => [
                                                            'input' => '$cameras',
                                                            'as' => 'camera',
                                                            'cond' => [
                                                                '$eq' => [
                                                                    ['$toString' => '$$camera._id'],
                                                                    '$$id'
                                                                ]
                                                            ]
                                                        ]
                                                    ],
                                                    0
                                                ]
                                            ]
                                        ]
                                    ]
                                ]
                            ],
                            [
                                '$unwind' => '$cameras'
                            ],
                            [
                                '$replaceRoot' => [
                                    'newRoot' => '$cameras'
                                ]
                            ]
                        ],
                        'as' => 'camera_details'
                    ]
                ],
                [
                    '$addFields' => [
                        'camera_details_debug' => '$camera_details'
                    ]
                ],
                [
                    '$project' => [
                        '_id' => 1,
                        'region' => 1,
                        'label' => 1,
                        'presets' => 1,
                        'region_details' => 1,
                        'camera_details' => 1,
                        'preset_ids_debug' => 1,
                        'camera_details_debug' => 1
                    ]
                ]
            ];

            $presets = $collection_preset->aggregate($pipeline_preset)->toArray();

            if (empty($presets)) {
                // return view("virtualwall.view_virtial_wall")->with('warning', 'No presets found.');
                $presets = [];
            }

            return view("virtualwall.view_virtial_wall", compact('presets'));
        } catch (\MongoDB\Driver\Exception\Exception $e) {
            \Log::error('MongoDB Error: ' . $e->getMessage());
            return view("virtualwall.view_virtial_wall")->with('error', 'An error occurred while fetching data from the database.');
        } catch (\Exception $e) {
            \Log::error('Error in get_cameras_stream: ' . $e->getMessage());
            return view("virtualwall.view_virtial_wall")->with('error', 'An unexpected error occurred.');
        }

    }






    public function preset_save(Request $request)
    {
        $request->validate([
            'preset_label' => 'required|array',
            'region_id' => 'required|array',
            'preset' => 'required|array',
        ]);

        $collection = $this->mongoDB->dataprocess->presets;

        $successCount = 0;
        $failCount = 0;

        // Use array_values to reindex the arrays and ensure we process all items
        $presetLabels = array_values($request->input('preset_label'));
        $regionIds = array_values($request->input('region_id'));
        $presets = array_values($request->input('preset'));

        $totalRecords = count($presetLabels);

        for ($i = 0; $i < $totalRecords; $i++) {
            if (!isset($regionIds[$i]) || !isset($presetLabels[$i]) || !isset($presets[$i])) {
                continue; // Skip this iteration if any required data is missing
            }

            $regionId = $regionIds[$i];
            $presetLabel = $presetLabels[$i];
            $currentPresets = $presets[$i]; // This should be an array of presets for this row

            // Prepare the data to insert
            $dataToInsert = [
                'region' => new \MongoDB\BSON\ObjectID($regionId),
                'label' => $presetLabel,
                'presets' => [], // Initialize an empty array for presets
                'user_id' => auth()->user()->uuid,
                'created_at' => new \MongoDB\BSON\UTCDateTime(now()),
                'updated_at' => new \MongoDB\BSON\UTCDateTime(now()),
            ];

            // Handle $currentPresets as an array
            foreach ($currentPresets as $preset) {
                $dataToInsert['presets'][] = json_encode([$preset]);
            }

            // Only insert if there are presets
            if (!empty($dataToInsert['presets'])) {
                // Insert the data into MongoDB
                $result = $collection->insertOne($dataToInsert);

                // Check if the insert was successful
                if ($result->getInsertedCount() > 0) {
                    $successCount++;
                } else {
                    $failCount++;
                }
            } else {
                $failCount++;
            }
        }

        if ($failCount == 0) {
            return redirect()->back()->with('success', "$successCount preset(s) added successfully");
        } elseif ($successCount == 0) {
            return redirect()->back()->with('error', "Failed to add all presets. Please try again.");
        } else {
            return redirect()->back()->with('warning', "$successCount preset(s) added successfully. $failCount preset(s) failed to add.");
        }
    }




    public function loadPreset($preset_id = null)
    {
        $collection = $this->mongoDB->dataprocess->presets;
        $preset = $collection->findOne(['_id' => new \MongoDB\BSON\ObjectID($preset_id)]);

        if (!$preset) {
            return response()->json(['error' => 'Preset not found'], 404);
        }

        // Extract preset keys from the 'presets' array
        $presetKeys = [];
        if (isset($preset['presets']) && $preset['presets'] instanceof \MongoDB\Model\BSONArray) {
            foreach ($preset['presets'] as $presetJson) {
                $presetData = json_decode($presetJson, true);
                if (is_array($presetData) && isset($presetData['preset'])) {
                    $presetKeys[] = $presetData['preset'];
                } elseif (is_string($presetJson)) {
                    // Handle the case where 'presetJson' is directly the ID string
                    $presetKeys[] = substr($presetJson, 2, 24);
                }
            }
        }

        // Convert preset keys to ObjectIDs
        $cameraObjectIds = array_map(function ($id) {
            return new \MongoDB\BSON\ObjectID($id);
        }, $presetKeys);

        // Fetch matching camera data from the cameras collection
        $cameraCollection = $this->mongoDB->dataprocess->cameras;
        $matchedCameras = $cameraCollection->find(['_id' => ['$in' => $cameraObjectIds]]);

        // Convert the cursor to an array while preserving the order of presetKeys
        $camerasMap = [];
        foreach ($matchedCameras as $camera) {
            $camerasMap[(string) $camera['_id']] = $camera;
        }

        $cameras = [];
        foreach ($presetKeys as $presetKey) {
            if (isset($camerasMap[$presetKey])) {
                $cameras[] = $camerasMap[$presetKey];
            }
        }

        // Return the matched camera data
        return response()->json(['cameras' => $cameras]);
    }


    public function preset_delete($id)
    {
        try {
            // Get the MongoDB collection
            $collection = $this->mongoDB->dataprocess->presets;

            // Convert the string ID to MongoDB ObjectId
            $objectId = new \MongoDB\BSON\ObjectID($id);

            // Delete the document
            $result = $collection->deleteOne(['_id' => $objectId]);

            if ($result->getDeletedCount() > 0) {
                return redirect()->back()->with('success', 'Deleted Successfully');
            } else {
                return redirect()->back()->with('error', 'Preset not found');

            }
        } catch (\Exception $e) {
            return response()->json(['message' => 'Error deleting preset', 'error' => $e->getMessage()], 500);
        }
    }


}
