import React, { useState, useEffect, useCallback } from "react";
import { __ } from "@wordpress/i18n";
import Form from "rc-field-form";
import FormBuilder from "@libs/form-builder";
import { Skeleton } from "@libs/skeleton";
import { ToastContainer } from "@libs/toast";
import { useToast } from "@libs/toast/useToast";
import DefaultPageLayout from "@/components/DefaultPageLayout";
import {
  dotToNested,
  nestedToDot,
  fetchSettings,
  saveSettings,
} from "./settingsHelpers";
import { buildUrl } from "@libs/url";

/**
 * Build the form structure for Toolkit settings.
 *
 * Receives roles as a parameter so the MultiSelect data
 * can be populated after the async fetch.
 *
 * @param {Array} roleOptions - Array of { value, label } for WP roles.
 * @returns {Array} FormBuilder formItems structure.
 */
const getFormStructure = (roleOptions) => [
  // Admin Bar
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Admin Bar", "arraysubs"),
        subText: __(
          "Control the WordPress admin bar visibility on the frontend",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "toolkit.hide_admin_bar",
        label: __("Hide admin bar for non-admin users", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When enabled, the WordPress admin bar will be hidden on the frontend for all users who are not administrators or do not have an allowed role. Administrators always see the admin bar.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Flow: members and customers browse the frontend without the WordPress toolbar, while administrators and allowed staff still keep their normal admin shortcuts. This only affects the frontend view and does not change backend capabilities by itself.",
          "arraysubs",
        ),
      },
    ],
  },

  // WP-Admin Access
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Admin Dashboard Access", "arraysubs"),
        subText: __(
          "Restrict access to the WordPress admin dashboard for non-admin users",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "toolkit.restrict_wp_admin",
        label: __("Restrict wp-admin access", "arraysubs"),
      },
      {
        field: "Select",
        name: "toolkit.wp_admin_redirect",
        label: __("Redirect unauthorized users to", "arraysubs"),
        data: [
          {
            label: __("WooCommerce My Account page", "arraysubs"),
            value: "my_account",
          },
          {
            label: __("404 Not Found page", "arraysubs"),
            value: "not_found",
          },
        ],
        showWhen: {
          field: "toolkit.restrict_wp_admin",
          operator: "=",
          value: true,
        },
      },
      {
        field: "MultiSelect",
        name: "toolkit.allowed_roles",
        label: __("Allowed roles", "arraysubs"),
        data: roleOptions,
        placeholder: __("Select roles that retain admin access…", "arraysubs"),
        showWhen: {
          field: "toolkit.restrict_wp_admin",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Users with the selected roles will still have access to the WordPress admin dashboard. Administrators always have access regardless of this setting. AJAX, REST API, WP-Cron, and other infrastructure requests are never blocked.",
          "arraysubs",
        ),
        showWhen: {
          field: "toolkit.restrict_wp_admin",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          "Flow: after saving, members who try to open /wp-admin will be redirected to the destination you choose here. Administrators are always allowed, and any selected staff roles keep normal backend access. Logged-out visitors can still reach the normal WordPress authentication flow when admin access requires login.",
          "arraysubs",
        ),
        showWhen: {
          field: "toolkit.restrict_wp_admin",
          operator: "=",
          value: true,
        },
      },
    ],
  },

  // WP Login Page
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("WordPress Login Page", "arraysubs"),
        subText: __(
          "Hide the default WordPress login page and funnel logins through WooCommerce",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "toolkit.hide_wp_login",
        label: __("Hide WordPress login page", "arraysubs"),
      },
      {
        field: "Select",
        name: "toolkit.wp_login_redirect",
        label: __("Redirect login page to", "arraysubs"),
        data: [
          {
            label: __("WooCommerce My Account page", "arraysubs"),
            value: "my_account",
          },
          {
            label: __("404 Not Found page", "arraysubs"),
            value: "not_found",
          },
        ],
        showWhen: {
          field: "toolkit.hide_wp_login",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          "Password reset links, email verification callbacks, and logout requests will continue to work even when the login page is hidden. Administrators can always access the login page when logged in.",
          "arraysubs",
        ),
        showWhen: {
          field: "toolkit.hide_wp_login",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When this is enabled, the default /wp-login.php page will redirect visitors to the selected target. WooCommerce My Account should be configured to handle login and registration. This makes your membership site feel like a true frontend experience.",
          "arraysubs",
        ),
        showWhen: {
          field: "toolkit.hide_wp_login",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Flow: customer-facing login and sign-up links now resolve to the WooCommerce My Account page instead of wp-login.php. That includes third-party plugins or themes that call the standard WordPress login or registration URL helpers. Admin-targeted login flows still keep the WordPress admin login path when needed.",
          "arraysubs",
        ),
        showWhen: {
          field: "toolkit.hide_wp_login",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          "Before enabling this on a live site, confirm that WooCommerce account registration is configured the way you want and that your My Account page is publicly reachable. If registration is disabled in WooCommerce, visitors will still land on My Account but only the login form will be available.",
          "arraysubs",
        ),
        showWhen: {
          field: "toolkit.hide_wp_login",
          operator: "=",
          value: true,
        },
      },
    ],
  },

  // Login as User
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Login as User", "arraysubs"),
        subText: __(
          "Allow administrators to log in as any non-admin user for troubleshooting and support",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "toolkit.login_as_user",
        label: __("Enable Login as User", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When enabled, administrators can impersonate non-admin users from the Users list, user profile, WooCommerce order pages, and subscription detail screens. A notification bar is shown while impersonating.",
          "arraysubs",
        ),
      },
    ],
  },

];

const ToolkitSettings = () => {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [formData, setFormData] = useState({});
  const [roleOptions, setRoleOptions] = useState([]);
  const { toasts, showToast, removeToast } = useToast();
  const { env } = window.arraySubs || {};

  /**
   * Fetch available WordPress roles.
   */
  const fetchRoles = useCallback(async () => {
    try {
      const url = buildUrl(
        `${env?.apiBaseUrl || ""}arraysubs/v1/members-access/select/roles`,
      );
      const response = await fetch(url, {
        headers: {
          "X-WP-Nonce": env?.nonce || "",
        },
      });

      if (!response.ok) {
        return;
      }

      const result = await response.json();

      if (result?.success && Array.isArray(result?.data)) {
        // Exclude 'administrator' — admins are always allowed.
        const filtered = result.data.filter(
          (role) => role.value !== "administrator",
        );
        setRoleOptions(filtered);
      }
    } catch {
      // Roles fetch failure is non-critical — the form still works.
    }
  }, [env?.apiBaseUrl, env?.nonce]);

  const loadSettings = useCallback(async () => {
    setLoading(true);
    try {
      const [settings] = await Promise.all([fetchSettings(), fetchRoles()]);
      const flatData = nestedToDot(settings);
      setFormData(flatData);
      form.setFieldsValue(flatData);
    } catch (err) {
      showToast(
        err.message || __("Failed to load settings", "arraysubs"),
        "error",
      );
    } finally {
      setLoading(false);
    }
  }, [form, showToast, fetchRoles]);

  useEffect(() => {
    loadSettings();
  }, [loadSettings]);

  const handleSubmit = async (values) => {
    setSaving(true);
    try {
      const nestedData = dotToNested(values);
      const savedSettings = await saveSettings(nestedData);
      const nextFormData = nestedToDot(savedSettings);

      window.arraySubs.settings = savedSettings;
      setFormData(nextFormData);
      showToast(__("Settings saved!", "arraysubs"), "success");
    } catch (err) {
      showToast(
        err.message || __("Failed to save settings", "arraysubs"),
        "error",
      );
    } finally {
      setSaving(false);
    }
  };

  const handleDiscard = () => {
    form.setFieldsValue(formData);
  };

  if (loading) {
    return (
      <DefaultPageLayout title={__("Toolkit", "arraysubs")}>
        <Skeleton variant="rectangle" width="100%" height={400} />
      </DefaultPageLayout>
    );
  }

  return (
    <DefaultPageLayout
      title={__("Toolkit", "arraysubs")}
      subtitle={__(
        "Control admin bar, dashboard access, login page visibility, and admin tools",
        "arraysubs",
      )}
    >
      <Form form={form} onFinish={handleSubmit} layout="vertical">
        <FormBuilder formItems={getFormStructure(roleOptions)} form={form} />

        <div className="arraysubs-settings-actions arraysubs-bottom-fixed-actions">
          <div>
            <button
              type="submit"
              className="button button-primary"
              disabled={saving}
            >
              {saving
                ? __("Saving...", "arraysubs")
                : __("Save Settings", "arraysubs")}
            </button>
            <button
              type="button"
              className="button"
              onClick={handleDiscard}
              disabled={saving}
            >
              {__("Discard Changes", "arraysubs")}
            </button>
          </div>
        </div>
      </Form>

      <ToastContainer toasts={toasts} removeToast={removeToast} />
    </DefaultPageLayout>
  );
};

export default ToolkitSettings;
