import React, { useState, useEffect, useMemo, useCallback } from "react";
import { __ } from "@wordpress/i18n";
import Form, { useWatch } 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";

// Default prefilled cancellation reasons
const DEFAULT_REASONS = [
  {
    id: "too_expensive",
    key: "too_expensive",
    label: __("Too expensive", "arraysubs"),
  },
  {
    id: "not_using",
    key: "not_using",
    label: __("Not using it enough", "arraysubs"),
  },
  {
    id: "found_alternative",
    key: "found_alternative",
    label: __("Found a better alternative", "arraysubs"),
  },
  {
    id: "missing_features",
    key: "missing_features",
    label: __("Missing features I need", "arraysubs"),
  },
  {
    id: "technical_issues",
    key: "technical_issues",
    label: __("Technical issues", "arraysubs"),
  },
  {
    id: "temporary_pause",
    key: "temporary_pause",
    label: __("Just need a temporary break", "arraysubs"),
  },
  { id: "other", key: "other", label: __("Other", "arraysubs") },
];

const hasSavedReasons = (settings) =>
  Array.isArray(settings?.cancellation?.reasons) &&
  Object.prototype.hasOwnProperty.call(settings.cancellation, "reasons");

// Helper to build reason options from repeater data
const buildReasonOptions = (reasons) => {
  if (!reasons || !Array.isArray(reasons) || reasons.length === 0) {
    return [];
  }

  return [
    ...reasons.map((reason) => ({
      value: reason.key || reason.id || "",
      label: reason.label || reason.key || __("Unnamed reason", "arraysubs"),
    })),
  ];
};

/**
 * Build retention condition fields for a specific offer.
 *
 * Each offer can optionally restrict eligibility by subscription value,
 * customer lifetime spend, and remaining days until next payment/end.
 * Fields are hidden unless the offer is enabled.
 */
const buildConditionFields = (offerKey) => {
  const prefix = `cancellation.retention_offers.${offerKey}`;
  const enabledField = `${prefix}.enabled`;
  const showWhen = { field: enabledField, operator: "=", value: true };

  return [
    {
      field: "Title",
      heading: 5,
      text: __("Eligibility Conditions", "arraysubs"),
      subText: __(
        "Restrict this offer to subscriptions matching these conditions. Leave a field empty or set it to 0 to ignore that rule.",
        "arraysubs",
      ),
      showWhen,
    },
    {
      field: "Alert",
      type: "info",
      message: __(
        "Subscription value uses the subscription recurring price. Customer lifetime spend uses the customer's total WooCommerce spend. Remaining days uses the same end-of-period timing logic as cancellation scheduling, based on the earliest valid next payment or end date.",
        "arraysubs",
      ),
      showWhen,
    },
    {
      field: "Number",
      name: `${prefix}.min_subscription_age_days`,
      label: __("Minimum Subscription Age (days)", "arraysubs"),
      min: 0,
      helperText: __(
        "Only show this offer if the subscription start date is at least this many days in the past.",
        "arraysubs",
      ),
      showWhen,
    },
    {
      field: "AutoGrid",
      cols: 2,
      showWhen,
      children: [
        {
          field: "Number",
          name: `${prefix}.min_subscription_value`,
          label: __("Min Subscription Value", "arraysubs"),
          min: 0,
          step: "0.01",
          helperText: __(
            "The subscription recurring price must be at least this amount.",
            "arraysubs",
          ),
        },
        {
          field: "Number",
          name: `${prefix}.max_subscription_value`,
          label: __("Max Subscription Value", "arraysubs"),
          min: 0,
          step: "0.01",
          helperText: __(
            "The subscription recurring price must be at most this amount.",
            "arraysubs",
          ),
        },
      ],
    },
    {
      field: "AutoGrid",
      cols: 2,
      showWhen,
      children: [
        {
          field: "Number",
          name: `${prefix}.min_user_total_value`,
          label: __("Min Customer Lifetime Spend", "arraysubs"),
          min: 0,
          step: "0.01",
          helperText: __(
            "The customer's total WooCommerce spend must be at least this amount.",
            "arraysubs",
          ),
        },
        {
          field: "Number",
          name: `${prefix}.max_user_total_value`,
          label: __("Max Customer Lifetime Spend", "arraysubs"),
          min: 0,
          step: "0.01",
          helperText: __(
            "The customer's total WooCommerce spend must be at most this amount.",
            "arraysubs",
          ),
        },
      ],
    },
    {
      field: "AutoGrid",
      cols: 2,
      showWhen,
      children: [
        {
          field: "Number",
          name: `${prefix}.min_remaining_days`,
          label: __("Min Remaining Days", "arraysubs"),
          min: 0,
          helperText: __(
            "The subscription must have at least this many days remaining until its next payment or end date.",
            "arraysubs",
          ),
        },
        {
          field: "Number",
          name: `${prefix}.max_remaining_days`,
          label: __("Max Remaining Days", "arraysubs"),
          min: 0,
          helperText: __(
            "The subscription must have at most this many days remaining until its next payment or end date.",
            "arraysubs",
          ),
        },
      ],
    },
  ];
};

// Build form structure with callback for dynamic reason options
const buildFormStructure = (getReasonOptions) => [
  // Cancellation Settings
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Cancellation Settings", "arraysubs"),
        subText: __("Configure how cancellations are processed", "arraysubs"),
      },
      {
        field: "Switch",
        name: "cancellation.cancel_immediately",
        label: __("Cancel Immediately", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When disabled, cancelled subscriptions will remain active until the end of the current billing period.",
          "arraysubs",
        ),
      },
    ],
  },

  // Cancellation Reasons
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Cancellation Reasons", "arraysubs"),
        subText: __(
          "Configure the reasons customers can select when cancelling their subscriptions",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "cancellation.require_reason",
        label: __("Require Cancellation Reason", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When enabled, customers must select a reason when cancelling from My Account. This helps you understand why customers are leaving.",
          "arraysubs",
        ),
      },
    ],
  },

  // Cancellation Reasons Repeater
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Cancellation Reason Options", "arraysubs"),
        subText: __(
          "Add, edit, or remove the reasons customers can choose from. Drag to reorder.",
          "arraysubs",
        ),
      },
      {
        field: "Repeater",
        name: "cancellation.reasons",
        addButtonText: __("Add Reason", "arraysubs"),
        itemTitleTemplate: __("Reason {index}", "arraysubs"),
        showFirstInputInTitle: true,
        collapsible: true,
        showDeleteButton: true,
        items: [
          {
            field: "Text",
            name: "key",
            label: __("Reason Key", "arraysubs"),
            placeholder: __("e.g., too_expensive", "arraysubs"),
            helperText: __(
              "Unique identifier (lowercase, no spaces). Used for analytics.",
              "arraysubs",
            ),
            rules: [
              { required: true, message: __("Key is required", "arraysubs") },
            ],
          },
          {
            field: "Text",
            name: "label",
            label: __("Display Label", "arraysubs"),
            placeholder: __("e.g., Too expensive", "arraysubs"),
            helperText: __(
              "What customers will see when selecting this reason.",
              "arraysubs",
            ),
            rules: [
              { required: true, message: __("Label is required", "arraysubs") },
            ],
          },
        ],
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          'Tip: Include an "Other" option with a key of "other" to allow customers to provide custom feedback.',
          "arraysubs",
        ),
      },
    ],
  },

  // Retention Offers
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Retention Offers", "arraysubs"),
        subText: __(
          "Show special offers to customers before they cancel based on their selected reason",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "cancellation.retention_offers_enabled",
        label: __("Enable Retention Offers", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When enabled, customers will see targeted retention offers based on their cancellation reason. This can significantly reduce churn.",
          "arraysubs",
        ),
      },
    ],
  },

  // Discount Offer
  {
    field: "Card",
    showWhen: {
      field: "cancellation.retention_offers_enabled",
      operator: "=",
      value: true,
    },
    children: [
      {
        field: "Title",
        heading: 4,
        text: __("💰 Discount Offer", "arraysubs"),
        subText: __(
          "Offer a temporary discount to keep the customer",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "cancellation.retention_offers.discount.enabled",
        label: __("Enable Discount Offer", "arraysubs"),
      },
      {
        field: "MultiSelect",
        name: "cancellation.retention_offers.discount.trigger_reasons",
        label: __("Show for these reasons", "arraysubs"),
        placeholder: __("Select reasons...", "arraysubs"),
        helperText: __(
          "This offer will be shown when customers select any of these reasons. Leave empty to show for all reasons.",
          "arraysubs",
        ),
        getOptions: getReasonOptions,
        showWhen: {
          field: "cancellation.retention_offers.discount.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "AutoGrid",
        cols: 2,
        showWhen: {
          field: "cancellation.retention_offers.discount.enabled",
          operator: "=",
          value: true,
        },
        children: [
          {
            field: "Number",
            name: "cancellation.retention_offers.discount.discount_percent",
            label: __("Discount Percentage", "arraysubs"),
            min: 1,
            max: 100,
            suffix: "%",
          },
          {
            field: "Number",
            name: "cancellation.retention_offers.discount.discount_cycles",
            label: __("Number of Billing Cycles", "arraysubs"),
            min: 1,
            max: 12,
          },
        ],
      },
      {
        field: "Text",
        name: "cancellation.retention_offers.discount.headline",
        label: __("Custom Headline (optional)", "arraysubs"),
        placeholder: __("e.g., Stay with us and save!", "arraysubs"),
        showWhen: {
          field: "cancellation.retention_offers.discount.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "TextArea",
        name: "cancellation.retention_offers.discount.description",
        label: __("Custom Description (optional)", "arraysubs"),
        placeholder: __(
          "e.g., We'll give you {percent}% off for the next {cycles} billing cycles.",
          "arraysubs",
        ),
        rows: 2,
        showWhen: {
          field: "cancellation.retention_offers.discount.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          "Support note: Discount-offer renewal amount updates are currently supported on manual payments and Stripe automatic renewals. PayPal and Paddle do not support the same direct automatic retention amount update flow.",
          "arraysubs",
        ),
        showWhen: {
          field: "cancellation.retention_offers.discount.enabled",
          operator: "=",
          value: true,
        },
      },
      ...buildConditionFields("discount"),
    ],
  },

  // Pause Offer
  {
    field: "Card",
    showWhen: {
      field: "cancellation.retention_offers_enabled",
      operator: "=",
      value: true,
    },
    children: [
      {
        field: "Title",
        heading: 4,
        text: __("⏸️ Pause Offer", "arraysubs"),
        subText: __("Allow customers to pause instead of cancel", "arraysubs"),
      },
      {
        field: "Switch",
        name: "cancellation.retention_offers.pause.enabled",
        label: __("Enable Pause Offer", "arraysubs"),
      },
      {
        field: "MultiSelect",
        name: "cancellation.retention_offers.pause.trigger_reasons",
        label: __("Show for these reasons", "arraysubs"),
        placeholder: __("Select reasons...", "arraysubs"),
        helperText: __(
          "Best for reasons like 'temporary break' or 'not using'. Leave empty for all reasons.",
          "arraysubs",
        ),
        getOptions: getReasonOptions,
        showWhen: {
          field: "cancellation.retention_offers.pause.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Number",
        name: "cancellation.retention_offers.pause.max_pause_days",
        label: __("Maximum Pause Duration (days)", "arraysubs"),
        min: 7,
        max: 90,
        showWhen: {
          field: "cancellation.retention_offers.pause.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Text",
        name: "cancellation.retention_offers.pause.headline",
        label: __("Custom Headline (optional)", "arraysubs"),
        placeholder: __("e.g., Need a break?", "arraysubs"),
        showWhen: {
          field: "cancellation.retention_offers.pause.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "TextArea",
        name: "cancellation.retention_offers.pause.description",
        label: __("Custom Description (optional)", "arraysubs"),
        placeholder: __(
          "e.g., Take a break for up to {days} days. Your subscription will automatically resume.",
          "arraysubs",
        ),
        rows: 2,
        showWhen: {
          field: "cancellation.retention_offers.pause.enabled",
          operator: "=",
          value: true,
        },
      },
      ...buildConditionFields("pause"),
    ],
  },

  // Downgrade Offer
  {
    field: "Card",
    showWhen: {
      field: "cancellation.retention_offers_enabled",
      operator: "=",
      value: true,
    },
    children: [
      {
        field: "Title",
        heading: 4,
        text: __("⬇️ Downgrade Offer", "arraysubs"),
        subText: __(
          "Suggest a cheaper plan instead of cancelling",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "cancellation.retention_offers.downgrade.enabled",
        label: __("Enable Downgrade Offer", "arraysubs"),
      },
      {
        field: "MultiSelect",
        name: "cancellation.retention_offers.downgrade.trigger_reasons",
        label: __("Show for these reasons", "arraysubs"),
        placeholder: __("Select reasons...", "arraysubs"),
        helperText: __(
          "Best for 'too expensive' or 'missing features' reasons. Leave empty for all reasons.",
          "arraysubs",
        ),
        getOptions: getReasonOptions,
        showWhen: {
          field: "cancellation.retention_offers.downgrade.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "This will show available downgrade options based on your Plan Switching configuration. Make sure you have downgrade paths configured for your subscription products.",
          "arraysubs",
        ),
        showWhen: {
          field: "cancellation.retention_offers.downgrade.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Text",
        name: "cancellation.retention_offers.downgrade.headline",
        label: __("Custom Headline (optional)", "arraysubs"),
        placeholder: __("e.g., Try a smaller plan", "arraysubs"),
        showWhen: {
          field: "cancellation.retention_offers.downgrade.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "TextArea",
        name: "cancellation.retention_offers.downgrade.description",
        label: __("Custom Description (optional)", "arraysubs"),
        placeholder: __(
          "e.g., Keep using our service with a more affordable plan that fits your needs.",
          "arraysubs",
        ),
        rows: 2,
        showWhen: {
          field: "cancellation.retention_offers.downgrade.enabled",
          operator: "=",
          value: true,
        },
      },
      ...buildConditionFields("downgrade"),
    ],
  },

  // Contact Support Offer
  {
    field: "Card",
    showWhen: {
      field: "cancellation.retention_offers_enabled",
      operator: "=",
      value: true,
    },
    children: [
      {
        field: "Title",
        heading: 4,
        text: __("💬 Contact Support Offer", "arraysubs"),
        subText: __(
          "Encourage customers to reach out before cancelling",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "cancellation.retention_offers.contact_support.enabled",
        label: __("Enable Contact Support Offer", "arraysubs"),
      },
      {
        field: "MultiSelect",
        name: "cancellation.retention_offers.contact_support.trigger_reasons",
        label: __("Show for these reasons", "arraysubs"),
        placeholder: __("Select reasons...", "arraysubs"),
        helperText: __(
          "Best for 'technical issues' or 'missing features' reasons. Leave empty for all reasons.",
          "arraysubs",
        ),
        getOptions: getReasonOptions,
        showWhen: {
          field: "cancellation.retention_offers.contact_support.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Text",
        name: "cancellation.retention_offers.contact_support.support_url",
        label: __("Support Hub URL", "arraysubs"),
        placeholder: __("e.g., https://yoursite.com/support", "arraysubs"),
        helperText: __(
          "The URL where customers will be directed to contact your support team.",
          "arraysubs",
        ),
        rules: [
          {
            required: true,
            message: __(
              "Support URL is required when this offer is enabled",
              "arraysubs",
            ),
          },
        ],
        showWhen: {
          field: "cancellation.retention_offers.contact_support.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Text",
        name: "cancellation.retention_offers.contact_support.headline",
        label: __("Custom Headline (optional)", "arraysubs"),
        placeholder: __("e.g., Let's talk before you go", "arraysubs"),
        showWhen: {
          field: "cancellation.retention_offers.contact_support.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "TextArea",
        name: "cancellation.retention_offers.contact_support.description",
        label: __("Custom Description (optional)", "arraysubs"),
        placeholder: __(
          "e.g., Our team is here to help! Let us know what's not working and we'll do our best to fix it.",
          "arraysubs",
        ),
        rows: 2,
        showWhen: {
          field: "cancellation.retention_offers.contact_support.enabled",
          operator: "=",
          value: true,
        },
      },
      {
        field: "Text",
        name: "cancellation.retention_offers.contact_support.button_text",
        label: __("Button Text (optional)", "arraysubs"),
        placeholder: __("e.g., Contact Support", "arraysubs"),
        showWhen: {
          field: "cancellation.retention_offers.contact_support.enabled",
          operator: "=",
          value: true,
        },
      },
      ...buildConditionFields("contact_support"),
    ],
  },
];

const CancellationSettings = () => {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [formData, setFormData] = useState({});
  const { toasts, showToast, removeToast } = useToast();

  // Callback function to get fresh reason options from form
  const getReasonOptions = useCallback(() => {
    // Use dot notation string as that's how the form stores the value
    const currentReasons = form.getFieldValue("cancellation.reasons");
    if (!currentReasons || !Array.isArray(currentReasons)) {
      return [{ value: "_all", label: __("All reasons", "arraysubs") }];
    }

    const validReasons = currentReasons.filter((r) => r && (r.key || r.label));
    return buildReasonOptions(validReasons);
  }, [form]);

  // Build form structure with getOptions callback (only build once)
  const formStructure = useMemo(
    () => buildFormStructure(getReasonOptions),
    [getReasonOptions],
  );

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

  const loadSettings = async () => {
    setLoading(true);
    try {
      const settings = await fetchSettings();
      const flatData = nestedToDot(settings);

      const savedReasons = settings?.cancellation?.reasons;
      if (hasSavedReasons(settings)) {
        // Ensure reasons have proper IDs for the repeater
        const reasonsWithIds = savedReasons.map((r, i) => ({
          ...r,
          id: r.id || `reason-${i}-${Date.now()}`,
        }));
        flatData["cancellation.reasons"] = reasonsWithIds;
      } else {
        // Set default reasons with IDs
        const defaultReasonsWithIds = DEFAULT_REASONS.map((r, i) => ({
          ...r,
          id: r.id || `reason-${i}-${Date.now()}`,
        }));
        flatData["cancellation.reasons"] = defaultReasonsWithIds;
      }

      setFormData(flatData);
      form.setFieldsValue(flatData);
    } catch (err) {
      showToast(
        err.message || __("Failed to load settings", "arraysubs"),
        "error",
      );
    } finally {
      setLoading(false);
    }
  };

  const handleSubmit = async (values) => {
    setSaving(true);
    try {
      const nestedData = dotToNested(values);
      await saveSettings(nestedData);
      setFormData(values);
      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={__("Cancellation & Retention", "arraysubs")}>
        <Skeleton variant="rectangle" width="100%" height={400} />
      </DefaultPageLayout>
    );
  }

  return (
    <DefaultPageLayout
      title={__("Cancellation & Retention", "arraysubs")}
      subtitle={__(
        "Configure cancellation reasons and retention offers to reduce churn",
        "arraysubs",
      )}
    >
      <Form form={form} onFinish={handleSubmit} layout="vertical">
        <FormBuilder formItems={formStructure} 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 CancellationSettings;
