<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Mailer;

use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\User\Model\User;
use Symfony\Component\Mime\Email;

final class EmailLogMetadata
{
    public const string HEADER = 'X-Serenity-Email-Log';
    public const string DIRECT_TRANSPORT_HEADER = 'X-Serenity-Email-Log-Direct';

    public static function attach(
        Email $email,
        string $type,
        ?User $user = null,
        ?Cart $cart = null,
    ): Email {
        $payload = [
            'type' => $type,
            'userId' => $user?->getId()->toString(),
            'cartId' => $cart?->getId()->toString(),
        ];

        $email->getHeaders()->remove(self::HEADER);
        $email->getHeaders()->addTextHeader(
            self::HEADER,
            base64_encode((string) json_encode($payload, \JSON_THROW_ON_ERROR))
        );

        return $email;
    }

    public static function attachForDirectTransport(
        Email $email,
        string $type,
        ?User $user = null,
        ?Cart $cart = null,
    ): Email {
        self::attach($email, $type, $user, $cart);

        $email->getHeaders()->remove(self::DIRECT_TRANSPORT_HEADER);
        $email->getHeaders()->addTextHeader(self::DIRECT_TRANSPORT_HEADER, '1');

        return $email;
    }

    /**
     * @return array{type: string, userId?: string|null, cartId?: string|null}|null
     */
    public static function read(Email $email, bool $remove = false): ?array
    {
        $headers = $email->getHeaders();
        if (!$headers->has(self::HEADER)) {
            return null;
        }

        $header = $headers->get(self::HEADER);
        $encoded = trim($header->getBodyAsString());

        if ($remove) {
            $headers->remove(self::HEADER);
        }

        $json = base64_decode($encoded, true);
        if (false === $json) {
            return null;
        }

        try {
            $payload = json_decode($json, true, 512, \JSON_THROW_ON_ERROR);
        } catch (\JsonException) {
            return null;
        }

        if (!\is_array($payload) || !isset($payload['type']) || !\is_string($payload['type']) || '' === $payload['type']) {
            return null;
        }

        return [
            'type' => $payload['type'],
            'userId' => self::stringOrNull($payload['userId'] ?? null),
            'cartId' => self::stringOrNull($payload['cartId'] ?? null),
        ];
    }

    public static function consumeDirectTransportMarker(Email $email): bool
    {
        $headers = $email->getHeaders();
        if (!$headers->has(self::DIRECT_TRANSPORT_HEADER)) {
            return false;
        }

        $headers->remove(self::DIRECT_TRANSPORT_HEADER);

        return true;
    }

    private static function stringOrNull(mixed $value): ?string
    {
        return \is_string($value) && '' !== $value ? $value : null;
    }
}
