<?php

namespace RTMCustomMails;

use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use RTMCustomMails\Email\RTMCustomEmail;
use RTMCustomMails\WooCommerce\WooCommerceSchemaConverter;
use WC_Email;
use WC_Emails;

/**
 *
 */
final class Util
{

    /**
     * @param ReflectionMethod[] $getters
     * @param string $methodPrefix
     * @param object $object
     * @return mixed
     * @throws ReflectionException
     */
    public static function invokeClassMethods(array $getters, string $methodPrefix, object $object): mixed
    {
        return array_reduce($getters, function ($carry, ReflectionMethod $m) use ($object, $methodPrefix) {
            try {
                $carry[substr($m->getName(), strlen($methodPrefix))] = $m->invoke($object);
            } catch (\Throwable|\Exception|\Error|\RuntimeException $_) {
                // ignore any failures (throwables, errors, etc)
            }
            return $carry;
        }, []);
    }

    /**
     * @template T of object
     * @param T|class-string<T> $object
     * @param string $method_prefix
     * @param array $exclude_methods
     * @return ReflectionMethod[]
     * @throws ReflectionException
     */
    public static function getClassMethods(object|string $object, string $method_prefix, array $exclude_methods): array
    {
        $exclude_methods = array_map(fn($e) => $method_prefix . $e, $exclude_methods);
        return array_filter(
            (new ReflectionClass($object))->getMethods(ReflectionMethod::IS_PUBLIC),
            fn(ReflectionMethod $m) => str_starts_with($m->getName(), $method_prefix)
                && $m->getNumberOfRequiredParameters() === 0
                && !in_array($m->getName(), $exclude_methods)
        );
    }

    /**
     * Get the email instance matching $emailId. If the email id is not found, returns false.
     */
    public static function getEmailById($emailId): RTMCustomEmail|false
    {
        $wcEmail = $emailId instanceof WC_Email
            ? $emailId
            : current(array_filter(WC_Emails::instance()->get_emails(), fn($e) => $e->id === $emailId));
        if (!$wcEmail) {
            return false;
        }
        return RTMCustomEmail::asCustomEmail($wcEmail);
    }

    public static function getEmailSettingsSchema(RTMCustomEmail $email): array
    {
        return WooCommerceSchemaConverter::getJsonSchema($email);
    }

}