<?php

namespace RTMCustomMails;

use RTMCustomMails\Email\RTMCustomEmail;
use RTMCustomMails\Email\RTMCustomEmail_Cancelled_Order;
use RTMCustomMails\Email\RTMCustomEmail_Customer_Completed_Order;
use RTMCustomMails\Email\RTMCustomEmail_Customer_Invoice;
use RTMCustomMails\Email\RTMCustomEmail_Customer_New_Account;
use RTMCustomMails\Email\RTMCustomEmail_Customer_Note;
use RTMCustomMails\Email\RTMCustomEmail_Customer_On_Hold_Order;
use RTMCustomMails\Email\RTMCustomEmail_Customer_Processing_Order;
use RTMCustomMails\Email\RTMCustomEmail_Customer_Refunded_Order;
use RTMCustomMails\Email\RTMCustomEmail_Customer_Reset_Password;
use RTMCustomMails\Email\RTMCustomEmail_Failed_Order;
use RTMCustomMails\Email\RTMCustomEmail_New_Order;
use RTMCustomMails\EmailSections\ActionSectionRender;
use RTMCustomMails\EmailSections\Defaults\DefaultLoader;
use RTMCustomMails\EmailSections\EmailSections;
use RTMCustomMails\EmailSections\TwigFunctions;
use RTMCustomMails\MetaBox\OrderEmailLogMetaBox;
use RTMCustomMails\Pages\EmailOverviewPage;
use RTMCustomMails\Pages\ScheduledEmailsPage;
use RTMCustomMails\PDFInvoices\WoocommercePDFInvoices;
use RTMCustomMails\Preview\DisallowPreviews;
use RTMCustomMails\Preview\EmailObjects;
use RTMCustomMails\Preview\PreviewEmails;
use RTMCustomMails\Preview\PreviewTriggerArguments;
use RTMCustomMails\Renderer\TimberEmailRenderer;
use RTMCustomMails\Rest\EmailApi;
use RTMCustomMails\Schedule\ScheduledEmails;
use RTMCustomMails\WooCommerce\OrderQuery;
use RTMCustomMails\WooCommerce\WoocommerceEmailActions;
use RTMCustomMails\WooCommerce\WooCommerceEmails;
use RTMCustomMails\WooCommerce\WoocommerceEmailSettingsTable;
use RTMCustomMails\WooCommerce\WooCommerceSchemaConverter;
use RTMCustomMails\WooCommerce\WooCommerceTemplate;
use Timber\Timber;
use WC_Email;
use WC_Emails;
use WordpressModels\Assets;
use WordpressModels\Traits\SingletonTrait;

/**
 *
 */
class Core
{

    private Assets $assets;

    use SingletonTrait;

    private function __construct()
    {
        add_action('admin_init', [$this, 'registerAdminModules']);
        add_action('init', [$this, 'registerInitModules']);

        // Rest APIs (register rest_api_init in constructor)
        EmailApi::instance();

        // NON-INIT
        WoocommercePDFInvoices::instance();
        OrderQuery::instance();
        WooCommerceEmails::instance();
        WooCommerceTemplate::instance();
        EmailTriggerHooks::instance();
        EmailObjects::instance();

        WooCommerceSchemaConverter::instance();

        // alias default woocommerce email classes.
        // this needs to be done during plugin load, before woocommerce registers their classes.
        $this->aliasWoocommerceEmailClasses();

        $this->assets()->addTimberTemplateLocation(WRCE_ROOT_PATH . 'view/');

        add_filter('wrce_email_enabled_conditional', [$this, 'checkEmailConditionallyEnabled'], 10, 2);

        add_action('woocommerce_email', [$this, 'registerFormFieldOptionHooks'], 10, 1);
    }

    /**
     * Triggered by plugin activation hook
     * @return void
     */
    public function activatePlugin()
    {
        DefaultLoader::instance();

        $emails = WC_Emails::instance()->get_emails();
        foreach ($emails as $email) {
            $customEmail = RTMCustomEmail::asCustomEmail($email);
            //if the email already has sections there is no need to import the default template
            if (!$customEmail->getSections()) {
                do_action('wrce_load_default_template', $customEmail);
            }
        }
    }

    public function registerInitModules(): void
    {
        // dynamic email sections
        //TwigContextInjection::instance();
        TwigFunctions::instance();
        TimberEmailRenderer::instance();
        ActionSectionRender::instance();
        EmailSections::instance();

        // scheduling emails
        ScheduledEmails::instance();

        // woocommerce
        WoocommerceEmailActions::instance();

        new Timber();

        if (is_admin()) {
            EmailOverviewPage::instance();
        }
    }

    public function registerAdminModules()
    {
        // admin only modules
        DisallowPreviews::instance();

        WoocommerceEmailSettingsTable::instance();

        PreviewEmails::instance();
        PreviewTriggerArguments::instance();

        OrderEmailLogMetaBox::instance();
    }

    /**
     * Get the plugin assets instance.
     * @return Assets
     */
    public function assets(): Assets
    {
        return $this->assets ?? new Assets(WRCE_ASSETS_PATH . '/build', WRCE_ASSETS_URL . '/build');
    }

    /**
     * Alias default WooCommerce email classes, such that they are not registered.
     * @return void
     */
    private function aliasWoocommerceEmailClasses(): void
    {
        // load WC_Email and WC_Settings_Api classes if not loaded
        if (!class_exists('WC_Email')) {
            $woocommerceIncludes = realpath(WP_CONTENT_DIR . '/plugins/woocommerce/includes');
            $settingsApiFile = 'abstracts/abstract-wc-settings-api.php';
            $emailsFile = 'emails/class-wc-email.php';

            if (!is_file("$woocommerceIncludes/$settingsApiFile") || !is_file("$woocommerceIncludes/$emailsFile")) {
                // skip email loading if woocommerce files are not found
                return;
            }
            require_once "$woocommerceIncludes/$settingsApiFile";
            require_once "$woocommerceIncludes/$emailsFile";
        }

        // alias woocommerce default emails, such that their `require` calls will immediately return
        class_alias(RTMCustomEmail_Cancelled_Order::class, 'WC_Email_Cancelled_Order');
        class_alias(RTMCustomEmail_Customer_Completed_Order::class, 'WC_Email_Customer_Completed_Order');
        class_alias(RTMCustomEmail_Customer_Invoice::class, 'WC_Email_Customer_Invoice');
        class_alias(RTMCustomEmail_Customer_New_Account::class, 'WC_Email_Customer_New_Account');
        class_alias(RTMCustomEmail_Customer_Note::class, 'WC_Email_Customer_Note');
        class_alias(RTMCustomEmail_Customer_On_Hold_Order::class, 'WC_Email_Customer_On_Hold_Order');
        class_alias(RTMCustomEmail_Customer_Processing_Order::class, 'WC_Email_Customer_Processing_Order');
        class_alias(RTMCustomEmail_Customer_Refunded_Order::class, 'WC_Email_Customer_Refunded_Order');
        class_alias(RTMCustomEmail_Customer_Reset_Password::class, 'WC_Email_Customer_Reset_Password');
        class_alias(RTMCustomEmail_Failed_Order::class, 'WC_Email_Failed_Order');
        class_alias(RTMCustomEmail_New_Order::class, 'WC_Email_New_Order');
    }


    public function checkEmailConditionallyEnabled(bool $value, WC_Email $email): bool
    {
        global $wp_filter;
        $filters = $wp_filter['woocommerce_email_enabled_' . $email->id] ?? [];
        // callbacks not empty
        return $value || !empty($filters->callbacks);
    }

    public function registerFormFieldOptionHooks(WC_Emails $emails)
    {
        $emailInstances = $emails->get_emails();
        // users should register to the desired email instances
        do_action('wrce_register_options', $emailInstances);

        // filters registered in option class constructors should register their form fields here
        foreach ($emailInstances as $email) {
            $email->form_fields = apply_filters('wrce_form_fields_' . $email->id, $email->form_fields);
        }
    }
}