<?php

namespace App\Mail;

use App\Mail\Concerns\RidesALane;
use App\Mail\Concerns\SendsFromMailbox;
use App\Models\SecurityBlock;
use App\Services\Mail\MailCatalogue;
use App\Services\Mail\MailPurpose;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

/**
 * "Eine Adresse wurde wegen Anmeldeversuchen gesperrt."
 *
 * ZWEI Empfängerkreise, eine Mailart — und das ist keine Bequemlichkeit,
 * sondern der Grund, warum diese Klasse beide Fälle ausdrücklich auseinander
 * hält:
 *
 *  - **Instanz-Sperre** → an den Inhaber. Text in der zweiten Person („bei
 *    Ihrer Cloud"), Anrede aus dem Kundendatensatz, Knopf auf die
 *    Sicherheitsseite des Portals (`portal.security`), wo er die Sperre
 *    einsehen und vorzeitig aufheben kann.
 *  - **Host-Sperre** → an die Betreiber mit `hosts.manage` (siehe
 *    `BlockAddress::notifyHostManagers()`). Eigener Text mit dem NAMEN des
 *    Hosts, keine Anrede, und der Knopf zeigt auf die Host-Detailseite der
 *    Konsole.
 *
 * Der Unterschied ist nicht kosmetisch: ein Betreiber hat im Portal kein
 * Konto, und Host-Sperren erscheinen dort ohnehin nie. Ein Knopf auf
 * `portal.security` in einer Host-Mail führt also zwangsläufig ins Leere —
 * und ohne den Hostnamen im Text stünde in einer Meldung an jemanden mit
 * einem Dutzend Maschinen nicht, welche gemeint ist.
 *
 * Aus dem SYSTEM-Postfach, genau wie NewDeviceSignInMail: das ist kein
 * Gespräch, und eine Antwort darauf soll kein Ticket öffnen. Über die Wegwahl
 * (`MailRoute`, Mailart `security-block`) kann der Betreiber sie auf ein
 * anderes Postfach legen — dann geht sie auch über DESSEN SMTP-Konto, nicht
 * nur mit dessen Absenderzeile.
 *
 * Die Drossel — höchstens eine Mail je Subjekt und Stunde — sitzt in
 * BlockAddress, nicht hier: diese Klasse weiß nichts davon, ob sie gerade die
 * erste oder die zehnte Sperre dieser Stunde beschreibt, und muss es auch
 * nicht wissen.
 */
class SecurityBlockMail extends Mailable implements ShouldQueue
{
    use Queueable, RidesALane, SendsFromMailbox, SerializesModels;

    public function __construct(public SecurityBlock $block)
    {
        $this->mailer(MailCatalogue::mailer('security-block'));
    }

    public function envelope(): Envelope
    {
        $host = $this->block->host;

        return $this->mailboxEnvelope(
            MailPurpose::SYSTEM,
            $host !== null
                ? __('security.mail_subject_host', ['host' => $host->name])
                : __('security.mail_subject'),
            'security-block',
        );
    }

    public function content(): Content
    {
        $host = $this->block->host;

        // instance() statt eines eigenen Customer-Parameters: der Aufrufer
        // (BlockAddress) hat ohnehin nur den Datensatz, und ein zweiter Weg,
        // an dieselbe Instanz zu kommen, wäre eine zweite Stelle, an der der
        // Name veralten könnte.
        $customer = $this->block->instance?->customer;

        return new Content(view: 'mail.security-block', with: [
            // Der Name des Hosts ist das Unterscheidungsmerkmal für die
            // Ansicht: gesetzt heißt Host-Sperre, null heißt Instanz-Sperre.
            // Ein zweites Flag daneben wäre eine zweite Wahrheit.
            'hostName' => $host?->name,
            'name' => (string) ($customer?->contact_name ?: $customer?->name ?: ''),
            'ip' => $this->block->ip,
            'attempts' => $this->block->attempts,
            'blockedAt' => $this->block->blocked_at,
            'expiresAt' => $this->block->expires_at,
            // Der Betreiber hat im Portal kein Konto, und Host-Sperren stehen
            // dort nie. Sein Weg zum Handgriff ist die Host-Detailseite der
            // Konsole, auf der die Host-Sperren mit ihrem Aufheben-Knopf
            // stehen (Aufgabe 6, App\Livewire\Admin\HostDetail).
            'securityUrl' => $host !== null
                ? route('admin.hosts.show', $host)
                : route('portal.security'),
        ]);
    }
}
