<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Models\Notification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\Response;

class NotificationController extends Controller
{
    /**
     * List notifications for the current user (superadmin or franchisee).
     */
    public function index(Request $request)
    {
        $perPage = $request->get('per_page', 50);
        $page = $request->get('page', 1);
        $type = $request->get('type', 'all'); // all | read | unread

        try {
            $user = Auth::user();
            $userId = $user->role === 'super_admin' ? (string) $user->id : $user->franchisee_id;

            // Base query: notifications relevant to the user
            $baseQuery = Notification::query()
                ->whereJsonContains('global_notification', $userId);

            // Count unread
            $unreadCount = (clone $baseQuery)
                ->where(function ($q) use ($userId) {
                    $q->whereNull('global_read')
                        ->orWhereJsonDoesntContain('global_read', $userId);
                })
                ->count();

            // Count read
            $readCount = (clone $baseQuery)
                ->whereJsonContains('global_read', $userId)
                ->count();

            // Apply type filter for paginated results
            $query = clone $baseQuery;

            if ($type === 'unread') {
                $query->where(function ($q) use ($userId) {
                    $q->whereNull('global_read')
                        ->orWhereJsonDoesntContain('global_read', $userId);
                });
            } elseif ($type === 'read') {
                $query->whereJsonContains('global_read', $userId);
            }

            // Order by latest
            // Select only required columns
            $query->select([
                'id',
                'type',
                'message',
                'data',
                'status',
                'created_at',
                'updated_at',
                'global_read',
            ])->orderByDesc('created_at');

            // Paginate
            $notifications = $query->paginate($perPage, ['*'], 'page', $page);
            // Add read/unread flag to each notification
            $notifications->getCollection()->transform(function ($notification) use ($userId) {
                $notification->read = !empty($notification->global_read) && in_array($userId, $notification->global_read);
                unset($notification->global_read); // remove if you don't want to return raw array
                return $notification;
            });
            return ApiResponse::success([
                'notifications' => $notifications,
                'counts' => [
                    'read' => $readCount,
                    'unread' => $unreadCount,
                    'total' => $readCount + $unreadCount,
                ],
            ], 'Notification list with counts.');

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }


    public function count()
    {
        try {
            $user = Auth::user();
            $userId = $user->role === 'super_admin' ? (string) $user->id : $user->franchisee_id;

            // Start query: notifications relevant to the user
            $query = Notification::query()
                ->whereJsonContains('global_notification', $userId)
                ->where(function ($q) use ($userId) {
                    $q->whereNull('global_read')
                        ->orWhereJsonDoesntContain('global_read', $userId);
                });

            $unreadCount = $query->count();

            return ApiResponse::success(['unread_count' => $unreadCount], 'Unread notifications count.');

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }


    /**
     * Mark a notification as read.
     */
    public function markAsRead($id)
    {
        try {
            $user = Auth::user();
            $idToMark = $user->role === 'super_admin' ? (string) $user->id : $user->franchisee_id;

            // Fetch the notification
            $notification = Notification::findOrFail($id);

            // Decode existing global_read array or initialize empty
            $globalRead = $notification->global_read ?? [];

            // Add ID if not already present
            if (!in_array($idToMark, $globalRead)) {
                $globalRead[] = $idToMark;

                $notification->update([
                    'global_read' => array_values($globalRead), // reindex for proper JSON
                ]);
            }

            return ApiResponse::success($notification, 'Notification marked as read successfully.');

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }


    /**
     * Mark all notifications as read for the current user.
     */
    public function markAllAsRead(Request $request)
    {
        // Validate request
        $validator = Validator::make($request->all(), [
            'notification_ids' => 'required|array|min:1',
            'notification_ids.*' => 'string|exists:notifications,id',
        ]);

        if ($validator->fails()) {
            return ApiResponse::error(
                $validator->errors()->first(),
                Response::HTTP_UNPROCESSABLE_ENTITY
            );
        }

        try {
            $user = Auth::user();
            $idToMark = $user->role === 'super_admin' ? (string) $user->id : $user->franchisee_id;
            $notificationIds = $request->notification_ids;

            // Fetch all notifications by IDs
            $notifications = Notification::whereIn('id', $notificationIds)->get();

            // Mark each notification as read for this user
            foreach ($notifications as $notification) {
                $globalRead = $notification->global_read ?? [];

                if (!in_array($idToMark, $globalRead)) {
                    $globalRead[] = $idToMark;

                    $notification->update([
                        'global_read' => array_values($globalRead), // reindex array
                    ]);
                }
            }

            return ApiResponse::success($notifications, 'Selected notifications marked as read successfully.');

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }


    /**
     * Delete a single notification.
     */
    public function destroy($id)
    {
        try {
            $user = Auth::user();
            $notification = Notification::findOrFail($id);

            // Determine the ID to remove (super_admin or franchisee)
            $idToRemove = $user->role === 'super_admin' ? (string) $user->id : $user->franchisee_id;

            $globalNotification = $notification->global_notification ?? [];

            // Check if the ID exists in global_notification
            if (!in_array($idToRemove, $globalNotification)) {
                return ApiResponse::error(
                    'User ID not found in global notification.',
                    Response::HTTP_NOT_FOUND
                );
            }

            // Remove the ID
            $globalNotification = array_filter($globalNotification, fn($item) => $item !== $idToRemove);

            // Update the notification
            $notification->update([
                'global_notification' => array_values($globalNotification), // reindex array
            ]);

            return ApiResponse::success($notification, 'Notification deleted successfully.');

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }


    /**
     * Clear all notifications for the current user.
     */
    public function clearAll(Request $request)
    {
        // Validate request
        $validator = Validator::make($request->all(), [
            'notification_ids' => 'required|array|min:1',
            'notification_ids.*' => 'string|exists:notifications,id',
        ]);

        if ($validator->fails()) {
            return ApiResponse::error(
                $validator->errors()->first(),
                Response::HTTP_UNPROCESSABLE_ENTITY
            );
        }

        try {
            $user = Auth::user();
            $notificationIds = $request->notification_ids;

            // Determine the ID to remove (franchise or super_admin)
            $idToRemove = $user->role === 'super_admin' ? (string) $user->id : $user->franchisee_id;

            // Fetch all relevant notifications
            $notifications = Notification::whereIn('id', $notificationIds)->get();

            // Update notifications in a single loop
            foreach ($notifications as $notification) {
                $globalNotification = $notification->global_notification ?? [];

                // Remove the user ID if it exists
                $globalNotification = array_filter($globalNotification, fn($id) => $id !== $idToRemove);

                // Save updated array
                $notification->update([
                    'global_notification' => array_values($globalNotification),
                ]);
            }

            return ApiResponse::success(
                $notifications,
                'Selected notifications cleared successfully.'
            );

        } catch (\Throwable $e) {
            return ApiResponse::exception($e);
        }
    }

}
