import React, { useState, useEffect, useMemo } from "react";
import { __ } from "@wordpress/i18n";
import Form from "rc-field-form";
import FormBuilder from "@libs/form-builder";
import SpinnerButton from "@libs/confirm-dialog/SpinnerButton";
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";

const AUTOMATIC_PAYMENTS_MODULE = "Features\\AutomaticPayments\\";

const hasLoadedModule = (moduleFragment) => {
  const classes = window.arraySubs?.liveBootClasses || [];

  return classes.some(
    (className) =>
      typeof className === "string" && className.includes(moduleFragment),
  );
};

// Form structure for General settings
const formStructure = [
  // Multiple Subscriptions
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Multiple Subscriptions", "arraysubs"),
        subText: __(
          "Control how multiple subscriptions are handled",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "multiple_subscriptions.allow_multiple_in_cart",
        label: __("Allow Multiple Subscriptions in Cart", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Controls the current cart only. Turn this off when customers should check out one subscription plan at a time. Existing subscriptions already in the customer's account are not affected by this setting.",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "multiple_subscriptions.one_per_customer",
        label: __("One Subscription per Customer", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Blocks customers from starting another live subscription when the same account or checkout email already has an active, trial, on-hold, or pending subscription. This rule is checked during add to cart for logged-in customers and again at checkout for guests or returning email addresses.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "multiple_subscriptions.one_per_customer",
          operator: "==",
          value: true,
        },
        message: __(
          "When enabled, customers can only move forward with one live subscription relationship at a time unless checkout migration is enabled below.",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "multiple_subscriptions.auto_migrate_on_checkout",
        label: __(
          "Auto Migrate to New Subscription Upon Checkout",
          "arraysubs",
        ),
        showWhen: {
          field: "multiple_subscriptions.one_per_customer",
          operator: "==",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "multiple_subscriptions.auto_migrate_on_checkout",
          operator: "==",
          value: true,
        },
        message: __(
          "Allows checkout to replace the customer's existing subscription with a new eligible plan instead of blocking the order. Pricing is adjusted using the plan switching proration rules for upgrades, downgrades, and crossgrades.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "multiple_subscriptions.auto_migrate_on_checkout",
          operator: "==",
          value: true,
        },
        message: __(
          "Checkout migration only works when ArraySubs can match exactly one existing subscription for the customer and the new product is configured as an allowed switch target. If the customer has multiple matching subscriptions, checkout will still stop and ask them to manage the switch manually.",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "multiple_subscriptions.one_per_product",
        label: __("One Subscription per Product", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Limits each subscription product in the current cart to a quantity of 1. It does not look at subscriptions the customer already owns in their account.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "multiple_subscriptions.one_per_product",
          operator: "==",
          value: true,
        },
        message: __(
          "When enabled, customers can still buy different subscription plans, but each subscription product can only appear once in the cart and order.",
          "arraysubs",
        ),
      },
      {
        field: "Divider",
      },
      {
        field: "Switch",
        name: "multiple_subscriptions.allow_mixed_cart",
        label: __("Allow Mixed Checkout", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Controls whether subscription items can be purchased together with regular one-time products in the same order. This setting does not change the separate rules above for duplicate or replacement subscriptions.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "multiple_subscriptions.allow_mixed_cart",
          operator: "==",
          value: false,
        },
        message: __(
          "Mixed checkout is disabled. Customers cannot purchase subscription and non-subscription products in the same order.",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "multiple_subscriptions.allow_different_cycles",
        label: __("Allow Different Billing Cycles", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When multiple subscription plans are allowed in one checkout, this setting controls whether those plans may use different billing periods or intervals.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "multiple_subscriptions.allow_different_cycles",
          operator: "==",
          value: false,
        },
        message: __(
          "Different billing cycles are disabled. Customers can only purchase multiple subscriptions if they share the same billing period and interval.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Automatic payment gateways may impose additional checkout restrictions regardless of these settings.",
          "arraysubs",
        ),
      },
    ],
  },

  // Button Text
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Button Text", "arraysubs"),
        subText: __(
          "Customize WooCommerce button labels for subscription products",
          "arraysubs",
        ),
      },
      {
        field: "AutoGrid",
        cols: 2,
        children: [
          {
            field: "Text",
            name: "button_text.add_to_cart",
            label: __("Add to Cart Text", "arraysubs"),
            placeholder: __("Subscribe Now", "arraysubs"),
          },
        ],
      },
      {
        field: "Alert",
        type: "info",
        message: __("Leave empty to use default button text.", "arraysubs"),
      },
    ],
  },

  // Checkout & Trials
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Checkout & Trials", "arraysubs"),
        subText: __(
          "Configure checkout behavior and free trial settings",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "checkout.auto_create_account",
        label: __("Auto Create Account", "arraysubs"),
      },
      {
        field: "Select",
        name: "checkout.one_click_mode",
        label: __("One Click Checkout", "arraysubs"),
        data: [
          { value: "default", label: __("Default", "arraysubs") },
          {
            value: "subscription_items",
            label: __("Enabled for subscription items", "arraysubs"),
          },
          {
            value: "all_items",
            label: __("Enabled for all items", "arraysubs"),
          },
        ],
      },
      {
        field: "Switch",
        name: "checkout.disable_cart_page",
        label: __("Disable Cart Page", "arraysubs"),
        showWhen: {
          field: "checkout.one_click_mode",
          operator: "!=",
          value: "default",
        },
      },
      {
        field: "Text",
        name: "checkout.non_subscription_button_text",
        label: __("Non-Subscription Purchase Button Text", "arraysubs"),
        placeholder: __("Buy Now", "arraysubs"),
        showWhen: {
          field: "checkout.one_click_mode",
          operator: "=",
          value: "all_items",
        },
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "checkout.one_click_mode",
          operator: "!=",
          value: "default",
        },
        message: __(
          "One-click checkout sends customers straight to checkout, clears any existing cart contents, and keeps only the clicked item for purchase. Store credit purchases follow the subscription-items mode too.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "checkout.one_click_mode",
          operator: "=",
          value: "all_items",
        },
        message: __(
          "Use the optional button text above to replace the standard purchase button label for regular non-subscription items. Leave it empty to keep WooCommerce's default text.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        message: __(
          "Guest checkout is not available for subscription products. Customers must have an account to manage their subscriptions.",
          "arraysubs",
        ),
      },
      {
        field: "Divider",
      },
      {
        field: "Switch",
        name: "trials.require_payment_method",
        label: __("Require Payment Method for Trials", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "trials.require_payment_method",
          operator: "==",
          value: true,
        },
        message: __(
          "When enabled, customers must provide payment details even for free trials. This helps you keep billing information on file before the trial ends.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "trials.require_payment_method",
          operator: "==",
          value: false,
        },
        message: __(
          "When disabled, customers can start trials without payment details. You will need to collect payment information before the trial ends.",
          "arraysubs",
        ),
      },
      {
        field: "Divider",
      },
      {
        field: "Switch",
        name: "trials.one_trial_per_customer",
        label: __("One Trial per Customer", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "trials.one_trial_per_customer",
          operator: "==",
          value: true,
        },
        message: __(
          "Prevents customers from signing up for multiple free trials of the same product. Helps prevent trial abuse.",
          "arraysubs",
        ),
      },
    ],
  },

  // Grace Period
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Grace Period", "arraysubs"),
        subText: __(
          "Configure grace periods for unpaid renewal invoices",
          "arraysubs",
        ),
      },
      {
        field: "AutoGrid",
        cols: 2,
        style: { maxWidth: "400px", gridTemplateColumns: "2fr 1fr" },
        children: [
          {
            field: "Number",
            name: "renewals.invoice_before_due_value",
            label: __("Generate Invoice Before Due", "arraysubs"),
            min: 1,
            max: 30,
          },
          {
            field: "Select",
            name: "renewals.invoice_before_due_unit",
            label: __("Unit", "arraysubs"),
            data: [
              { label: __("Hours", "arraysubs"), value: "hours" },
              { label: __("Days", "arraysubs"), value: "days" },
            ],
          },
        ],
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "How long before the payment due date to generate the renewal invoice. This gives customers time to see and pay. If set to a duration equal to or longer than the billing cycle, the invoice will be generated at least 6 hours before the due date.",
          "arraysubs",
        ),
      },
      {
        field: "Divider",
      },
      {
        field: "AutoGrid",
        cols: 2,
        children: [
          {
            field: "Number",
            name: "renewals.grace_days_before_on_hold",
            label: __("Days Active After Due", "arraysubs"),
            min: 0,
            max: 30,
          },
          {
            field: "Number",
            name: "renewals.grace_days_before_cancel",
            label: __("Days On-Hold Before Cancel", "arraysubs"),
            min: 1,
            max: 60,
          },
        ],
      },
      {
        field: "Alert",
        type: "warning",
        title: __("Grace Period Timeline", "arraysubs"),
        message: __(
          "Payment Due Date → Subscription stays ACTIVE (X days) → Moves to ON-HOLD (Y days) → CANCELLED. Customers retain access during ACTIVE period but not during ON-HOLD.",
          "arraysubs",
        ),
      },
    ],
  },

  // Renewal Sync
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Renewal Sync", "arraysubs"),
        subText: __(
          "Align new subscriptions to predictable billing-cycle dates",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "renewals.sync_to_billing_cycle",
        label: __("Sync Renewals to Next Billing Cycle", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When enabled, new non-trial subscriptions renew on the next cycle boundary: next day, next store week, first day of next month, or January 1 for yearly plans. Existing subscriptions are not changed.",
          "arraysubs",
        ),
      },
      {
        field: "Select",
        name: "renewals.sync_first_charge_mode",
        label: __("First Charge", "arraysubs"),
        data: [
          {
            value: "prorate",
            label: __("Prorate until the synced renewal date", "arraysubs"),
          },
          {
            value: "full",
            label: __("Charge the full recurring amount", "arraysubs"),
          },
        ],
        showWhen: {
          field: "renewals.sync_to_billing_cycle",
          operator: "==",
          value: true,
        },
      },
      {
        field: "Alert",
        type: "info",
        showWhen: {
          field: "renewals.sync_to_billing_cycle",
          operator: "==",
          value: true,
        },
        message: __(
          "Prorate charges only the remaining part of the current cycle at checkout. Full charges the regular recurring amount at signup. In both modes, future renewal invoices use the full recurring price on the synced date.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "renewals.sync_to_billing_cycle",
          operator: "==",
          value: true,
        },
        message: __(
          "Supported checkout gateways are manual/offline payment gateways and Stripe. Unsupported ArraySubs automatic gateways are hidden while a synced subscription is in the cart. Free trials and lifetime deals keep their normal schedule.",
          "arraysubs",
        ),
      },
    ],
  },

  // Email Reminder Schedule
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Email Reminder Schedule", "arraysubs"),
        subText: __(
          "Configure when reminder emails are sent to customers",
          "arraysubs",
        ),
      },
      {
        field: "AutoGrid",
        cols: 3,
        children: [
          {
            field: "Number",
            name: "emails.renewal_upcoming.days_before",
            label: __("Renewal Reminder (Days Before)", "arraysubs"),
            min: 1,
            max: 30,
          },
          {
            field: "Number",
            name: "emails.trial_ending.days_before",
            label: __("Trial Ending Reminder (Days Before)", "arraysubs"),
            min: 1,
            max: 30,
          },
          {
            field: "Number",
            name: "emails.expiring_soon.days_before",
            label: __("Expiring Soon Reminder (Days Before)", "arraysubs"),
            min: 1,
            max: 60,
          },
        ],
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "These settings control how many days before an event occurs the reminder email is sent. For example, setting 'Renewal Reminder' to 3 will send the email 3 days before the next payment is due.",
          "arraysubs",
        ),
      },
    ],
  },

  // Customer Actions
  {
    field: "Card",
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Customer Actions", "arraysubs"),
        subText: __(
          "Control which self-service actions customers can use from My Account",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Need to rename or reorder the Subscriptions tab? Use ArraySubs -> Profile Builder -> My Account. These settings control the action buttons inside the subscription portal.",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "customer_actions.allow_cancellation",
        label: __("Allow Cancellation", "arraysubs"),
      },
      {
        field: "Switch",
        name: "pause_subscription.customer_can_pause",
        label: __("Allow Suspension (Pause)", "arraysubs"),
      },
      {
        field: "Switch",
        name: "customer_actions.allow_reactivation",
        label: __("Allow Reactivation", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "Disabling an action hides the matching portal button for all customers and blocks the matching customer REST action.",
          "arraysubs",
        ),
      },
    ],
  },

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

  // Automatic Payments
  {
    field: "Card",
    requiresModule: AUTOMATIC_PAYMENTS_MODULE,
    children: [
      {
        field: "Title",
        heading: 3,
        text: __("Automatic Payments", "arraysubs"),
        subText: __(
          "Configure customer controls for automatic payment subscriptions",
          "arraysubs",
        ),
      },
      {
        field: "Switch",
        name: "automatic_payments.allow_auto_renew_toggle",
        label: __("Allow Customers to Turn Off Auto-Renew", "arraysubs"),
      },
      {
        field: "Alert",
        type: "info",
        message: __(
          "When enabled, customers with automatic payment subscriptions can turn off auto-renew from the customer portal. The subscription stays active, but the next renewal will generate a manual invoice instead of charging the payment method automatically.",
          "arraysubs",
        ),
      },
      {
        field: "Alert",
        type: "warning",
        showWhen: {
          field: "automatic_payments.allow_auto_renew_toggle",
          operator: "=",
          value: true,
        },
        message: __(
          "Customers who turn off auto-renew will receive manual renewal invoices by email. They can re-enable auto-renew at any time as long as a valid payment method is on file.",
          "arraysubs",
        ),
      },
    ],
  },
];

const GeneralSettings = () => {
  const [form] = Form.useForm();
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [formData, setFormData] = useState({});
  const { toasts, showToast, removeToast } = useToast();
  const visibleFormStructure = useMemo(
    () =>
      formStructure.filter(
        (item) => !item.requiresModule || hasLoadedModule(item.requiresModule),
      ),
    [],
  );

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

  const loadSettings = async () => {
    setLoading(true);
    try {
      const settings = await fetchSettings();
      const flatData = nestedToDot(settings);
      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={__("General", "arraysubs")}>
        <Skeleton variant="rectangle" width="100%" height={400} />
      </DefaultPageLayout>
    );
  }

  return (
    <DefaultPageLayout
      title={__("General", "arraysubs")}
      subtitle={__(
        "Renewals, checkout, and customer self-service settings",
        "arraysubs",
      )}
    >
      <Form form={form} onFinish={handleSubmit} layout="vertical">
        <FormBuilder formItems={visibleFormStructure} form={form} />

        <div className="arraysubs-settings-actions arraysubs-bottom-fixed-actions">
          <div>
            <SpinnerButton
              type="submit"
              className="button button-primary"
              loading={saving}
              loadingText={__("Saving...", "arraysubs")}
            >
              {__("Save Settings", "arraysubs")}
            </SpinnerButton>
            <button
              type="button"
              className="button"
              onClick={handleDiscard}
              disabled={saving}
            >
              {__("Discard Changes", "arraysubs")}
            </button>
          </div>
        </div>
      </Form>

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

export default GeneralSettings;
