<?php

declare(strict_types=1);

use MyParcelNL\Sdk\src\Model\Carrier\CarrierInstabox;
use MyParcelNL\Sdk\src\Support\Arr;

if (! defined('ABSPATH')) {
    exit;
} // Exit if accessed directly

if (class_exists('WCMYPA_Settings')) {
    return new WCMYPA_Settings();
}

/**
 * Create & render settings page
 */
class WCMYPA_Settings
{
    public const SETTINGS_MENU_SLUG = 'wcmp_settings';

    public const SETTINGS_GENERAL         = "general";
    public const SETTINGS_CHECKOUT        = "checkout";
    public const SETTINGS_EXPORT_DEFAULTS = "export_defaults";

    /**
     * General
     */
    public const SETTING_API_KEY                   = 'api_key';
    public const SETTING_TRIGGER_MANUAL_UPDATE     = 'trigger_manual_update';
    public const SETTING_AUTOMATIC_ORDER_STATUS    = 'automatic_order_status';
    public const SETTING_BARCODE_IN_NOTE           = 'barcode_in_note';
    public const SETTING_BARCODE_IN_NOTE_TITLE     = 'barcode_in_note_title';
    public const SETTING_DOWNLOAD_DISPLAY          = 'download_display';
    public const SETTING_EXPORT_MODE               = 'export_mode';
    public const SETTING_ERROR_LOGGING             = 'error_logging';
    public const SETTING_LABEL_FORMAT              = 'label_format';
    public const SETTING_ORDER_STATUS_AUTOMATION   = 'order_status_automation';
    public const SETTING_CHANGE_ORDER_STATUS_AFTER = 'change_order_status_after';
    public const SETTING_ASK_FOR_PRINT_POSITION    = 'ask_for_print_position';
    public const SETTING_PROCESS_DIRECTLY          = 'process_directly';
    public const SETTING_TRACK_TRACE_EMAIL         = 'track_trace_email';
    public const SETTING_TRACK_TRACE_MY_ACCOUNT    = 'track_trace_my_account';

    /**
     * Export defaults
     */
    public const SETTING_SHIPPING_METHODS_PACKAGE_TYPES = 'shipping_methods_package_types';
    public const SETTING_CONNECT_EMAIL                  = 'connect_email';
    public const SETTING_CONNECT_PHONE                  = 'connect_phone';
    public const SETTING_LABEL_DESCRIPTION              = 'label_description';
    public const SETTING_EMPTY_PARCEL_WEIGHT            = 'empty_parcel_weight';
    public const SETTING_EMPTY_DIGITAL_STAMP_WEIGHT     = 'empty_digital_stamp_weight';
    public const SETTING_HS_CODE                        = 'hs_code';
    public const SETTING_PACKAGE_CONTENT                = 'package_contents';
    public const SETTING_COUNTRY_OF_ORIGIN              = 'country_of_origin';
    public const SETTING_AUTOMATIC_EXPORT               = 'export_automatic';
    public const SETTING_AUTOMATIC_EXPORT_STATUS        = 'export_automatic_status';
    public const SETTING_RETURN_IN_THE_BOX              = 'return_in_the_box';
    public const SETTING_SAVE_CUSTOMER_ADDRESS          = 'save_customer_address';

    /**
     * Checkout
     */
    public const SETTING_DELIVERY_OPTIONS_CUSTOM_CSS           = 'delivery_options_custom_css';
    public const SETTING_DELIVERY_OPTIONS_DISPLAY              = 'delivery_options_display';
    public const SETTING_DELIVERY_OPTIONS_ENABLED              = 'delivery_options_enabled';
    public const SETTING_DELIVERY_OPTIONS_POSITION             = 'delivery_options_position';
    public const SETTING_DELIVERY_OPTIONS_PRICE_FORMAT         = 'delivery_options_price_format';
    public const SETTINGS_SHOW_DELIVERY_OPTIONS_FOR_BACKORDERS = 'delivery_options_enabled_for_backorders';
    public const SETTING_SHOW_DELIVERY_DAY                     = 'show_delivery_day';
    public const SETTING_DELIVERY_TITLE                        = 'delivery_title';
    public const SETTING_HEADER_DELIVERY_OPTIONS_TITLE         = 'header_delivery_options_title';
    public const SETTING_PICKUP_TITLE                          = 'pickup_title';
    public const SETTING_PICKUP_LOCATIONS_DEFAULT_VIEW         = 'pickup_locations_default_view';
    public const SETTING_ADDRESS_NOT_FOUND_TITLE               = 'address_not_found_title';
    public const SETTING_MORNING_DELIVERY_TITLE                = 'morning_title';
    public const SETTING_EVENING_DELIVERY_TITLE                = 'evening_title';
    public const SETTING_SAME_DAY_DELIVERY_TITLE               = 'same_day_title';
    public const SETTING_ONLY_RECIPIENT_TITLE                  = 'only_recipient_title';
    public const SETTING_SIGNATURE_TITLE                       = 'signature_title';
    public const SETTING_STANDARD_TITLE                        = 'standard_title';
    public const SETTING_SAME_DAY_TITLE                        = 'same_day_title';
    public const SETTING_USE_SPLIT_ADDRESS_FIELDS              = 'use_split_address_fields';

    /*
     * Carrier settings, these will be prefixed with carrier names.
     *
     * e.g. cutoff_time => postnl_cutoff_time/dpd_cutoff_time
     */
    // Defaults
    public const SETTING_CARRIER_DEFAULT_EXPORT_SIGNATURE                = 'export_signature';
    public const SETTING_CARRIER_DEFAULT_EXPORT_ONLY_RECIPIENT           = 'export_only_recipient';
    public const SETTING_CARRIER_DEFAULT_EXPORT_HIDE_SENDER              = 'export_hide_sender';
    public const SETTING_CARRIER_DEFAULT_EXPORT_LARGE_FORMAT             = 'export_large_format';
    public const SETTING_CARRIER_DEFAULT_EXPORT_LARGE_FORMAT_FROM_WEIGHT = 'export_large_format_from_weight';
    public const SETTING_CARRIER_DEFAULT_EXPORT_AGE_CHECK                = 'export_age_check';
    public const SETTING_CARRIER_DEFAULT_EXPORT_RETURN                   = 'export_return_shipments';
    public const SETTING_CARRIER_DEFAULT_EXPORT_SAME_DAY_DELIVERY        = 'export_same_day_delivery';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED                  = 'export_insured';
    public const SETTING_CARRIER_DEFAULT_EXPORT_EXTRA_ASSURANCE          = 'export_extra_assurance';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED_AMOUNT           = 'export_insured_amount';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED_EU_AMOUNT        = 'export_insured_eu_amount';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED_FROM_PRICE       = 'export_insured_from_price';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED_FOR_BE           = 'export_insured_for_be';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED_TYPE             = 'export_insured_type';
    public const SETTING_CARRIER_DEFAULT_EXPORT_INSURED_PERCENTAGE       = 'export_insured_percentage';

    // Delivery options settings
    public const SETTING_CARRIER_CUTOFF_TIME                   = 'cutoff_time';
    public const SETTING_CARRIER_DELIVERY_DAYS_WINDOW          = 'delivery_days_window';
    public const SETTING_CARRIER_DELIVERY_ENABLED              = 'delivery_enabled';
    public const SETTING_CARRIER_ALLOW_SHOW_DELIVERY_DATE      = 'allow_show_delivery_date';
    public const SETTING_CARRIER_DIGITAL_STAMP_DEFAULT_WEIGHT  = 'digital_stamp_default_weight';
    public const SETTING_CARRIER_DROP_OFF_DAYS                 = 'drop_off_days';
    public const SETTING_CARRIER_DROP_OFF_DELAY                = 'drop_off_delay';
    public const SETTING_CARRIER_EXTRA_ASSURANCE_ENABLED       = 'extra_assurance_enabled';
    public const SETTING_CARRIER_EXTRA_ASSURANCE_FEE           = 'extra_assurance_fee';
    public const SETTING_CARRIER_HIDE_SENDER_ENABLED           = 'hide_sender_enabled';
    public const SETTING_CARRIER_HIDE_SENDER_FEE               = 'hide_sender_fee';
    public const SETTING_CARRIER_PICKUP_ENABLED                = 'pickup_enabled';
    public const SETTING_CARRIER_PICKUP_FEE                    = 'pickup_fee';
    public const SETTING_CARRIER_PICKUP_TITLE                  = 'pickup_title';
    public const SETTING_CARRIER_ONLY_RECIPIENT_ENABLED        = 'only_recipient_enabled';
    public const SETTING_CARRIER_ONLY_RECIPIENT_FEE            = 'only_recipient_fee';
    public const SETTING_CARRIER_SIGNATURE_ENABLED             = 'signature_enabled';
    public const SETTING_CARRIER_SIGNATURE_FEE                 = 'signature_fee';
    public const SETTING_CARRIER_DELIVERY_MORNING_ENABLED      = 'delivery_morning_enabled';
    public const SETTING_CARRIER_DELIVERY_MORNING_FEE          = 'delivery_morning_fee';
    public const SETTING_CARRIER_DELIVERY_EVENING_ENABLED      = 'delivery_evening_enabled';
    public const SETTING_CARRIER_DELIVERY_EVENING_FEE          = 'delivery_evening_fee';
    public const SETTING_CARRIER_DELIVERY_STANDARD_FEE         = 'delivery_standard_fee';
    public const SETTING_CARRIER_SAME_DAY_DELIVERY             = 'same_day_delivery';
    public const SETTING_CARRIER_SAME_DAY_DELIVERY_CUTOFF_TIME = 'same_day_delivery_cutoff_time';
    public const SETTING_CARRIER_SAME_DAY_DELIVERY_FEE         = 'same_day_delivery_fee';

    // Saturday delivery
    // TODO; Currently not implemented
    public const SETTING_CARRIER_FRIDAY_CUTOFF_TIME        = 'friday_cutoff_time';
    public const SETTING_CARRIER_SATURDAY_DELIVERY_ENABLED = 'saturday_delivery_enabled';
    public const SETTING_CARRIER_SATURDAY_DELIVERY_FEE     = 'saturday_delivery_fee';

    // Monday delivery
    public const SETTING_CARRIER_MONDAY_DELIVERY_ENABLED = 'monday_delivery_enabled';
    public const SETTING_CARRIER_MONDAY_DELIVERY_FEE     = 'monday_delivery_fee';
    public const SETTING_CARRIER_SATURDAY_CUTOFF_TIME    = 'saturday_cutoff_time';

    public function __construct()
    {
        add_action("admin_menu", [$this, "menu"]);
        add_filter(
            "plugin_action_links_" . WCMYPA()->plugin_basename,
            [
                $this,
                "add_settings_link",
            ]
        );

        /**
         * Add the new screen to the woocommerce screen ids to make wc tooltips work.
         */
        add_filter(
            "woocommerce_screen_ids",
            function($ids) {
                $ids[] = "woocommerce_page_" . self::SETTINGS_MENU_SLUG;

                return $ids;
            }
        );

        // Create the admin settings
        require_once("class-wcmp-settings-data.php");

        // notice for MyParcel plugin
        add_action("woocommerce_myparcel_before_settings_page", [$this, "myparcel_country_notice"], 10, 1);
    }

    /**
     * Add settings item to WooCommerce menu
     */
    public function menu()
    {
        add_submenu_page(
            "woocommerce",
            __("MyParcel", "woocommerce-myparcel"),
            __("MyParcel", "woocommerce-myparcel"),
            "manage_options",
            self::SETTINGS_MENU_SLUG,
            [$this, "settings_page"]
        );
    }

    /**
     * Add settings link to plugins page
     *
     * @param array $links
     *
     * @return array
     */
    public function add_settings_link(array $links): array
    {
        $url     = WCMYPA_Settings::getSettingsUrl();
        $links[] = sprintf(
            '<a href="%s">%s</a>',
            $url,
            __('Settings', 'woocommerce-myparcel')
        );

        return $links;
    }

    /**
     * Output the settings pages.
     */
    public function settings_page()
    {
        // Enqueue modern CSS for version 2.0
        $plugin_dir = explode('/includes', plugin_dir_url(__FILE__))[0] ?? null;
        
        if ($plugin_dir) {
            wp_enqueue_style(
                'wcmp-settings-v2',
                $plugin_dir . '/assets/css/myparcel-settings-v2.css',
                [],
                '2.0.0'
            );
        }

        $settings_tabs = apply_filters(
            self::SETTINGS_MENU_SLUG . '_tabs',
            WCMP_Settings_Data::getTabs()
        );

        $active_tab = filter_input(INPUT_GET, 'tab') ?? self::SETTINGS_GENERAL;
        ?>
        <div class="wrap woocommerce wcmp-settings-v2">
            <h1>
                <?php esc_html_e('MyParcel Settings', 'woocommerce-myparcel'); ?>
                <span class="wcmp-license-badge">Licensed by Dyronics</span>
            </h1>
            <p class="wcmp-subtitle"><?php esc_html_e('Configure your MyParcel integration settings', 'woocommerce-myparcel'); ?></p>
            <h2 class="nav-tab-wrapper">
                <?php
                foreach ($settings_tabs as $tabSlug => $tabTitle) :
                    printf(
                        '<a href="?page=%4$s&tab=%1$s" class="nav-tab nav-tab-%1$s %2$s">%3$s</a>',
                        esc_html($tabSlug),
                        (($active_tab === $tabSlug) ? 'nav-tab-active' : ''),
                        esc_html($tabTitle),
                        esc_attr(self::SETTINGS_MENU_SLUG)
                    );
                endforeach;
                ?>
            </h2>
            <?php do_action("woocommerce_myparcel_before_settings_page", $active_tab); ?>
            <form
                    method="post"
                    action="options.php"
                    id="<?php echo esc_attr(self::SETTINGS_MENU_SLUG); ?>">
                <?php
                do_action("woocommerce_myparcel_before_settings", $active_tab);
                settings_fields(self::getOptionId($active_tab));
                $this->render_settings_sections(self::getOptionId($active_tab));
                do_action("woocommerce_myparcel_after_settings", $active_tab);

                submit_button();
                ?>
            </form>
            <?php do_action("woocommerce_myparcel_after_settings_page", $active_tab); ?>
        </div>
        <?php
    }

    /**
     * Show the user a notice if they might be using the wrong plugin.
     */
    public function myparcel_country_notice()
    {
        $base_country = WC()->countries->get_base_country();

        // save or check option to hide notice filter_input(INPUT_GET, 'tab') ?? self::SETTINGS_GENERAL;
        if (filter_input(INPUT_GET, 'myparcel_hide_be_notice')) {
            update_option('myparcel_hide_be_notice', true);
            $hide_notice = true;
        } else {
            $hide_notice = get_option('myparcel_hide_be_notice');
        }

        // link to hide message when one of the premium extensions is installed
        if (! $hide_notice && 'BE' === $base_country) {
            $myparcel_be_link = '<a href="https://wordpress.org/plugins/wc-myparcel-belgium/" target="_blank">WC MyParcel Belgium</a>';
            $text             = sprintf(
                    /* translators: %s is a link to the MyParcel Belgium plugin */
                __(
                    'It looks like your shop is based in Belgium. This plugin is for MyParcelNL. If you are based in Belgium, download the %s plugin instead!',
                    'woocommerce-myparcel'
                ),
                $myparcel_be_link
            );
            $dismiss_button   = sprintf(
                '<a href="%s">%s</a>',
                esc_url(add_query_arg('myparcel_hide_be_notice', 'true')),
                esc_html__('Hide this message', 'woocommerce-myparcel')
            );
            printf(
              '<div class="notice notice-warning"><p>%s %s</p></div>',
              wp_kses($text, ['a'=> ['href' => [], 'target' => []]]),
              wp_kses($dismiss_button, ['a' => ['href' => []]])
            );
        }
    }

    /**
     * @param string $option
     *
     * @return string
     */
    public static function getOptionId(string $option)
    {
        return "woocommerce_myparcel_{$option}_settings";
    }

    /**
     * @return string|void
     */
    public static function getSettingsUrl(): string
    {
        return admin_url("admin.php?page=" . self::SETTINGS_MENU_SLUG);
    }

    /**
     * Render the settings sections. Mostly taken from the WordPress equivalent but done like this so parts can
     * be overridden/changed easily.
     *
     * @param string $page - Page ID
     *
     * @see \do_settings_sections
     */
    private function render_settings_sections(string $page)
    {
        global $wp_settings_sections, $wp_settings_fields;

        if (! isset($wp_settings_sections[$page])) {
            return;
        }

        foreach ((array) $wp_settings_sections[$page] as $section) {
            echo '<div class="wcmp__settings-section">';
            $id       = Arr::get($section, 'id');
            $title    = Arr::get($section, 'title');
            $callback = Arr::get($section, 'callback');

            if ($title) {
                printf('<h2 id="%s">%s</h2>', esc_html($id), esc_html($title));
            }

            if ($callback) {
                $callback($section);
            }

            if (! isset($wp_settings_fields[$page][$id])) {
                continue;
            }
            echo '<table class="form-table" role="presentation">';
            $this->render_settings_fields($page, $id);
            echo '</table>';
            echo '</div>';
        }
    }

    /**
     * Mostly copied from the WordPress function.
     *
     * @param $page
     * @param $section
     *
     * @see \do_settings_fields
     */
    private function render_settings_fields($page, $section): void
    {
        global $wp_settings_fields;

        if (! Arr::get($wp_settings_fields, "$page.$section")) {
            return;
        }

        foreach (Arr::get($wp_settings_fields, "$page.$section") as $field) {
            $class = Arr::get($field, 'args.class') ?? '';

            if ($class) {
                $class = is_array($class) ? implode(' ', $class) : $class;
                $class = wc_implode_html_attributes(['class' => esc_attr($class)]);
            }

            echo wp_kses("<tr {$class}>", ['tr' => ['class'=>[]]]);

            $helpText = Arr::get($field, 'args.help_text');
            $label    = Arr::get($field, 'args.label_for');

            printf('<th scope="row"><label class="wcmp__ws--nowrap" %s>%s%s</label></th>',
                $label ? 'for="' . esc_attr($label) . '"' : '',
                esc_html(Arr::get($field, 'title')),
                wp_kses(($helpText ? wc_help_tip($helpText) : ''),['span' => ['class' => [], 'data-tip' => [], 'style' => []]])
            );

            // Pass the option id as argument
            Arr::set($field, 'args.option_id', $page);

            echo '<td>';
            call_user_func(
                Arr::get($field, 'callback'),
                Arr::get($field, 'args')
            );
            echo '</td>';
            echo '</tr>';
        }
    }
}

return new WCMYPA_Settings();
