<?php

namespace App\Notifications;

use App\Models\Application;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

/**
 * Base for everything sent to an applicant about their application.
 *
 * Queued so nothing user-facing waits on mail delivery (PRD 27, 69).
 * Subclasses supply the copy; this class handles the channels, the portal
 * payload and the branded mail shell.
 */
abstract class ApplicationNotification extends Notification implements ShouldQueue
{
    use Queueable;

    public function __construct(public Application $application)
    {
        $this->onQueue('notifications');
    }

    /** @return array<int, string> */
    public function via(object $notifiable): array
    {
        $channels = ['database'];

        if (setting('email_enabled', true)) {
            $channels[] = 'mail';
        }

        return $channels;
    }

    abstract protected function subject(): string;

    abstract protected function heading(): string;

    /** @return array<int, string> */
    abstract protected function lines(): array;

    protected function actionLabel(): ?string
    {
        return 'View Application';
    }

    protected function actionUrl(): ?string
    {
        return route('applicant.applications.show', $this->application);
    }

    /** Short form used when this notification is also sent by SMS. */
    public function toSms(): ?string
    {
        return null;
    }

    public function toMail(object $notifiable): MailMessage
    {
        $mail = (new MailMessage)
            ->subject($this->subject())
            ->greeting($this->heading());

        foreach ($this->lines() as $line) {
            $mail->line($line);
        }

        if ($this->actionLabel() && $this->actionUrl()) {
            $mail->action($this->actionLabel(), $this->actionUrl());
        }

        return $mail->salutation('— Admissions Office, '.setting('university_name', 'King Ceasor University'));
    }

    /** @return array<string, mixed> */
    public function toArray(object $notifiable): array
    {
        return [
            'type' => class_basename($this),
            'title' => $this->subject(),
            'message' => $this->lines()[0] ?? '',
            'application_id' => $this->application->id,
            'application_number' => $this->application->application_number,
            'url' => $this->actionUrl(),
        ];
    }
}
