<?php

namespace Modules\Notification\Controllers\Api;

use App\Controllers\BaseController;
use Firebase\JWT\JWT;
use Modules\Notification\Models\NotificationModel;
use Modules\Notification\Models\UserNotificationModel;
use Modules\User\Models\UserModel;

class Notification extends BaseController
{
    protected $notificationModel;
    protected $userNotificationModel;

    public function __construct()
    {
        $this->notificationModel = new NotificationModel();
        $this->userNotificationModel = new UserNotificationModel();
    }

    /**
     * Get user notifications
     */
    // public function getUserNotifications($userId)
    // {
    //     try {
    //         $limit = $this->request->getGet('limit') ?? 50;
    //         $offset = $this->request->getGet('offset') ?? 0;
            
    //         $notifications = $this->userNotificationModel->getUserNotifications($userId, $limit, $offset);
    //         $unreadCount = $this->userNotificationModel->getUnreadCount($userId);
            
    //         return $this->response->setJSON([
    //             'status' => 'success',
    //             'data' => [
    //                 'notifications' => $notifications,
    //                 'unread_count' => $unreadCount,
    //                 'total_count' => count($notifications)
    //             ]
    //         ]);
    //     } catch (\Exception $e) {
    //         return $this->response->setStatusCode(500)->setJSON([
    //             'status' => 'error',
    //             'message' => 'Failed to fetch notifications',
    //             'error' => $e->getMessage()
    //         ]);
    //     }
    // }
    public function getUserNotifications($userId)
    {
        try {
            $limit = $this->request->getGet('limit') ?? 50;
            $offset = $this->request->getGet('offset') ?? 0;
            
            $limit = (int) $limit;
            $offset = (int) $offset;

            $notifications = $this->userNotificationModel->getUserNotifications($userId, $limit, $offset);
            $counts        = $this->userNotificationModel->getUserCounts((int) $userId);

            $notificationsData = array_map(function ($notification) {
                $record = (array) $notification;
                $record['sent_at']  = !empty($record['sent_at']) ? date('c', strtotime($record['sent_at'])) : null;
                $record['read_at']  = !empty($record['read_at']) ? date('c', strtotime($record['read_at'])) : null;
                $record['created_at'] = !empty($record['created_at']) ? date('c', strtotime($record['created_at'])) : null;
                $record['updated_at'] = !empty($record['updated_at']) ? date('c', strtotime($record['updated_at'])) : null;
                return $record;
            }, $notifications);

            return $this->response->setJSON([
                'status' => 'success',
                'data' => [
                    'notifications' => $notificationsData,
                    'unread_count' => $counts['unread'],
                    'total_count' => $counts['total'],
                    'limit' => $limit,
                    'offset' => $offset
                ]
            ]);
        } catch (\Exception $e) {
            return $this->response->setStatusCode(500)->setJSON([
                'status' => 'error',
                'message' => 'Failed to fetch notifications',
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * Mark notification as read
     */
    public function markAsRead($notificationId)
    {
        try {
            $payload = $this->request->getJSON(true) ?? [];
            $userId  = $payload['user_id'] ?? $this->request->getPost('user_id');
            
            if (!$userId) {
                return $this->response->setStatusCode(400)->setJSON([
                    'status' => 'error',
                    'message' => 'User ID is required'
                ]);
            }
            
            $result = $this->userNotificationModel->markAsRead($notificationId, $userId);
            
            if ($result) {
                return $this->response->setJSON([
                    'status' => 'success',
                    'message' => 'Notification marked as read'
                ]);
            } else {
                return $this->response->setStatusCode(404)->setJSON([
                    'status' => 'error',
                    'message' => 'Notification not found or already marked as read'
                ]);
            }
        } catch (\Exception $e) {
            return $this->response->setStatusCode(500)->setJSON([
                'status' => 'error',
                'message' => 'Failed to mark notification as read',
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * Get unread notifications count
     */
    public function getUnreadCount($userId)
    {
        try {
            $count = $this->userNotificationModel->getUnreadCount($userId);
            
            return $this->response->setJSON([
                'status' => 'success',
                'data' => [
                    'unread_count' => $count
                ]
            ]);
        } catch (\Exception $e) {
            return $this->response->setStatusCode(500)->setJSON([
                'status' => 'error',
                'message' => 'Failed to fetch unread count',
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * Mark all notifications as read for a user
     */
    public function markAllAsRead()
    {
        try {
            $userId = $this->resolveUserIdFromBearerToken();
            if ($userId <= 0) {
                return $this->response->setStatusCode(401)->setJSON([
                    'status' => 'error',
                    'message' => 'Unauthorized',
                ]);
            }

            $updated = (int) $this->userNotificationModel->markAllAsRead($userId);
            
            return $this->response->setJSON([
                'status' => 'success',
                'message' => 'All notifications marked as read',
                'data' => [
                    'updated' => $updated,
                ],
            ]);
        } catch (\Exception $e) {
            return $this->response->setStatusCode(500)->setJSON([
                'status' => 'error',
                'message' => 'Failed to mark all notifications as read',
                'error' => $e->getMessage()
            ]);
        }
    }

    private function resolveUserIdFromBearerToken(): int
    {
        $authHeader = $this->request->getHeaderLine('Authorization');
        if (! $authHeader) {
            // Some deployments may use server var instead of header bag.
            $authHeader = (string) ($this->request->getServer('HTTP_AUTHORIZATION') ?? '');
        }

        $authHeader = trim($authHeader);
        if ($authHeader === '') {
            return 0;
        }

        if (stripos($authHeader, 'Bearer ') === 0) {
            $token = trim(substr($authHeader, 7));
        } else {
            // Be permissive: allow raw token too.
            $token = $authHeader;
        }

        if ($token === '') {
            return 0;
        }

        $key = getenv('TOKEN_SECRET');
        if (! $key) {
            return 0;
        }

        try {
            $decoded = JWT::decode($token, $key, ['HS256']);
        } catch (\Throwable $e) {
            return 0;
        }

        $slug = isset($decoded->slug) ? (string) $decoded->slug : '';
        if ($slug === '') {
            return 0;
        }

        $user = (new UserModel())->where('slug', $slug)->first();
        if (! $user) {
            return 0;
        }

        return (int) ($user->id ?? 0);
    }
}
