<?php
/**
 * Shared behaviour for the two WooCommerce emails.
 *
 * @package SkyServers\Retragere
 */

declare(strict_types=1);

namespace SkyServers\Retragere\Wc\Emails;

use SkyServers\Retragere\Core\EmailComposer;
use SkyServers\Retragere\Wp\Repository;
use WC_Email;

/**
 * WooCommerce owns the wrapper - header, footer, logo, colours. We own the body,
 * and the body is rendered from the snapshot taken when the request arrived.
 */
abstract class BaseEmail extends WC_Email
{
    /** @var string */
    protected $bodyHtml = '';

    /** @var string */
    protected $bodyText = '';

    /** @var int */
    protected $recordId = 0;

    /**
     * @return array{subject:string,html:string,text:string}|null
     */
    protected function compose(int $recordId): ?array
    {
        $request = Repository::request($recordId);

        if (null === $request) {
            return null;
        }

        $composer  = new EmailComposer(Repository::snapshot($recordId));
        $post      = get_post($recordId);
        $gmt       = $post ? (string) $post->post_date_gmt : gmdate('Y-m-d H:i:s');
        $localTime = (string) wp_date('d.m.Y H:i:s', (int) strtotime($gmt . ' UTC'));
        $reference = Repository::reference($recordId);

        return $this->build($composer, $request, $reference, $localTime, (string) wp_timezone_string());
    }

    /**
     * @param mixed $request
     *
     * @return array{subject:string,html:string,text:string}
     */
    abstract protected function build(
        EmailComposer $composer,
        $request,
        string $reference,
        string $localTime,
        string $timezone
    ): array;

    public function get_content_html(): string
    {
        ob_start();
        wc_get_template('emails/email-header.php', ['email_heading' => $this->get_heading(), 'email' => $this]);
        echo $this->bodyHtml; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped by EmailComposer.
        wc_get_template('emails/email-footer.php', ['email' => $this]);

        return (string) ob_get_clean();
    }

    public function get_content_plain(): string
    {
        return $this->bodyText;
    }

    /**
     * Records the outcome so the register keeps its evidence trail.
     *
     * @param mixed $to
     * @param mixed $subject
     * @param mixed $message
     * @param mixed $headers
     * @param mixed $attachments
     */
    public function send($to, $subject, $message, $headers, $attachments): bool
    {
        $text      = $this->bodyText;
        $transport = '';

        $capture = static function ($phpmailer) use ($text, &$transport) {
            $phpmailer->AltBody = $text;
            $transport          = (string) $phpmailer->Mailer;

            if ('' !== (string) $phpmailer->Host) {
                $transport .= ':' . (string) $phpmailer->Host;
            }
        };

        add_action('phpmailer_init', $capture, 99);
        $sent = (bool) parent::send($to, $subject, $message, $headers, $attachments);
        remove_action('phpmailer_init', $capture, 99);

        if ('' !== $transport && $this->recordId > 0) {
            Repository::setTransport($this->recordId, $transport);
        }

        return $sent;
    }
}
