/**
 * Role Mapping Rules Tab
 *
 * Auto-assign WordPress roles based on subscription conditions
 *
 * @package ArraySubs
 */

import React, { useState, useEffect, useCallback } from "react";
import { __ } from "@wordpress/i18n";
import { buildUrl } from "@libs/url";
import { ToastContainer } from "@libs/toast";
import { useToast } from "@libs/toast/useToast";
import { Skeleton } from "@libs/skeleton";
import RestrictionRuleBuilder, {
  defaultConditionTypes,
} from "@/components/RestrictionRuleBuilder";

/**
 * RoleMappingRulesTab Component
 *
 * Manages role mapping rules that auto-assign WordPress roles based on conditions
 */
const RoleMappingRulesTab = () => {
  const { env } = window.arraySubs;
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [rules, setRules] = useState([]);
  const [availableRoles, setAvailableRoles] = useState([]);
  const { toasts, showToast, removeToast } = useToast();

  /**
   * Load settings and available roles on mount
   */
  useEffect(() => {
    loadData();
  }, []);

  /**
   * Fetch settings and available roles
   */
  const loadData = async () => {
    setLoading(true);
    try {
      // Load settings and roles in parallel
      const [settingsRes, rolesRes] = await Promise.all([
        fetch(
          buildUrl(
            `${env?.apiBaseUrl}arraysubs/v1/members-access/settings`,
            {},
          ),
          { headers: { "X-WP-Nonce": env?.nonce } },
        ),
        fetch(
          buildUrl(
            `${env?.apiBaseUrl}arraysubs/v1/members-access/select-options`,
            { type: "roles" },
          ),
          { headers: { "X-WP-Nonce": env?.nonce } },
        ),
      ]);

      if (!settingsRes.ok || !rolesRes.ok) {
        throw new Error(__("Failed to load data", "arraysubs"));
      }

      const settingsData = await settingsRes.json();
      const rolesData = await rolesRes.json();

      setRules(settingsData.data?.role_mapping_rules || []);
      setAvailableRoles(rolesData.data || []);
    } catch (error) {
      console.error("Error loading role mapping rules:", error);
      showToast(__("Failed to load role mapping rules", "arraysubs"), "error");
    } finally {
      setLoading(false);
    }
  };

  /**
   * Save rules to server
   */
  const saveRules = async () => {
    setSaving(true);
    try {
      const response = await fetch(
        buildUrl(`${env?.apiBaseUrl}arraysubs/v1/members-access/settings`, {}),
        {
          method: "POST",
          headers: {
            "X-WP-Nonce": env?.nonce,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            role_mapping_rules: rules,
          }),
        },
      );

      if (!response.ok) {
        throw new Error(__("Failed to save rules", "arraysubs"));
      }

      showToast(__("Rules saved successfully!", "arraysubs"), "success");
    } catch (error) {
      console.error("Error saving rules:", error);
      showToast(__("Failed to save rules", "arraysubs"), "error");
    } finally {
      setSaving(false);
    }
  };

  /**
   * Get default rule structure for role mapping
   */
  const getDefaultRule = useCallback(() => {
    return {
      enabled: true,
      name: __("New Role Mapping Rule", "arraysubs"),
      conditions: { logic: "and", rules: [] },
      add_roles: [],
      remove_roles: [],
      on_hold_behavior: "remove",
      fallback_role: "subscriber",
    };
  }, []);

  /**
   * Render action fields for the THEN section
   */
  const renderActionFields = useCallback(
    (rule, updateRule) => {
      return (
        <>
          {/* Roles to Add */}
          <div className="arraysubs-rule-field">
            <label className="arraysubs-rule-field__label">
              {__("Add Roles", "arraysubs")}
            </label>
            <select
              multiple
              className="arraysubs-rule-field__multi-select"
              value={rule.add_roles || []}
              onChange={(e) =>
                updateRule({
                  add_roles: Array.from(
                    e.target.selectedOptions,
                    (o) => o.value,
                  ),
                })
              }
            >
              {availableRoles.map((role) => (
                <option key={role.value} value={role.value}>
                  {role.label}
                </option>
              ))}
            </select>
            <p className="arraysubs-rule-field__help">
              {__("Hold Ctrl/Cmd to select multiple roles", "arraysubs")}
            </p>
          </div>

          {/* Roles to Remove */}
          <div className="arraysubs-rule-field">
            <label className="arraysubs-rule-field__label">
              {__("Remove Roles", "arraysubs")}
            </label>
            <select
              multiple
              className="arraysubs-rule-field__multi-select"
              value={rule.remove_roles || []}
              onChange={(e) =>
                updateRule({
                  remove_roles: Array.from(
                    e.target.selectedOptions,
                    (o) => o.value,
                  ),
                })
              }
            >
              {availableRoles.map((role) => (
                <option key={role.value} value={role.value}>
                  {role.label}
                </option>
              ))}
            </select>
            <p className="arraysubs-rule-field__help">
              {__("Roles removed when conditions no longer match", "arraysubs")}
            </p>
          </div>

          {/* On Hold Behavior */}
          <div className="arraysubs-rule-field">
            <label className="arraysubs-rule-field__label">
              {__("On Hold Behavior", "arraysubs")}
            </label>
            <select
              value={rule.on_hold_behavior || "remove"}
              onChange={(e) => updateRule({ on_hold_behavior: e.target.value })}
              className="arraysubs-rule-field__select"
            >
              <option value="keep">
                {__("Keep assigned roles", "arraysubs")}
              </option>
              <option value="remove">
                {__("Remove assigned roles", "arraysubs")}
              </option>
            </select>
          </div>

          {/* Fallback Role */}
          <div className="arraysubs-rule-field">
            <label className="arraysubs-rule-field__label">
              {__("Fallback Role", "arraysubs")}
            </label>
            <select
              value={rule.fallback_role || ""}
              onChange={(e) => updateRule({ fallback_role: e.target.value })}
              className="arraysubs-rule-field__select"
            >
              <option value="">{__("No fallback", "arraysubs")}</option>
              {availableRoles.map((role) => (
                <option key={role.value} value={role.value}>
                  {role.label}
                </option>
              ))}
            </select>
            <p className="arraysubs-rule-field__help">
              {__("Role to assign when subscription ends", "arraysubs")}
            </p>
          </div>
        </>
      );
    },
    [availableRoles],
  );

  /**
   * Render loading state
   */
  if (loading) {
    return (
      <div className="arraysubs-members-access__tab-content">
        <Skeleton count={3} height={100} />
      </div>
    );
  }

  return (
    <div className="arraysubs-members-access__tab-content">
      {/* Header with description */}
      <div className="arraysubs-members-access__section-header">
        <div className="arraysubs-members-access__section-info">
          <h3>{__("Role Mapping Rules", "arraysubs")}</h3>
          <p>
            {__(
              "Automatically assign or remove WordPress user roles based on subscription status and conditions. Rules are processed in order.",
              "arraysubs",
            )}
          </p>
        </div>
      </div>

      <div className="arraysubs-members-access__info-box">
        <h4>{__("How Role Mapping Rules Work", "arraysubs")}</h4>
        <ol>
          <li>
            {__(
              "Define who qualifies using the IF conditions — for example, customers with an active subscription to a specific plan, customers who bought a certain product, or users with an existing role.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Configure the THEN section — add one or more roles, remove old roles, decide what happens while a subscription is on-hold, and optionally assign a fallback role when access ends.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "When a customer matches a rule, the selected roles are applied automatically. When they stop matching, roles can be removed again based on the rule settings.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Rules are evaluated in order, so place more specific role mappings before broad catch-all rules if you need predictable outcomes.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Use this to sync WordPress permissions with membership access — for example unlocking member-only dashboards, courses, communities, or admin-controlled content.",
              "arraysubs",
            )}
          </li>
        </ol>
        <p className="arraysubs-members-access__info-note">
          <strong>{__("Note:", "arraysubs")}</strong>{" "}
          {__(
            "Be careful when removing default WordPress roles. If needed, use a fallback role like Subscriber so customers do not end up with fewer permissions than intended after access expires.",
            "arraysubs",
          )}
        </p>
      </div>

      {/* Rule Builder */}
      <RestrictionRuleBuilder
        rules={rules}
        onChange={setRules}
        ruleType="role_mapping"
        conditionTypes={defaultConditionTypes}
        renderActionFields={renderActionFields}
        getDefaultRule={getDefaultRule}
        ruleLabel={__("Role Mapping Rule", "arraysubs")}
      />

      {/* Save Button */}
      {rules.length > 0 && (
        <div className="arraysubs-members-access__actions arraysubs-bottom-fixed-actions">
          <div>
            <button
              type="button"
              className="button button-primary"
              onClick={saveRules}
              disabled={saving}
            >
              {saving
                ? __("Saving...", "arraysubs")
                : __("Save Rules", "arraysubs")}
            </button>
          </div>
        </div>
      )}

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

export default RoleMappingRulesTab;
