<?php

namespace Webnestors\Wsn;

class Plugin {
    const VERSION = "1.1.1";
    private string $plugin_file;
    private static $instance = null;

    public static function instance(): self {
        if (!self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    public function plugin_dir_path() {
        return plugin_dir_path($this->plugin_file);
    }

    public function get_url(string $path) {
        return trailingslashit(plugins_url("", $this->plugin_file)) . $path;
    }

    public function init(string $plugin_file) {
        $this->plugin_file = $plugin_file;
        $this->register_hooks();
        $this->register_admin_hooks();
        $this->run_snippets();
    }

    private function register_hooks() {
    }

    private function register_admin_hooks() {
        if (!is_admin()) {
            return;
        }

        add_action("admin_menu", [Settings::class, "init"]);

        add_action("admin_enqueue_scripts", function () {
            wp_register_script("wsn-settings", $this->get_url("assets/dist/wsn.iife.js"), [], self::VERSION);

            wp_register_style(
                "wsn-settings-style",
                $this->get_url("assets/dist/style.css"),
                [],
                self::VERSION
            );
        });

        add_action("wp_ajax_wsn_toggle", function () {
            if (!check_admin_referer("enhancements_for_woocommerce")) {
                wp_send_json_error(["error" => "nonce verify fail"]);
            }

            if (!current_user_can("manage_options")) {
                wp_send_json_error(["error" => "unauthorized"]);
            }

            $id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
            $enabled = boolval(sanitize_text_field(filter_input(INPUT_POST, "enabled")));
            $wsn_settings = get_option("enhancements_for_woocommerce_settings", []);
            $wsn_settings[$id]["__enabled"] = $enabled;
            update_option("enhancements_for_woocommerce_settings", $wsn_settings);
            wp_send_json_success();
            wp_die();
        });

        add_action("wp_ajax_wsn_save", function () {
            if (!check_admin_referer("enhancements_for_woocommerce")) {
                wp_send_json_error(["error" => "nonce verify fail"]);
            }

            if (!current_user_can("manage_options")) {
                wp_send_json_error(["error" => "unauthorized"]);
            }

            $id = filter_input(INPUT_POST, "id", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
            $snippet = self::get_snippet_object_by_id($id);

            if (!$snippet) {
                return;
            }

            $wsn_settings = get_option("enhancements_for_woocommerce_settings", []);

            $saved_settings = [
                "__enabled" => boolval(sanitize_text_field(filter_input(INPUT_POST, "__enabled"))),
            ];

            foreach ($snippet->meta() as $meta) {
                if (isset($_POST[$meta["name"]])) {
                    $saved_settings[$meta["name"]] = wp_kses_post($_POST[$meta["name"]]);
                }
            }

            $wsn_settings = get_option("enhancements_for_woocommerce_settings", []);
            $wsn_settings[$id] = $saved_settings;
            update_option("enhancements_for_woocommerce_settings", $wsn_settings);

            wp_send_json_success(["wsn_settings" => $wsn_settings]);
            wp_die();
        });

        add_action("wp_ajax_wsn_fetch_tooltip", function () {
            if (!current_user_can("manage_options")) {
                wp_die();
            }

            $id = sanitize_text_field(filter_input(INPUT_GET, "id"));
            $snippet = self::get_snippet_object_by_id($id);

            if ($snippet) {
                echo wp_kses_post($snippet->tooltip());
            }

            wp_die();
        });
    }

    private function run_snippets() {
        $wsn_settings = get_option("enhancements_for_woocommerce_settings", []);
        $snippets = self::get_snippet_objects();
        $stylesheets = [];

        foreach ($snippets as $snippet) {
            $settings = $wsn_settings[$snippet::class] ?? null;

            if ($settings && $settings["__enabled"] ?? false === true) {
                foreach ($settings as $key => $value) {
                    if (property_exists($snippet, $key)) {
                        $snippet->{$key} = $value;
                    }
                }

                $stylesheets[] = str_replace("Webnestors\\Wsn\\Snippets\\", "", $snippet::class);

                $snippet->run();
            }
        }

        add_action("wp_enqueue_scripts", function () use ($stylesheets) {
            foreach ($stylesheets as $s) {
                $file = plugin_dir_path($this->plugin_file) . "assets/snippets/styles/" . $s . ".css";

                if (!file_exists($file)) {
                    continue;
                }

                wp_enqueue_style("wsn-$s", $this->get_url("assets/snippets/styles/$s.css"));
            }
        });
    }

    static function get_snippet_objects() {
        $namespace = "Webnestors\\Wsn\\Snippets";
        $classmap = require __DIR__ . "/../vendor/composer/autoload_classmap.php";
        $classes = [];

        foreach ($classmap as $class => $path) {
            if (strpos($class, $namespace) === 0) {
                /** @var Snippet */
                $class = new $class();
                $classes[] = $class;
            }
        }

        return $classes;
    }

    /**
     * @return ?Snippet
     */
    static function get_snippet_object_by_id(string $id) {
        $namespace = "Webnestors\\Wsn\\Snippets";
        $classmap = require __DIR__ . "/../vendor/composer/autoload_classmap.php";

        foreach ($classmap as $class => $path) {
            if (strpos($class, $namespace) === 0 && $class === $id) {
                /** @var Snippet */
                $class = new $class();
                return $class;
            }
        }

        return null;
    }
}
