import React, { useState, useEffect, useMemo, 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 "../Settings/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 form structure with callback for dynamic reason options
const buildFormStructure = (getReasonOptions) => [
  // 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,
        },
      },
    ],
  },

  // 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,
        },
      },
    ],
  },

  // 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,
        },
      },
    ],
  },

  // 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,
        },
      },
    ],
  },
];

const RetentionFlowPage = () => {
  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(() => {
    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)) {
        const reasonsWithIds = savedReasons.map((r, i) => ({
          ...r,
          id: r.id || `reason-${i}-${Date.now()}`,
        }));
        flatData["cancellation.reasons"] = reasonsWithIds;
      } else {
        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={__("Retention Flow", "arraysubs")}>
        <Skeleton variant="rectangle" width="100%" height={400} />
      </DefaultPageLayout>
    );
  }

  return (
    <DefaultPageLayout
      title={__("Retention Flow", "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 RetentionFlowPage;
