/**
 * Login Limit Rules Tab
 *
 * Set conditional session limits per user based on subscription conditions.
 * Users matching these rules use the rule's session limit instead of the global default.
 *
 * @package ArraySubs
 */

import React, { useState, useEffect, useCallback } from "react";
import { __ } from "@wordpress/i18n";
import Form from "rc-field-form";
import FormBuilder from "@libs/form-builder";
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";
import { fetchSettings, saveSettings } from "../Settings/settingsHelpers";

const getGlobalSettingsFormValues = (settings = {}) => ({
  "toolkit.multi_login_prevention": Boolean(
    settings?.toolkit?.multi_login_prevention,
  ),
  "toolkit.multi_login_max_sessions":
    settings?.toolkit?.multi_login_max_sessions ?? 1,
  "toolkit.multi_login_include_admins": Boolean(
    settings?.toolkit?.multi_login_include_admins,
  ),
});

const getGlobalSettingsPayload = (values = {}) => ({
  toolkit: {
    multi_login_prevention: Boolean(values["toolkit.multi_login_prevention"]),
    multi_login_max_sessions: Number(
      values["toolkit.multi_login_max_sessions"] || 1,
    ),
    multi_login_include_admins: Boolean(
      values["toolkit.multi_login_include_admins"],
    ),
  },
});

const getGlobalSettingsFormStructure = () => [
  {
    field: "Card",
    className: "arraysubs-login-limit-global-settings",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Multi-Login Prevention", "arraysubs"),
        subText: __(
          "Limit the number of concurrent login sessions per user to prevent credential sharing",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "toolkit.multi_login_prevention",
        label: __("Enable Multi-Login Prevention", "arraysubs"),
      },
      {
        field: "Number",
        name: "toolkit.multi_login_max_sessions",
        label: __("Default max sessions per user", "arraysubs"),
        min: 1,
        step: 1,
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "This is the global default. Users who match a Login Limit rule below will use that rule's limit instead. When a user exceeds the session limit, the oldest sessions are automatically destroyed.",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "toolkit.multi_login_include_admins",
        label: __("Apply to administrators", "arraysubs"),
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          "By default, administrators are exempt from session limits. Enable this if you also want to enforce limits for administrator accounts.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Flow: when a customer logs in and already has the maximum number of sessions, the oldest session is automatically terminated. The current login always succeeds. Impersonated sessions (Login as User) are never counted toward the limit.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "For per-subscription or per-role session limits, configure Login Limit Rules below.",
          "arraysubs",
        ),
      },
    ],
  },
];

const LoginLimitRulesTab = () => {
  const { env } = window.arraySubs;
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [rules, setRules] = useState([]);
  const { toasts, showToast, removeToast } = useToast();

  const loadData = useCallback(async () => {
    setLoading(true);
    try {
      const [settings, response] = await Promise.all([
        fetchSettings(),
        fetch(
          buildUrl(
            `${env?.apiBaseUrl}arraysubs/v1/members-access/settings`,
            {},
          ),
          { headers: { "X-WP-Nonce": env?.nonce } },
        ),
      ]);

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

      const data = await response.json();
      setRules(data.data?.login_limit_rules || []);
      form.setFieldsValue(getGlobalSettingsFormValues(settings));
    } catch (error) {
      showToast(__("Failed to load login limit settings", "arraysubs"), "error");
    } finally {
      setLoading(false);
    }
  }, [env?.apiBaseUrl, env?.nonce, form, showToast]);

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

  const saveLoginLimits = async () => {
    setSaving(true);
    try {
      const values = await form.validateFields();
      const [savedSettings, response] = await Promise.all([
        saveSettings(getGlobalSettingsPayload(values)),
        fetch(
          buildUrl(
            `${env?.apiBaseUrl}arraysubs/v1/members-access/settings`,
            {},
          ),
          {
            method: "POST",
            headers: {
              "X-WP-Nonce": env?.nonce,
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              login_limit_rules: rules,
            }),
          },
        ),
      ]);

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

      window.arraySubs.settings = savedSettings;
      form.setFieldsValue(getGlobalSettingsFormValues(savedSettings));
      showToast(__("Login limit settings saved!", "arraysubs"), "success");
    } catch (error) {
      showToast(__("Failed to save login limit settings", "arraysubs"), "error");
    } finally {
      setSaving(false);
    }
  };

  const getDefaultRule = useCallback(() => {
    return {
      enabled: true,
      name: __("New Login Limit Rule", "arraysubs"),
      conditions: { logic: "and", rules: [] },
      max_sessions: 3,
    };
  }, []);

  const renderActionFields = useCallback((rule, updateRule) => {
    return (
      <div className="arraysubs-rule-field">
        <label className="arraysubs-rule-field__label">
          {__("Max Allowed Sessions", "arraysubs")}
        </label>
        <input
          type="number"
          min="1"
          step="1"
          value={rule.max_sessions ?? 1}
          onChange={(e) => {
            const val = parseInt(e.target.value, 10);
            updateRule({ max_sessions: val >= 1 ? val : 1 });
          }}
          className="arraysubs-rule-field__input"
          style={{ maxWidth: "120px" }}
        />
        <p className="arraysubs-rule-field__help">
          {__(
            "The maximum number of concurrent login sessions allowed for users matching this rule. When exceeded, the oldest sessions are logged out.",
            "arraysubs",
          )}
        </p>
      </div>
    );
  }, []);

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

  return (
    <div className="arraysubs-members-access__tab-content">
      <Form form={form} layout="vertical">
        <FormBuilder
          formItems={getGlobalSettingsFormStructure()}
          form={form}
        />
      </Form>

      <div className="arraysubs-members-access__section-header">
        <div className="arraysubs-members-access__section-info">
          <h3>{__("Login Limit Rules", "arraysubs")}</h3>
          <p>
            {__(
              "Set conditional session limits. Users matching these rules will use the rule's session limit instead of the global default. When multiple rules match, the highest limit applies.",
              "arraysubs",
            )}
          </p>
        </div>
      </div>

      <div className="arraysubs-members-access__info-box">
        <h4>{__("How Login Limit Rules Work", "arraysubs")}</h4>
        <ol>
          <li>
            {__(
              "Define who qualifies using the IF conditions — for example, customers with an active subscription to a premium plan, VIP members, or users with a specific role.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Configure the THEN section — set the maximum number of concurrent sessions (devices) allowed for matching users.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "When a user logs in and exceeds the session limit, the oldest sessions are automatically destroyed. The new login always succeeds.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "If a user matches multiple rules, the highest session limit applies (most permissive wins).",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Users who don't match any rule fall back to the global default set above.",
              "arraysubs",
            )}
          </li>
        </ol>
        <p className="arraysubs-members-access__info-note">
          <strong>{__("Note:", "arraysubs")}</strong>{" "}
          {__(
            "Multi-Login Prevention must be enabled above for session enforcement to run. If disabled, no session enforcement occurs regardless of these rules.",
            "arraysubs",
          )}
        </p>
      </div>

      <RestrictionRuleBuilder
        rules={rules}
        onChange={setRules}
        ruleType="login_limit"
        conditionTypes={defaultConditionTypes}
        renderActionFields={renderActionFields}
        getDefaultRule={getDefaultRule}
        ruleLabel={__("Login Limit Rule", "arraysubs")}
      />

      <div className="arraysubs-members-access__actions arraysubs-bottom-fixed-actions">
        <div>
          <button
            type="button"
            className="button button-primary"
            onClick={saveLoginLimits}
            disabled={saving}
          >
            {saving
              ? __("Saving...", "arraysubs")
              : __("Save Login Limits", "arraysubs")}
          </button>
        </div>
      </div>

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

export default LoginLimitRulesTab;
