<?php

use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
use EventEspresso\core\domain\services\registration\form\utilities\CountryOptions;
use EventEspresso\core\domain\services\registration\form\utilities\StateOptions;
use EventEspresso\core\exceptions\InvalidDataTypeException;
use EventEspresso\core\exceptions\InvalidInterfaceException;
use EventEspresso\core\services\loaders\LoaderFactory;
use EventEspresso\core\services\notifications\PersistentAdminNoticeManager;

/**
 * EED_Add_New_State class
 *
 * @package        Event Espresso
 * @subpackage     /modules/add_new_state/
 * @author         Brent Christensen
 */
class EED_Add_New_State extends EED_Module
{
    /**
     * @return EED_Add_New_State|EED_Module
     * @throws EE_Error
     * @throws ReflectionException
     */
    public static function instance()
    {
        return parent::get_instance(__CLASS__);
    }


    /**
     * set_hooks - for hooking into EE Core, other modules, etc
     *
     * @return void
     */
    public static function set_hooks()
    {
        add_action('wp_loaded', ['EED_Add_New_State', 'set_definitions'], 2);
        add_action('wp_enqueue_scripts', ['EED_Add_New_State', 'translate_js_strings'], 0);
        add_action('wp_enqueue_scripts', ['EED_Add_New_State', 'wp_enqueue_scripts']);
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
            ['EED_Add_New_State', 'display_add_new_state_micro_form'],
            1
        );
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
            ['EED_Add_New_State', 'display_add_new_state_micro_form'],
            1
        );
        add_filter(
            'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
            ['EED_Add_New_State', 'unset_new_state_request_params']
        );
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
            ['EED_Add_New_State', 'inject_new_reg_state_into_options'],
            10,
            5
        );
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
            ['EED_Add_New_State', 'inject_new_reg_country_into_options'],
            10,
            5
        );
        add_filter(
            'FHEE__EE_State_Select_Input____construct__state_options',
            ['EED_Add_New_State', 'state_options']
        );
        add_filter(
            'FHEE__EE_Country_Select_Input____construct__country_options',
            ['EED_Add_New_State', 'country_options']
        );
    }


    /**
     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
     *
     * @return void
     */
    public static function set_hooks_admin()
    {
        add_action('wp_loaded', ['EED_Add_New_State', 'set_definitions'], 2);
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___question_group_reg_form__question_group_reg_form',
            ['EED_Add_New_State', 'display_add_new_state_micro_form'],
            1
        );
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
            ['EED_Add_New_State', 'display_add_new_state_micro_form'],
            1
        );
        add_action('wp_ajax_espresso_add_new_state', ['EED_Add_New_State', 'add_new_state']);
        add_action('wp_ajax_nopriv_espresso_add_new_state', ['EED_Add_New_State', 'add_new_state']);
        add_filter(
            'FHEE__EE_Single_Page_Checkout__process_attendee_information__valid_data_line_item',
            ['EED_Add_New_State', 'unset_new_state_request_params']
        );
        add_action(
            'AHEE__General_Settings_Admin_Page__update_country_settings__state_saved',
            ['EED_Add_New_State', 'update_country_settings'],
            10,
            3
        );
        add_action(
            'AHEE__General_Settings_Admin_Page__delete_state__state_deleted',
            ['EED_Add_New_State', 'update_country_settings'],
            10,
            3
        );
        add_filter(
            'FHEE__EE_State_Select_Input____construct__state_options',
            ['EED_Add_New_State', 'state_options']
        );
        add_filter(
            'FHEE__EE_Country_Select_Input____construct__country_options',
            ['EED_Add_New_State', 'country_options']
        );
        add_filter(
            'FHEE__EE_Form_Section_Proper__receive_form_submission__request_data',
            ['EED_Add_New_State', 'filter_checkout_request_params']
        );
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__state_options',
            ['EED_Add_New_State', 'inject_new_reg_state_into_options'],
            10,
            5
        );
        add_filter(
            'FHEE__EE_SPCO_Reg_Step_Attendee_Information___generate_question_input__country_options',
            ['EED_Add_New_State', 'inject_new_reg_country_into_options'],
            10,
            5
        );
    }


    /**
     * @return void
     */
    public static function set_definitions()
    {
        define('ANS_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
        define(
            'ANS_TEMPLATES_PATH',
            str_replace(
                '\\',
                '/',
                plugin_dir_path(__FILE__)
            ) . 'templates/'
        );
    }


    /**
     * @param WP $WP
     * @return void
     */
    public function run($WP)
    {
    }


    /**
     * @return void
     */
    public static function translate_js_strings()
    {
        EE_Registry::$i18n_js_strings['ans_no_country']        = esc_html__(
            'In order to proceed, you need to select the Country that your State/Province belongs to.',
            'event_espresso'
        );
        EE_Registry::$i18n_js_strings['ans_no_name']           = esc_html__(
            'In order to proceed, you need to enter the name of your State/Province.',
            'event_espresso'
        );
        EE_Registry::$i18n_js_strings['ans_no_abbreviation']   = esc_html__(
            'In order to proceed, you need to enter an abbreviation for the name of your State/Province.',
            'event_espresso'
        );
        EE_Registry::$i18n_js_strings['ans_save_success']      = esc_html__(
            'The new state was successfully saved to the database.',
            'event_espresso'
        );
        EE_Registry::$i18n_js_strings['ans_server_save_error'] = esc_html__(
            'An unknown error has occurred on the server while saving the new state to the database.',
            'event_espresso'
        );
    }


    /**
     * @return void
     */
    public static function wp_enqueue_scripts()
    {
        if (apply_filters('EED_Single_Page_Checkout__SPCO_active', false)) {
            wp_register_script(
                'add_new_state',
                ANS_ASSETS_URL . 'add_new_state.js',
                ['espresso_core', 'single_page_checkout'],
                EVENT_ESPRESSO_VERSION,
                true
            );
            wp_enqueue_script('add_new_state');
        }
    }


    /**
     * display_add_new_state_micro_form
     *
     * @param EE_Form_Section_Proper $question_group_reg_form
     * @return EE_Form_Section_Proper
     * @throws EE_Error
     * @throws ReflectionException
     */
    public static function display_add_new_state_micro_form(
        EE_Form_Section_Proper $question_group_reg_form
    ): EE_Form_Section_Proper {
        $request = self::getRequest();
        // only add the 'new_state_micro_form' when displaying reg forms,
        // not during processing since we process the 'new_state_micro_form' in its own AJAX request
        $action = $request->getRequestParam('action');
        // is the "state" question in this form section?
        $input = $question_group_reg_form->get_subsection('state');
        if ($action === 'process_reg_step' || $action === 'update_reg_step') {
            // ok then all we need to do is make sure the input's HTML name is consistent
            // by forcing it to set it now, like it did while getting the form for display
            if ($input instanceof EE_State_Select_Input) {
                $input->html_name();
            }
            return $question_group_reg_form;
        }
        // we're only doing this for state select inputs
        if (
            $input instanceof EE_State_Select_Input
            && ! $input->get_display_strategy() instanceof EE_Hidden_Display_Strategy
        ) {
            // grab any set values from the request
            $country_name        = str_replace('state', 'nsmf_new_state_country', $input->html_name());
            $state_name          = str_replace('state', 'nsmf_new_state_name', $input->html_name());
            $abbrv_name          = str_replace('state', 'nsmf_new_state_abbrv', $input->html_name());
            $new_state_submit_id = str_replace('state', 'new_state', $input->html_id());
            $country_options     = [];
            $countries           = EEM_Country::instance()->get_all_countries();
            if (! empty($countries)) {
                foreach ($countries as $country) {
                    if ($country instanceof EE_Country) {
                        $country_options[ $country->ID() ] = $country->name();
                    }
                }
            }
            $new_state_micro_form = new EE_Form_Section_Proper(
                [
                    'name'            => 'new_state_micro_form',
                    'html_id'         => 'new_state_micro_form',
                    'layout_strategy' => new EE_Div_Per_Section_Layout(),
                    'subsections'     => [
                        // add hidden input to indicate that a new state is being added
                        'add_new_state'               => new EE_Hidden_Input(
                            [
                                'html_name' => str_replace(
                                    'state',
                                    'nsmf_add_new_state',
                                    $input->html_name()
                                ),
                                'html_id'   => str_replace(
                                    'state',
                                    'nsmf_add_new_state',
                                    $input->html_id()
                                ),
                                'default'   => 0,
                            ]
                        ),
                        // add link for displaying hidden container
                        'click_here_link'             => new EE_Form_Section_HTML(
                            apply_filters(
                                'FHEE__EED_Add_New_State__display_add_new_state_micro_form__click_here_link',
                                EEH_HTML::link(
                                    '',
                                    esc_html__('click here to add a new state/province', 'event_espresso'),
                                    '',
                                    'display-' . $input->html_id(),
                                    'ee-form-add-new-state-lnk display-the-hidden smaller-text hide-if-no-js',
                                    '',
                                    'data-target="' . $input->html_id() . '"'
                                )
                            )
                        ),
                        // add initial html for hidden container
                        'add_new_state_micro_form'    => new EE_Form_Section_HTML(
                            apply_filters(
                                'FHEE__EED_Add_New_State__display_add_new_state_micro_form__add_new_state_micro_form',
                                EEH_HTML::div(
                                    '',
                                    $input->html_id() . '-dv',
                                    'ee-form-add-new-state-dv',
                                    'display: none;'
                                ) .
                                EEH_HTML::h6(
                                    esc_html__(
                                        'Is your state/province missing from the dropdown menu above? You can add it by completing the following steps:',
                                        'event_espresso'
                                    )
                                ) .
                                EEH_HTML::ul() .
                                EEH_HTML::li(
                                    esc_html__(
                                        'first select the Country that your State/Province belongs to',
                                        'event_espresso'
                                    )
                                ) .
                                EEH_HTML::li(
                                    esc_html__('enter the name of your State/Province', 'event_espresso')
                                ) .
                                EEH_HTML::li(
                                    esc_html__(
                                        'enter a two to six letter abbreviation for the name of your State/Province',
                                        'event_espresso'
                                    )
                                ) .
                                EEH_HTML::li(esc_html__('click the ADD button', 'event_espresso')) .
                                EEH_HTML::ulx()
                            )
                        ),
                        // NEW STATE COUNTRY
                        'new_state_country'           => new EE_Country_Select_Input(
                            $country_options,
                            [
                                'html_name'       => $country_name,
                                'html_id'         => str_replace(
                                    'state',
                                    'nsmf_new_state_country',
                                    $input->html_id()
                                ),
                                'html_class'      => $input->html_class() . ' new-state-country',
                                'html_label_text' => esc_html__('New State/Province Country', 'event_espresso'),
                                'default'         => $request->getRequestParam($country_name),
                                'required'        => false,
                            ]
                        ),
                        // NEW STATE NAME
                        'new_state_name'              => new EE_Text_Input(
                            [
                                'html_name'       => $state_name,
                                'html_id'         => str_replace(
                                    'state',
                                    'nsmf_new_state_name',
                                    $input->html_id()
                                ),
                                'html_class'      => $input->html_class() . ' new-state-state',
                                'html_label_text' => esc_html__(
                                    'New State/Province Name',
                                    'event_espresso'
                                ),
                                'default'         => $request->getRequestParam($state_name),
                                'required'        => false,
                            ]
                        ),
                        // NEW STATE NAME
                        'new_state_abbrv'             => new EE_Text_Input(
                            [
                                'html_name'             => $abbrv_name,
                                'html_id'               => str_replace(
                                    'state',
                                    'nsmf_new_state_abbrv',
                                    $input->html_id()
                                ),
                                'html_class'            => $input->html_class() . ' new-state-abbrv',
                                'html_label_text'       => esc_html__(
                                    'New State/Province Abbreviation',
                                    'event_espresso'
                                ) . ' *',
                                'other_html_attributes' => 'size="24"',
                                'default'               => $request->getRequestParam($abbrv_name),
                                'required'              => false,
                            ]
                        ),
                        // "submit" button
                        'add_new_state_submit_button' => new EE_Form_Section_HTML(
                            apply_filters(
                                'FHEE__EED_Add_New_State__display_add_new_state_micro_form__add_new_state_submit_button',
                                EEH_HTML::div(
                                    EEH_HTML::button(
                                        esc_html__('ADD', 'event_espresso'),
                                        'ee-form-add-new-state-submit button button--secondary',
                                        '',
                                        'submit-' . $new_state_submit_id,
                                        '',
                                        'data-target="' . $new_state_submit_id . '"'
                                        . ' data-value-field-name="' . $input->valueFieldName() . '"'
                                    ),
                                    '',
                                    'ee-form-add-new-state-submit-dv'
                                )
                            )
                        ),
                        // extra info
                        'add_new_state_extra'         => new EE_Form_Section_HTML(
                            apply_filters(
                                'FHEE__EED_Add_New_State__display_add_new_state_micro_form__add_new_state_extra',
                                EEH_HTML::br()
                                .
                                EEH_HTML::div('', '', 'small-text')
                                .
                                EEH_HTML::strong(
                                    '* ' .
                                    esc_html__(
                                        'Don\'t know your State/Province Abbreviation?',
                                        'event_espresso'
                                    )
                                )
                                .
                                EEH_HTML::br()
                                .
                                sprintf(
                                    esc_html__(
                                        'You can look here: %s, for a list of Countries and links to their State/Province Abbreviations ("Subdivisions assigned codes" column).',
                                        'event_espresso'
                                    ),
                                    EEH_HTML::link(
                                        'https://en.wikipedia.org/wiki/ISO_3166-2',
                                        'https://en.wikipedia.org/wiki/ISO_3166-2',
                                        '',
                                        '',
                                        'ee-form-add-new-state-wiki-lnk',
                                        '',
                                        'target="_blank"'
                                    )
                                )
                                .
                                EEH_HTML::divx()
                                .
                                EEH_HTML::br()
                                .
                                EEH_HTML::link(
                                    '',
                                    esc_html__('cancel new State/Province', 'event_espresso'),
                                    '',
                                    'hide-' . $input->html_id(),
                                    'ee-form-cancel-new-state-lnk smaller-text',
                                    '',
                                    'data-target="' . $input->html_id() . '"'
                                )
                                .
                                EEH_HTML::divx()
                                .
                                EEH_HTML::br()
                            )
                        ),
                    ],
                ]
            );
            $question_group_reg_form->add_subsections(
                ['new_state_micro_form' => $new_state_micro_form],
                'state',
                false
            );
        }
        return $question_group_reg_form;
    }


    /**
     * set_new_state_input_width
     *
     * @return int|string
     * @throws EE_Error
     * @throws InvalidArgumentException
     * @throws InvalidDataTypeException
     * @throws InvalidInterfaceException
     * @throws ReflectionException
     */
    public static function add_new_state()
    {
        $request = self::getRequest();
        if ($request->getRequestParam('nsmf_add_new_state', 0, 'int') === 1) {
            EE_Registry::instance()->load_model('State');
            // grab country ISO code, new state name, and new state abbreviation
            $state_country = $request->getRequestParam('nsmf_new_state_country');
            $state_name    = $request->getRequestParam('nsmf_new_state_name');
            $state_abbr    = $request->getRequestParam('nsmf_new_state_abbrv');
            if ($state_country && $state_name && $state_abbr) {
                $new_state = EED_Add_New_State::save_new_state_to_db(
                    [
                        'CNT_ISO'    => strtoupper($state_country),
                        'STA_abbrev' => strtoupper($state_abbr),
                        'STA_name'   => ucwords($state_name),
                        'STA_active' => false,
                    ]
                );
                if ($new_state instanceof EE_State) {
                    // clean house
                    $request->unSetRequestParams(
                        [
                            'nsmf_add_new_state',
                            'nsmf_new_state_country',
                            'nsmf_new_state_name',
                            'nsmf_new_state_abbrv',
                        ]
                    );
                    // get any existing new states
                    $new_states                     = EE_Registry::instance()->SSN->get_session_data('nsmf_new_states');
                    $new_states[ $new_state->ID() ] = $new_state;
                    EE_Registry::instance()->SSN->set_session_data(
                        ['nsmf_new_states' => $new_states]
                    );
                    if ($request->isAjax()) {
                        echo wp_json_encode(
                            [
                                'success'      => true,
                                'id'           => $new_state->ID(),
                                'name'         => $new_state->name(),
                                'abbrev'       => $new_state->abbrev(),
                                'country_iso'  => $new_state->country_iso(),
                                'country_name' => $new_state->country()->name(),
                            ]
                        );
                        exit();
                    }
                    return $new_state->ID();
                }
            } else {
                $error = esc_html__(
                    'A new State/Province could not be added because invalid or missing data was received.',
                    'event_espresso'
                );
                if ($request->isAjax()) {
                    echo wp_json_encode(['error' => $error]);
                    exit();
                }
                EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
            }
        }
        return false;
    }


    /**
     * recursively drills down through request params to remove any that were added by this module
     *
     * @param array $request_params
     * @return array
     */
    public static function filter_checkout_request_params(array $request_params): array
    {
        foreach ($request_params as $form_section) {
            if (is_array($form_section)) {
                EED_Add_New_State::unset_new_state_request_params($form_section);
                EED_Add_New_State::filter_checkout_request_params($form_section);
            }
        }
        return $request_params;
    }


    /**
     * @param array $request_params
     * @return array
     */
    public static function unset_new_state_request_params(array $request_params): array
    {
        unset(
            $request_params['new_state_micro_form'],
            $request_params['new_state_micro_add_new_state'],
            $request_params['new_state_micro_new_state_country'],
            $request_params['new_state_micro_new_state_name'],
            $request_params['new_state_micro_new_state_abbrv']
        );
        return $request_params;
    }


    /**
     * @param array $props_n_values
     * @return EE_State|null
     * @throws EE_Error
     * @throws ReflectionException
     */
    public static function save_new_state_to_db(array $props_n_values = []): ?EE_State
    {
        /** @var EE_State[] $existing_state */
        $existing_state = EEM_State::instance()->get_all([$props_n_values, 'limit' => 1]);
        if (! empty($existing_state)) {
            return array_pop($existing_state);
        }
        $new_state = EE_State::new_instance($props_n_values);
        if ($new_state instanceof EE_State) {
            $country_settings_url = add_query_arg(
                [
                    'page'    => 'espresso_general_settings',
                    'action'  => 'country_settings',
                    'country' => $new_state->country_iso(),
                ],
                admin_url('admin.php')
            );
            // if not non-ajax admin
            new PersistentAdminNotice(
                'new-state-added-' . $new_state->country_iso() . '-' . $new_state->abbrev(),
                sprintf(
                    esc_html__(
                        'A new State named "%1$s (%2$s)" was dynamically added from an Event Espresso form for the Country of "%3$s".%5$sTo verify, edit, and/or delete this new State, please go to the %4$s and update the States / Provinces section.%5$sCheck "Yes" to have this new State added to dropdown select lists in forms.',
                        'event_espresso'
                    ),
                    '<b>' . $new_state->name() . '</b>',
                    '<b>' . $new_state->abbrev() . '</b>',
                    '<b>' . $new_state->country()->name() . '</b>',
                    '<a href="'
                    . $country_settings_url
                    . '">'
                    . esc_html__(
                        'Event Espresso - General Settings > Countries Tab',
                        'event_espresso'
                    )
                    . '</a>',
                    '<br />'
                )
            );
            $new_state->save();
            EEM_State::instance()->reset_cached_states();
            return $new_state;
        }
        return null;
    }


    /**
     * @param string $CNT_ISO
     * @param int    $STA_ID
     * @param array  $cols_n_values
     * @return void
     * @throws DomainException
     * @throws EE_Error
     * @throws InvalidArgumentException
     * @throws InvalidDataTypeException
     * @throws InvalidInterfaceException
     * @throws ReflectionException
     */
    public static function update_country_settings(string $CNT_ISO = '', int $STA_ID = 0, array $cols_n_values = [])
    {
        /** @var EE_Capabilities $capabilities */
        $capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class);
        if (! $capabilities->current_user_can('manage_options', 'update-country-settings')) {
            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
        }
        if (! $CNT_ISO) {
            EE_Error::add_error(
                esc_html__('An invalid or missing Country ISO Code was received.', 'event_espresso'),
                __FILE__,
                __FUNCTION__,
                __LINE__
            );
        }
        $STA_abbrev = is_array($cols_n_values) && isset($cols_n_values['STA_abbrev']) ? $cols_n_values['STA_abbrev']
            : false;
        if (! $STA_abbrev && ! empty($STA_ID)) {
            $state = EEM_State::instance()->get_one_by_ID($STA_ID);
            if ($state instanceof EE_State) {
                $STA_abbrev = $state->abbrev();
            }
        }
        if (! $STA_abbrev) {
            EE_Error::add_error(
                esc_html__('An invalid or missing State Abbreviation was received.', 'event_espresso'),
                __FILE__,
                __FUNCTION__,
                __LINE__
            );
        }
        /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
        $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
        );
        $persistent_admin_notice_manager->dismissNotice($CNT_ISO . '-' . $STA_abbrev, true, true);
    }


    /**
     * @param EE_State[]                                              $state_options
     * @param EE_SPCO_Reg_Step_Attendee_Information|StateOptions|null $deprecated
     * @param EE_Registration                                         $registration
     * @param EE_Question|null                                        $question
     * @param EE_Answer|null                                          $answer
     * @return array
     * @throws EE_Error
     * @throws ReflectionException
     */
    public static function inject_new_reg_state_into_options(
        array $state_options,
        $deprecated,
        EE_Registration $registration,
        ?EE_Question $question,
        ?EE_Answer $answer
    ): array {
        if (
            $answer instanceof EE_Answer && $question instanceof EE_Question
            && $question->type() === EEM_Question::QST_type_state
        ) {
            $STA_ID = $answer->value();
            if (! empty($STA_ID)) {
                $state = EEM_State::instance()->get_one_by_ID($STA_ID);
                if ($state instanceof EE_State) {
                    $country = $state->country();
                    if ($country instanceof EE_Country) {
                        if (! isset($state_options[ $country->name() ])) {
                            $state_options[ $country->name() ] = [];
                        }
                        if (! isset($state_options[ $country->name() ][ $STA_ID ])) {
                            $state_options[ $country->name() ][ $STA_ID ] = $state->name();
                        }
                    }
                }
            }
        }
        return $state_options;
    }


    /**
     * @param EE_Country[]                                              $country_options
     * @param EE_SPCO_Reg_Step_Attendee_Information|CountryOptions|null $deprecated
     * @param EE_Registration                                           $registration
     * @param EE_Question|null                                          $question
     * @param EE_Answer|null                                            $answer
     * @return array
     * @throws EE_Error
     * @throws InvalidArgumentException
     * @throws InvalidDataTypeException
     * @throws InvalidInterfaceException
     * @throws ReflectionException
     */
    public static function inject_new_reg_country_into_options(
        array $country_options,
        $deprecated,
        EE_Registration $registration,
        ?EE_Question $question,
        ?EE_Answer $answer
    ): array {
        if (
            $answer instanceof EE_Answer
            && $question instanceof EE_Question
            && $question->type() === EEM_Question::QST_type_country
        ) {
            $CNT_ISO = $answer->value();
            if (! empty($CNT_ISO)) {
                $country = EEM_Country::instance()->get_one_by_ID($CNT_ISO);
                if ($country instanceof EE_Country) {
                    if (! isset($country_options[ $CNT_ISO ])) {
                        $country_options[ $CNT_ISO ] = $country->name();
                    }
                }
            }
        }
        return $country_options;
    }


    /**
     * @param EE_State[] $state_options
     * @return array
     * @throws EE_Error
     * @throws ReflectionException
     */
    public static function state_options(array $state_options = []): array
    {
        $new_states = EED_Add_New_State::_get_new_states();
        foreach ($new_states as $new_state) {
            if (
                $new_state instanceof EE_State
                && $new_state->country() instanceof EE_Country
            ) {
                $state_options[ $new_state->country()->name() ][ $new_state->ID() ] = $new_state->name();
            }
        }
        return $state_options;
    }


    /**
     * @return array
     * @throws InvalidArgumentException
     * @throws InvalidDataTypeException
     * @throws InvalidInterfaceException
     */
    protected static function _get_new_states(): array
    {
        $new_states = [];
        if (EE_Registry::instance()->SSN instanceof EE_Session) {
            $new_states = EE_Registry::instance()->SSN->get_session_data(
                'nsmf_new_states'
            );
        }
        return is_array($new_states) ? $new_states : [];
    }


    /**
     * @param EE_Country[] $country_options
     * @return array
     * @throws EE_Error
     * @throws ReflectionException
     */
    public static function country_options(array $country_options = []): array
    {
        $new_states = EED_Add_New_State::_get_new_states();
        foreach ($new_states as $new_state) {
            if (
                $new_state instanceof EE_State
                && $new_state->country() instanceof EE_Country
            ) {
                $country_options[ $new_state->country()->ID() ] = $new_state->country()->name();
            }
        }
        return $country_options;
    }
}
