<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

if (!class_exists("WC_AddressZen_Integration")):
  #[\AllowDynamicProperties]
  class WC_AddressZen_Integration extends WC_Integration
  {
    public function __construct()
    {
      global $woocommerce;

      $this->id = "addresszen";
      $this->method_title = __(
        "AddressZen - Address Lookup",
        "addresszen"
      );
      $this->method_description = __(
        "US and International Address Verification at checkout",
        "addresszen"
      );

      // Load the settings
      $this->init_form_fields();
      $this->init_settings();

      $this->config = (object) [
        "addresszen_enabled" => $this->get_option("addresszen_enabled"),
        "addresszen_api_key" => $this->get_option("addresszen_api_key"),
        "addresszen_populate_organisation" => $this->get_option(
          "addresszen_populate_organisation"
        ),
        "addresszen_populate_county" => $this->get_option(
          "addresszen_populate_county"
        ),
        "addresszen_watch_country" => $this->get_option(
          "addresszen_watch_country"
        ),
        "addresszen_separate_finder" => $this->get_option(
          "addresszen_separate_finder"
        ),
        "addresszen_autocomplete_override" => $this->get_option(
          "addresszen_autocomplete_override"
        ),
      ];

      add_action("woocommerce_update_options_integration_" . $this->id, [
        $this,
        "process_admin_options",
      ]);
      // Add action for admin settings page
      if (is_admin()) {
        add_action("admin_footer", [$this, "add_admin_settings_js"]);
      }
      if ($this->config->addresszen_enabled === "yes") {
        //AddressZen custom action
        add_action("wp_enqueue_scripts", [$this, "load_scripts"]);
        add_action("admin_enqueue_scripts", [$this, "load_admin_scripts"]);
      }
    }

    public function init_form_fields()
    {
      $this->form_fields = [
        "addresszen_required" => [
          "title" => __("Required", "addresszen"),
          "type" => "title",
          "description" => "",
          "id" => "addresszen_required",
        ],
        "addresszen_enabled" => [
          "id" => "addresszen_enabled",
          "title" => __("Enabled", "addresszen"),
          "type" => "checkbox",
          "description" => __(
            "Enable Address Validation at Checkout",
            "addresszen"
          ),
          "default" => "yes",
        ],
        "addresszen_api_key" => [
          "id" => "addresszen_api_key",
          "title" => __("API Key", "addresszen"),
          "type" => "text",
          "description" => "",
        ],
        "addresszen_options" => [
          "title" => __("Options", "addresszen"),
          "type" => "title",
          "description" => "",
          "id" => "addresszen_options",
        ],
        "addresszen_autocomplete" => [
          "id" => "addresszen_autocomplete",
          "title" => __("Enable Address Autocomplete", "addresszen"),
          "type" => "checkbox",
          "description" => __(
            "Enable Address Autocomplete on Address Fields",
            "addresszen"
          ),
          "default" => "yes",
        ],
        "addresszen_admin_autocomplete" => [
          "id" => "addresszen_admin_autocomplete",
          "title" => __("Enable Admin Address Autocomplete", "addresszen"),
          "type" => "checkbox",
          "description" => __(
            "Enable Address Autocomplete on WooCommerce administrative pages like order creation and editing",
            "addresszen"
          ),
          "default" => "yes",
        ],

        "addresszen_separate_finder" => [
          "id" => "addresszen_separate_finder",
          "title" => __(
            "Create a Separate Field for Address Finder",
            "addresszen"
          ),
          "type" => "checkbox",
          "description" => __(
            "Creates a separate input field for address search, instead of using the first line of the address",
            "addresszen"
          ),
          "default" => "false",
        ],
        "addresszen_hide_address_fields" => [
          "id" => "addresszen_hide_address_fields",
          "title" => __(
            "Hide Address Fields Until Selection",
            "addresszen"
          ),
          "type" => "checkbox",
          "description" => __(
            "When using the separate Address Finder, this will hide the address fields until an address is selected.",
            "addresszen"
          ),
          "default" => "false",
        ],
        "addresszen_populate_organisation" => [
          "id" => "addresszen_populate_organisation",
          "title" => __("Enable Populate Organisation", "addresszen"),
          "type" => "checkbox",
          "description" => __(
            "Fill the Company field based on selected address.",
            "addresszen"
          ),
          "default" => "yes",
        ],

        "addresszen_advanced" => [
          "title" => __("Advanced Configuration", "addresszen"),
          "type" => "title",
          "description" => "",
          "id" => "addresszen_advanced",
        ],
        "addresszen_autocomplete_override" => [
          "id" => "addresszen_autocomplete_override",
          "title" => __(
            "Address Autocomplete Configuration Override",
            "addresszen"
          ),
          "type" => "textarea",
          "description" => __(
            "Override the default configuration of the address autocomplete field. Must be a valid JSON object",
            "addresszen"
          ),
          "default" => "",
        ],
      ];
    }

    private function to_bool($value)
    {
      return $value === "yes";
    }

    private function get_config()
    {
      return [
        "enabled" => $this->to_bool(
          $this->get_option("addresszen_enabled")
        ),
        "apiKey" => $this->get_option("addresszen_api_key"),
        "autocomplete" => $this->to_bool(
          $this->get_option("addresszen_autocomplete")
        ),
        "postcodeLookup" => $this->to_bool(
          $this->get_option("addresszen_postcodelookup")
        ),
        "separateFinder" => $this->to_bool(
          $this->get_option("addresszen_separate_finder")
        ),
        "hideAddressFields" => $this->to_bool(
          $this->get_option("addresszen_hide_address_fields")
        ),
        "populateOrganisation" => $this->to_bool(
          $this->get_option("addresszen_populate_organisation")
        ),
        "autocompleteOverride" => $this->get_option(
          "addresszen_autocomplete_override"
        ),
      ];
    }

    private function get_config_json()
    {
      $config = $this->get_config();
      
      // Validate and sanitize JSON input
      $autocomplete_override = "{}";
      if (strlen($config["autocompleteOverride"]) > 0) {
        $sanitized_override = wp_kses($config["autocompleteOverride"], []);
        $decoded = html_entity_decode($sanitized_override);
        
        // Validate JSON structure
        json_decode($decoded);
        if (json_last_error() === JSON_ERROR_NONE) {
          $autocomplete_override = $decoded;
        } else {
          if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log("Invalid JSON in autocompleteOverride setting");
          }
        }
      }
      
      $config["autocompleteOverride"] = "%autocompleteOverride%";
      $json = json_encode($config, JSON_FORCE_OBJECT);
      $json = str_replace(
        "\"%autocompleteOverride%\"",
        $autocomplete_override,
        $json
      );
      if ($json === false) {
        if (defined('WP_DEBUG') && WP_DEBUG) {
          error_log("Failed to encode config");
        }
        return "{}";
      }
      return $json;
    }

    public function load_scripts()
    {
      $this->add_autocomplete_styles();
      $this->add_idpc_bindings();
    }

    public function load_admin_scripts()
    {
      $enabled = $this->to_bool(
        $this->get_option("addresszen_admin_autocomplete")
      );

      if(!$enabled) return;

      $this->add_autocomplete_styles();
      $this->add_admin_idpc_bindings();
    }

    /**
     * Add autocomplete css
     */
    private function add_autocomplete_styles()
    {
      wp_enqueue_style(
        "addresszen-autocomplete-style",
        ADDRESSZEN_URL . "css/addresszen.css",
        [],
        ADDRESSZEN_VERSION
      );
    }

    /**
     * Add config and bind plugin to page
     */
    private function add_idpc_bindings()
    {
      //need unescape the json
      $script = "window.idpcConfig = " . $this->get_config_json() . ";";
      wp_enqueue_script(
        "addresszen-bindings",
        ADDRESSZEN_URL . "js/woocommerce.min.js",
        [],
        ADDRESSZEN_VERSION,
        true
      );
      wp_add_inline_script("addresszen-bindings", $script, "before");
    }

    /**
     * Init js plugin on the checkout page
     */
    private function add_admin_idpc_bindings()
    {
      //need unescaped json
      $script = "window.idpcConfig = " . $this->get_config_json() . ";";
      wp_enqueue_script(
        "addresszen-bindings",
        ADDRESSZEN_URL . "js/admin-woocommerce.min.js",
        [],
        ADDRESSZEN_VERSION,
        true
      );
      wp_add_inline_script("addresszen-bindings", $script, "before");
    }

    /**
     * Add JavaScript for admin settings page to conditionally show/hide options
     */
    public function add_admin_settings_js() {
      // Only add the script on the AddressZen settings page
      if (!isset($_GET['page']) || sanitize_text_field(wp_unslash($_GET['page'])) !== 'wc-settings' ||
          !isset($_GET['tab']) || sanitize_text_field(wp_unslash($_GET['tab'])) !== 'integration' ||
          !isset($_GET['section']) || sanitize_text_field(wp_unslash($_GET['section'])) !== 'addresszen') {
        return;
      }

      // Enqueue the admin settings script
      wp_enqueue_script(
        'addresszen-admin-settings',
        ADDRESSZEN_URL . 'js/admin-settings.js',
        array('jquery'),
        ADDRESSZEN_VERSION,
        true
      );
    }
  }
endif;
