<?php
/**
 * BookiFlex Notification Extension
 *
 * @package    BookiFlex
 * @subpackage Notification
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);
namespace BookiFlex\Extensions\Notification\Provider;

use BookiFlex\Core\Model\Reservation\CancellationActor;
use BookiFlex\Core\Model\Reservation\Reservation;
use BookiFlex\Extensions\Notification\Contract\NotificationEventProviderInterface;
use BookiFlex\Extensions\Notification\Model\NotificationEvent;
use BookiFlex\Extensions\Notification\Model\Recipient;
use BookiFlex\Extensions\Notification\Service\Configuration;

defined( 'ABSPATH' ) || exit;

class CoreNotificationEventProvider implements NotificationEventProviderInterface
{
    public function supportedEvents(): array
    {
        return array_map(fn(NotificationEvent $e) => $e->value, NotificationEvent::cases());
    }

    public function getTemplateName(string $event, Recipient $recipient, string $language = 'en'): string
    {
        $type = match (NotificationEvent::from($event)) {
            NotificationEvent::NewReservation       => 'new',
            NotificationEvent::ReservationConfirmed => 'confirmed',
            NotificationEvent::ReservationCancelled => 'cancelled',
            NotificationEvent::ReservationOverdue   => 'overdue',
            NotificationEvent::WaitingConfirmation  => 'waiting-confirmation',
        };

        return "@notification/emails/{$language}/{$recipient->value}.{$type}.html.twig";
    }

    public function getSubject(string $event, Recipient $recipient): string
    {
        if ($recipient->isEqual(Recipient::Client)) {
            return Configuration::getCustomerSubjects()[$event] ?? '';
        }

        if ($recipient->isEqual(Recipient::Manager)) {
            return Configuration::getManagerSubjects()[$event] ?? '';
        }

        return '';
    }

    public function prepareForPreview(string $event, Reservation $reservation): void
    {
        match (NotificationEvent::from($event)) {
            NotificationEvent::NewReservation => $reservation->markAsWaitingForPayment(),
            NotificationEvent::WaitingConfirmation => $reservation->markAsWaitingForConfirmation(),
            NotificationEvent::ReservationCancelled => (function () use ($reservation) {
                $reservation->markAsWaitingForPayment();
                $reservation->markAsCancelled(CancellationActor::Guest);
            })(),
            NotificationEvent::ReservationOverdue => (function () use ($reservation) {
                $reservation->markAsWaitingForPayment();
                $reservation->markAsOverdue();
            })(),
            NotificationEvent::ReservationConfirmed => (function () use ($reservation) {
                $reservation->markAsWaitingForConfirmation();
                $reservation->markAsConfirmed();
            })(),
        };
    }

    public function modifyContext(array $context, string $event): array
    {
        return $context;
    }
}
