/**
 * CPT Rules Tab
 *
 * Members Access to posts, pages, and custom post types
 *
 * @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";
import AjaxSelect from "@/components/RestrictionRuleBuilder/AjaxSelect";

/**
 * CptRulesTab Component
 *
 * Manages post type and taxonomy-based access restrictions
 */
const CptRulesTab = () => {
  const { env } = window.arraySubs;
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [rules, setRules] = useState([]);
  const [postTypes, setPostTypes] = useState([]);
  const [taxonomies, setTaxonomies] = useState([]);
  const { toasts, showToast, removeToast } = useToast();

  /**
   * Target types for the rule
   */
  const targetTypes = [
    { value: "post_type", label: __("Entire Post Type", "arraysubs") },
    { value: "taxonomy", label: __("By Taxonomy/Category", "arraysubs") },
    { value: "specific_posts", label: __("Specific Posts/Pages", "arraysubs") },
  ];

  /**
   * Actions available when access is denied
   */
  const actionTypes = [
    { value: "redirect", label: __("Redirect to URL", "arraysubs") },
    { value: "message", label: __("Show message", "arraysubs") },
    { value: "403", label: __("Show 403 forbidden", "arraysubs") },
  ];

  /**
   * Archive behavior options
   */
  const archiveBehaviors = [
    { value: "hide", label: __("Hide from archives/listings", "arraysubs") },
    { value: "show_lock", label: __("Show with lock icon", "arraysubs") },
    {
      value: "show_normal",
      label: __("Show normally (restrict content only)", "arraysubs"),
    },
  ];

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

  /**
   * Fetch CPT rules and available post types/taxonomies
   */
  const loadData = async () => {
    setLoading(true);
    try {
      const [settingsRes, postTypesRes, taxonomiesRes] = 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: "post-types" },
          ),
          { headers: { "X-WP-Nonce": env?.nonce } },
        ),
        fetch(
          buildUrl(
            `${env?.apiBaseUrl}arraysubs/v1/members-access/select-options`,
            { type: "content-taxonomies" },
          ),
          { headers: { "X-WP-Nonce": env?.nonce } },
        ),
      ]);

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

      const settingsData = await settingsRes.json();
      const postTypesData = await postTypesRes.json();
      const taxonomiesData = await taxonomiesRes.json();

      setRules(settingsData.data?.cpt_rules || []);
      setPostTypes(postTypesData.data || []);
      setTaxonomies(taxonomiesData.data || []);
    } catch (error) {
      console.error("Error loading CPT rules:", error);
      showToast(__("Failed to load CPT 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({
            cpt_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 CPT rules
   */
  const getDefaultRule = useCallback(() => {
    return {
      enabled: true,
      name: __("New CPT Rule", "arraysubs"),
      target_type: "post_type",
      post_type: "post",
      taxonomy: "",
      term_ids: [],
      post_ids: [],
      conditions: { logic: "and", rules: [] },
      action: "redirect",
      redirect_url: "",
      message: "",
      archive_behavior: "hide",
      schedule_enabled: false,
      schedule_value: 0,
      schedule_unit: "days",
    };
  }, []);

  /**
   * Render target fields for the TARGET section
   */
  const renderTargetFields = useCallback(
    (rule, updateRule) => {
      const selectedPostTypeLabel =
        postTypes.find((postType) => postType.value === rule.post_type)
          ?.label || __("posts", "arraysubs");

      return (
        <>
          <div className="arraysubs-rule-field-row">
            {/* Target Type */}
            <div className="arraysubs-rule-field">
              <label className="arraysubs-rule-field__label">
                {__("Target Type", "arraysubs")}
              </label>
              <select
                value={rule.target_type || "post_type"}
                onChange={(e) =>
                  updateRule({
                    target_type: e.target.value,
                    taxonomy: "",
                    term_ids: [],
                    post_ids: [],
                  })
                }
                className="arraysubs-rule-field__select"
              >
                {targetTypes.map((type) => (
                  <option key={type.value} value={type.value}>
                    {type.label}
                  </option>
                ))}
              </select>
            </div>

            {/* Post Type (for post_type and specific_posts) */}
            {(rule.target_type === "post_type" ||
              rule.target_type === "specific_posts") && (
              <div className="arraysubs-rule-field">
                <label className="arraysubs-rule-field__label">
                  {__("Post Type", "arraysubs")}
                </label>
                <select
                  value={rule.post_type || "post"}
                  onChange={(e) =>
                    updateRule({
                      post_type: e.target.value,
                      post_ids: [],
                    })
                  }
                  className="arraysubs-rule-field__select"
                >
                  {postTypes.map((pt) => (
                    <option key={pt.value} value={pt.value}>
                      {pt.label}
                    </option>
                  ))}
                </select>
              </div>
            )}

            {/* Taxonomy (for taxonomy target) */}
            {rule.target_type === "taxonomy" && (
              <div className="arraysubs-rule-field">
                <label className="arraysubs-rule-field__label">
                  {__("Taxonomy", "arraysubs")}
                </label>
                <select
                  value={rule.taxonomy || ""}
                  onChange={(e) =>
                    updateRule({
                      taxonomy: e.target.value,
                      term_ids: [],
                    })
                  }
                  className="arraysubs-rule-field__select"
                >
                  <option value="">
                    {__("Select taxonomy...", "arraysubs")}
                  </option>
                  {taxonomies.map((tax) => (
                    <option key={tax.value} value={tax.value}>
                      {tax.label}
                    </option>
                  ))}
                </select>
              </div>
            )}
          </div>

          {/* Term IDs (for taxonomy target) */}
          {rule.target_type === "taxonomy" && rule.taxonomy && (
            <div className="arraysubs-rule-field">
              <label className="arraysubs-rule-field__label">
                {__("Terms", "arraysubs")}
              </label>
              <AjaxSelect
                value={rule.term_ids || []}
                onChange={(ids) => updateRule({ term_ids: ids })}
                endpoint="terms"
                dependsOnValue={rule.taxonomy}
                multiple={true}
                placeholder={__("Search terms...", "arraysubs")}
              />
              <p className="arraysubs-rule-field__help">
                {__(
                  "Search and select the terms to restrict. Leave empty to include every term in this taxonomy.",
                  "arraysubs",
                )}
              </p>
            </div>
          )}

          {/* Post IDs (for specific_posts target) */}
          {rule.target_type === "specific_posts" && (
            <div className="arraysubs-rule-field">
              <label className="arraysubs-rule-field__label">
                {selectedPostTypeLabel}
              </label>
              <AjaxSelect
                value={rule.post_ids || []}
                onChange={(ids) => updateRule({ post_ids: ids })}
                endpoint={`posts?post_type=${encodeURIComponent(
                  rule.post_type || "post",
                )}`}
                multiple={true}
                placeholder={__("Search content...", "arraysubs")}
              />
              <p className="arraysubs-rule-field__help">
                {__(
                  "Search and select the exact entries to restrict for this post type.",
                  "arraysubs",
                )}
              </p>
            </div>
          )}

          {/* Archive Behavior */}
          <div className="arraysubs-rule-field">
            <label className="arraysubs-rule-field__label">
              {__("Archive Behavior", "arraysubs")}
            </label>
            <select
              value={rule.archive_behavior || "hide"}
              onChange={(e) => updateRule({ archive_behavior: e.target.value })}
              className="arraysubs-rule-field__select"
            >
              {archiveBehaviors.map((behavior) => (
                <option key={behavior.value} value={behavior.value}>
                  {behavior.label}
                </option>
              ))}
            </select>
            <p className="arraysubs-rule-field__help">
              {__(
                "How restricted content appears in archives and search results",
                "arraysubs",
              )}
            </p>
          </div>
        </>
      );
    },
    [postTypes, taxonomies, targetTypes, archiveBehaviors],
  );

  /**
   * Render action fields for the THEN section
   */
  const renderActionFields = useCallback(
    (rule, updateRule) => {
      return (
        <>
          {/* Action */}
          <div className="arraysubs-rule-field">
            <label className="arraysubs-rule-field__label">
              {__("Action when denied", "arraysubs")}
            </label>
            <select
              value={rule.action || "redirect"}
              onChange={(e) => updateRule({ action: e.target.value })}
              className="arraysubs-rule-field__select"
            >
              {actionTypes.map((action) => (
                <option key={action.value} value={action.value}>
                  {action.label}
                </option>
              ))}
            </select>
          </div>

          {/* Redirect URL (conditional) */}
          {rule.action === "redirect" && (
            <div className="arraysubs-rule-field">
              <label className="arraysubs-rule-field__label">
                {__("Redirect URL", "arraysubs")}
              </label>
              <input
                type="text"
                className="arraysubs-rule-field__input"
                value={rule.redirect_url || ""}
                onChange={(e) => updateRule({ redirect_url: e.target.value })}
                placeholder={__("/pricing/", "arraysubs")}
              />
            </div>
          )}

          {/* Message (conditional) */}
          {rule.action === "message" && (
            <div className="arraysubs-rule-field">
              <label className="arraysubs-rule-field__label">
                {__("Access Denied Message", "arraysubs")}
              </label>
              <textarea
                className="arraysubs-rule-field__textarea"
                value={rule.message || ""}
                onChange={(e) => updateRule({ message: e.target.value })}
                placeholder={__(
                  "This content is restricted. Please subscribe to access.",
                  "arraysubs",
                )}
                rows={3}
              />
            </div>
          )}
        </>
      );
    },
    [actionTypes],
  );

  /**
   * 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>{__("CPT Rules", "arraysubs")}</h3>
          <p>
            {__(
              "Members Access to posts, pages, custom post types, and taxonomies. Rules can target entire post types, specific categories/tags, or individual posts.",
              "arraysubs",
            )}
          </p>
        </div>
      </div>

      <div className="arraysubs-members-access__info-box">
        <h4>{__("How CPT Rules Work", "arraysubs")}</h4>
        <ol>
          <li>
            {__(
              "Define who gets access using the IF conditions — for example, active subscribers to a membership product, customers with a qualifying order, or users with a specific role.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Choose what to protect in the TARGET section — an entire post type, specific taxonomy terms, or individual posts/pages by ID.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Configure Archive Behavior to control how restricted content appears in listings, search results, and archives: hide it completely, show it with a lock indicator, or show it normally while restricting the actual content.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "Configure the THEN section — redirect the visitor, show a custom message, or return a 403 forbidden response on direct access.",
              "arraysubs",
            )}
          </li>
          <li>
            {__(
              "When a customer gains the required membership, access is granted automatically. If they lose eligibility later, future visits follow the restricted behavior again.",
              "arraysubs",
            )}
          </li>
        </ol>
        <p className="arraysubs-members-access__info-note">
          <strong>{__("Note:", "arraysubs")}</strong>{" "}
          {__(
            "Use CPT Rules for posts, pages, lessons, directories, or other content types. If you only need to protect raw URL patterns, URL Rules are usually the simpler option.",
            "arraysubs",
          )}
        </p>
      </div>

      {/* Rule Builder */}
      <RestrictionRuleBuilder
        rules={rules}
        onChange={setRules}
        ruleType="cpt"
        conditionTypes={defaultConditionTypes}
        renderTargetFields={renderTargetFields}
        renderActionFields={renderActionFields}
        getDefaultRule={getDefaultRule}
        ruleLabel={__("CPT Rule", "arraysubs")}
        showSchedule
      />

      {/* 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 CptRulesTab;
