<?php

namespace App\Mail;

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

/**
 * Was jemand über das Anfrageformular der Website geschrieben hat.
 *
 * Die einzige Mail, die von DRAUSSEN nach drinnen läuft: alles andere hier
 * schickt der Betrieb an einen Kunden. Deshalb baut sie ihren Umschlag selbst,
 * statt `mailboxEnvelope()` zu benutzen — das setzt Reply-To auf das Postfach,
 * aus dem gesendet wird, und hier soll die Antwort an den Fragenden gehen, nicht
 * an uns selbst.
 *
 * Gesendet wird trotzdem AUS dem Support-Postfach, nicht aus der Adresse des
 * Fragenden: eine Mail, die vorgibt von fremder Domain zu kommen, scheitert an
 * SPF und DKIM und landet im Spam — ausgerechnet die eine Mail, die niemand
 * verpassen darf.
 */
class ContactRequestMail extends Mailable implements ShouldQueue
{
    use Queueable, RidesALane, SendsFromMailbox, SerializesModels;

    /**
     * @param  array{company: ?string, name: string, email: string, phone: ?string, message: string, topic: ?string}  $enquiry
     */
    public function __construct(public array $enquiry)
    {
        $this->mailer('cp_'.MailPurpose::SUPPORT);
    }

    public function envelope(): Envelope
    {
        [$from] = $this->mailboxAddresses(MailPurpose::SUPPORT);

        // Ohne eingerichtetes Postfach fällt beides auf die Absenderadresse des
        // Frameworks zurück. Eine Anfrage still verschwinden zu lassen, weil
        // niemand ein Postfach angelegt hat, wäre der teuerste Fehler auf dieser
        // Seite — sie ist der Grund, warum es die Seite gibt.
        $house = $from?->address ?: (string) config('mail.from.address');

        return new Envelope(
            from: $from ?: new Address($house),
            to: [new Address($house)],
            // Antworten geht an den Fragenden. Das ist der ganze Zweck: der
            // Betreiber drückt „Antworten" und schreibt der Person, nicht sich.
            replyTo: [new Address($this->enquiry['email'], $this->enquiry['name'])],
            subject: $this->subjectLine(),
        );
    }

    public function content(): Content
    {
        return new Content(view: 'mail.contact-request', with: [
            'enquiry' => $this->enquiry,
        ]);
    }

    private function subjectLine(): string
    {
        return self::subjectFor($this->enquiry);
    }

    /**
     * Der Betreff trägt, wonach gefragt wird, und von wem — beides in der
     * Postfachliste sichtbar, ohne die Mail zu öffnen.
     *
     * Öffentlich und statisch, weil ihn zwei brauchen: diese Mail und der
     * Eintrag im Posteingang der Konsole. Zwei Fassungen liefen auseinander,
     * und dann hieße dieselbe Anfrage an zwei Stellen verschieden.
     *
     * @param  array{company: ?string, name: string, topic: ?string}  $enquiry
     */
    public static function subjectFor(array $enquiry): string
    {
        $who = $enquiry['company'] ?: $enquiry['name'];

        return ($enquiry['topic'] ?? null) === 'enterprise'
            ? 'Anfrage: eigene Maschine — '.$who
            : 'Anfrage über die Website — '.$who;
    }
}
