<?php

declare(strict_types=1);

namespace App\Application\Admin\Notifications;

use App\Framework\Attributes\Route;
use App\Framework\Http\Method;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\Status;
use App\Framework\Router\Result\ViewResult;
use App\Framework\Http\Responses\JsonResponse;
use App\Framework\Notification\Storage\NotificationRepository;
use App\Framework\Notification\ValueObjects\NotificationId;
use App\Framework\Meta\MetaData;

/**
 * Admin Notifications Controller
 *
 * Displays and manages system notifications for administrators
 */
final readonly class NotificationsAdminController
{
    public function __construct(
        private NotificationRepository $notificationRepository
    ) {}

    /**
     * Display notifications list
     */
    #[Route(path: '/admin/notifications', method: Method::GET)]
    public function index(HttpRequest $request): ViewResult
    {
        // For now, use 'admin' as recipient ID
        // TODO: Replace with actual authenticated admin user ID
        $adminUserId = 'admin';

        // Get pagination parameters
        $page = $request->query->getInt('page', 1);
        $perPage = 20;
        $offset = ($page - 1) * $perPage;

        // Fetch notifications
        $notifications = $this->notificationRepository->findByUser(
            $adminUserId,
            limit: $perPage,
            offset: $offset
        );

        // Get unread count
        $unreadCount = $this->notificationRepository->countUnreadByUser($adminUserId);

        // Transform notifications for template
        $notificationsList = array_map(function ($notification) {
            return [
                'id' => $notification->id->toString(),
                'type' => $notification->type->toString(),
                'title' => $notification->title,
                'body' => $notification->body,
                'priority' => $notification->priority->value,
                'status' => $notification->status->value,
                'is_read' => $notification->status->value === 'read',
                'created_at' => $notification->createdAt->format('Y-m-d H:i:s'),
                'created_at_human' => $this->getHumanReadableTime($notification->createdAt->toDateTime()),
                'action_url' => $notification->actionUrl,
                'action_label' => $notification->actionLabel ?? 'View Details',
                'icon' => $this->getNotificationIcon($notification->type->toString()),
                'badge_class' => $this->getPriorityBadgeClass($notification->priority->value),
            ];
        }, $notifications);

        $data = [
            'notifications' => $notificationsList,
            'unread_count' => $unreadCount,
            'current_page' => $page,
            'per_page' => $perPage,
            'has_more' => count($notifications) === $perPage,
            'has_notifications' => count($notifications) > 0,
            'has_unread' => $unreadCount > 0,  // Boolean flag for if attribute
            'show_pagination' => count($notifications) === $perPage || $page > 1,  // Boolean flag
        ];

        return new ViewResult(
            template: 'notification-index',
            metaData: new MetaData(
                title: 'Notifications - Admin',
                description: 'System notifications for administrators'
            ),
            data    : $data
        );
    }

    /**
     * Mark notification as read
     */
    #[Route(path: '/admin/notifications/{id}/read', method: Method::POST)]
    public function markAsRead(HttpRequest $request, string $id): JsonResponse
    {
        $notificationId = NotificationId::fromString($id);

        $success = $this->notificationRepository->markAsRead($notificationId);

        if (!$success) {
            return new JsonResponse(
                body: ['error' => 'Notification not found'],
                status: Status::NOT_FOUND
            );
        }

        // Get updated unread count
        $unreadCount = $this->notificationRepository->countUnreadByUser('admin');

        return new JsonResponse([
            'success' => true,
            'unread_count' => $unreadCount,
        ]);
    }

    /**
     * Mark all notifications as read
     */
    #[Route(path: '/admin/notifications/read-all', method: Method::POST)]
    public function markAllAsRead(HttpRequest $request): JsonResponse
    {
        $count = $this->notificationRepository->markAllAsReadForUser('admin');

        return new JsonResponse([
            'success' => true,
            'marked_count' => $count,
            'unread_count' => 0,
        ]);
    }

    /**
     * Get unread count for badge
     */
    #[Route(path: '/admin/notifications/unread-count', method: Method::GET)]
    public function getUnreadCount(HttpRequest $request): JsonResponse
    {
        $unreadCount = $this->notificationRepository->countUnreadByUser('admin');

        return new JsonResponse([
            'unread_count' => $unreadCount,
        ]);
    }

    /**
     * Get human-readable time difference
     */
    private function getHumanReadableTime(\DateTimeInterface $timestamp): string
    {
        $now = new \DateTime();
        $diff = $now->diff($timestamp);

        if ($diff->y > 0) {
            return $diff->y . ' year' . ($diff->y > 1 ? 's' : '') . ' ago';
        }
        if ($diff->m > 0) {
            return $diff->m . ' month' . ($diff->m > 1 ? 's' : '') . ' ago';
        }
        if ($diff->d > 0) {
            return $diff->d . ' day' . ($diff->d > 1 ? 's' : '') . ' ago';
        }
        if ($diff->h > 0) {
            return $diff->h . ' hour' . ($diff->h > 1 ? 's' : '') . ' ago';
        }
        if ($diff->i > 0) {
            return $diff->i . ' minute' . ($diff->i > 1 ? 's' : '') . ' ago';
        }

        return 'Just now';
    }

    /**
     * Get icon for notification type
     */
    private function getNotificationIcon(string $type): string
    {
        return match ($type) {
            'ml_performance_degradation' => '⚠️',
            'ml_model_deployed' => '🚀',
            'ml_training_complete' => '✅',
            'system_alert' => '🚨',
            'security_alert' => '🔒',
            'info' => 'ℹ️',
            default => '📢',
        };
    }

    /**
     * Get badge class for priority
     */
    private function getPriorityBadgeClass(string $priority): string
    {
        return match ($priority) {
            'urgent' => 'admin-badge--danger',
            'high' => 'admin-badge--warning',
            'normal' => 'admin-badge--info',
            'low' => 'admin-badge--secondary',
            default => 'admin-badge--info',
        };
    }
}
