import { __, sprintf } from "@wordpress/i18n";
import { createInterpolateElement } from "@wordpress/element";
import { EventDateTBCSetting } from "@/components/event/event-date-tbc-setting";
import { EventDateTimezoneSetting } from "@/components/event/event-date-timezone-setting";
import { ShortcodeBox } from "@/components/ShortcodeBox";
import { TimeInput } from "@/components/time-input";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Command, CommandGroup, CommandItem } from "@/components/ui/command";
import { FloatingDatePicker } from "@/components/ui/FloatingDatePicker";
import { Input } from "@/components/ui/input";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { useEventEditContext } from "@/hooks/EventEditContext";
import { useSettings } from "@/hooks/SettingsContext";
import {
  ensureUtcZ,
  getDateInTimezone,
  getOrderedWeekdays,
  recurrenceUntilWall,
} from "@/lib/date-utils";
import { cn } from "@/lib/utils";
import { CheckCheck, Copy, MoveRight, Plus, Trash2, X } from "lucide-react";
import { DateTime } from "luxon";
import { memo, useCallback, useState } from "react";
import { Link } from "react-router-dom";

const WEEKDAY_NAMES = [
  __("Sunday", "eventkoi-lite"),
  __("Monday", "eventkoi-lite"),
  __("Tuesday", "eventkoi-lite"),
  __("Wednesday", "eventkoi-lite"),
  __("Thursday", "eventkoi-lite"),
  __("Friday", "eventkoi-lite"),
  __("Saturday", "eventkoi-lite"),
];
const MONTHS = [
  __("January", "eventkoi-lite"),
  __("February", "eventkoi-lite"),
  __("March", "eventkoi-lite"),
  __("April", "eventkoi-lite"),
  __("May", "eventkoi-lite"),
  __("June", "eventkoi-lite"),
  __("July", "eventkoi-lite"),
  __("August", "eventkoi-lite"),
  __("September", "eventkoi-lite"),
  __("October", "eventkoi-lite"),
  __("November", "eventkoi-lite"),
  __("December", "eventkoi-lite"),
];
const ORDINALS = [
  __("first", "eventkoi-lite"),
  __("second", "eventkoi-lite"),
  __("third", "eventkoi-lite"),
  __("fourth", "eventkoi-lite"),
  __("fifth", "eventkoi-lite"),
];

function getOrdinal(date) {
  if (!(date instanceof Date) || isNaN(date)) return "";
  const dayOfMonth = date.getDate();
  const ordinalIndex = Math.ceil(dayOfMonth / 7);
  return (
    ORDINALS[ordinalIndex - 1] ||
    sprintf(
      /* translators: %d: ordinal number fallback, for example 6th. */
      __("%dth", "eventkoi-lite"),
      ordinalIndex
    )
  );
}

function normalizeJsDate(value) {
  if (!value) return null;
  if (value instanceof Date) {
    return isNaN(value) ? null : value;
  }

  const normalized = new Date(value);
  return isNaN(normalized) ? null : normalized;
}

function getJsWeekdayFromLuxon(dt) {
  if (!dt || !dt.isValid) return null;
  // Luxon weekday is Mon=1..Sun=7; JS weekday is Sun=0..Sat=6.
  return dt.weekday % 7;
}

const getEndAfterStartChange = (previousStart, previousEnd, newStart) => {
  const fallback = newStart.plus({ hours: 1 });

  if (
    !previousStart?.isValid ||
    !previousEnd?.isValid ||
    previousEnd <= previousStart
  ) {
    return fallback;
  }

  const duration = previousEnd.diff(previousStart);
  const durationMinutes = duration.as("minutes");
  const isGeneratedNineToFiveRange =
    previousStart.hasSame(previousEnd, "day") &&
    previousStart.hour === 9 &&
    previousStart.minute === 0 &&
    previousEnd.hour === 17 &&
    previousEnd.minute === 0;

  if (
    !Number.isFinite(durationMinutes) ||
    durationMinutes <= 0 ||
    isGeneratedNineToFiveRange
  ) {
    return fallback;
  }

  return newStart.plus(duration);
};

function getRecurringSummary(rule, wpTz) {
  const freqPlural = {
    day: "days",
    week: "weeks",
    month: "months",
    year: "years",
  };

  const WEEKDAY_NAMES = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
  ];

  const MONTHS = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];

  const ordinals = ["first", "second", "third", "fourth", "fifth"];

  // Frequency text
  let freqText;
  if (rule.every && rule.every > 1) {
    freqText = `Every ${rule.every} ${freqPlural[rule.frequency] || "custom"}`;
  } else {
    freqText =
      {
        day: "Daily",
        week: "Weekly",
        month: "Monthly",
        year: "Yearly",
      }[rule.frequency] || "Custom";
  }

  let details = "";

  // WEEKLY
  const weekDays = (() => {
    const raw = Array.isArray(rule.weekdays)
      ? rule.weekdays
          .map((value) => parseInt(value, 10))
          .filter((value) => Number.isInteger(value) && value >= 0 && value <= 6)
      : [];

    if (rule.frequency !== "week" || raw.length !== 1 || !rule.start_date) {
      return raw;
    }

    const startDay = getJsWeekdayFromLuxon(
      DateTime.fromISO(rule.start_date, { zone: "utc" }).setZone(wpTz)
    );

    return Number.isInteger(startDay) && startDay >= 0 && startDay <= 6
      ? [startDay]
      : raw;
  })();
  if (rule.frequency === "week" && weekDays.length) {
    const days = weekDays.map((i) => WEEKDAY_NAMES[i]).join(", ");
    details = `, on ${days}`;
  }

  // MONTHLY — weekday-of-month
  if (
    rule.frequency === "month" &&
    rule.month_day_rule === "weekday-of-month"
  ) {
    const startDate = DateTime.fromISO(rule.start_date, { zone: "utc" }).setZone(
      wpTz
    );
    const weekdayIndex = getJsWeekdayFromLuxon(startDate);
    const ordinal = startDate?.isValid ? Math.ceil(startDate.day / 7) : 1;
    const dayName = WEEKDAY_NAMES[weekdayIndex ?? 0];

    details = `, on the ${ordinals[ordinal - 1] || `${ordinal}th`} ${dayName}`;
  }

  // MONTHLY — day-of-month
  if (rule.frequency === "month" && rule.month_day_rule === "day-of-month") {
    details = `, on day ${
      DateTime.fromISO(rule.start_date, { zone: "utc" }).setZone(wpTz).day
    }`;
  }

  // YEARLY — months
  const months = Array.isArray(rule.months) ? rule.months : [];
  if (rule.frequency === "year" && months.length) {
    const monthNames = months.map((m) => MONTHS[m]).join(", ");
    details = `, in ${monthNames}`;
  }

  // END CONDITIONS
  let endText = "";
  if (rule.ends === "after") {
    endText = `, ${rule.ends_after} events`;
  } else if (rule.ends === "on") {
    const endsOn = recurrenceUntilWall(rule.ends_on, wpTz);
    endText = endsOn ? `, until ${endsOn.toFormat("d MMM yyyy")}` : "";
  } else {
    endText = ", forever";
  }

  return `${freqText}${details}${endText}.`;
}

export const EventDateRecurring = memo(function EventDateRecurring({
  showAttributes,
}) {
  const { event, setEvent } = useEventEditContext();
  const tbc = event?.tbc ?? false;
  const [copyingIndex, setCopyingIndex] = useState(null);
  const rules = event.recurrence_rules || [];
  const { settings } = useSettings();

  const wpTz =
    event?.timezone || window.eventkoi_params?.timezone_string || "UTC";

  const addRule = useCallback(() => {
    const now = new Date();
    now.setHours(9, 0, 0, 0);

    const end = new Date(now);
    end.setHours(17, 0, 0, 0);

    const defaultEnd = new Date();
    defaultEnd.setFullYear(defaultEnd.getFullYear() + 1);

    const rule = {
      // Stable React-key identifier (stripped server-side before persist).
      _uid: `rule_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
      start_date: DateTime.fromJSDate(now, { zone: wpTz })
        .setZone("utc")
        .toISO({ suppressMilliseconds: true }),
      end_date: null,
      all_day: false,
      every: 1,
      frequency: "day",
      working_days_only: false,
      ends: "after",
      ends_after: 30,
      ends_on: DateTime.fromJSDate(defaultEnd, { zone: wpTz })
        .startOf("day")
        .toUTC()
        .toISO({ suppressMilliseconds: true }),
      weekdays: [],
      months: [now.getMonth()],
      month_day_rule: "day-of-month",
      month_day_value: now.getDate(),
    };

    setEvent((prev) => ({
      ...prev,
      recurrence_rules: [...(prev.recurrence_rules || []), rule],
    }));
  }, [setEvent]);

  const updateRule = useCallback(
    (index, key, value) => {
      const updated = [...rules];
      const prevRule = { ...updated[index] };
      const rule = { ...prevRule, [key]: value };

      const isStartDateChange = key === "start_date";
      const date = DateTime.fromISO(
        isStartDateChange ? value : rule.start_date,
        { zone: "utc" }
      )
        .setZone(wpTz)
        .toJSDate();
      const isValidDate = date instanceof Date && !isNaN(date);

      if (key === "all_day" && value === true) {
        rule.end_date = null;
      }

      const isWeekly =
        key === "frequency" ? value === "week" : rule.frequency === "week";

      // ONLY auto-set if weekdays is still empty
      if (
        isValidDate &&
        isWeekly &&
        isStartDateChange &&
        (!rule.weekdays || rule.weekdays.length === 0)
      ) {
        const weekday = getJsWeekdayFromLuxon(
          DateTime.fromISO(isStartDateChange ? value : rule.start_date, {
            zone: "utc",
          }).setZone(wpTz)
        );
        if (weekday !== null) {
          rule.weekdays = [weekday];
        }
      }

      if (
        (key === "frequency" && value === "year") ||
        (isStartDateChange && rule.frequency === "year")
      ) {
        if (isValidDate) {
          rule.months = [date.getMonth()];
          rule.month_day_value = date.getDate();
        }
      }

      if (
        (key === "frequency" && value === "month") ||
        (isStartDateChange && rule.frequency === "month")
      ) {
        if (isValidDate) {
          rule.month_day_value = date.getDate();
        }
      }

      // preserve duration when start_date changes
      if (isStartDateChange && prevRule.end_date) {
        const prevStart = DateTime.fromISO(prevRule.start_date, {
          zone: "utc",
        });
        const prevEnd = DateTime.fromISO(prevRule.end_date, { zone: "utc" });
        if (prevStart.isValid && prevEnd.isValid) {
          const duration = prevEnd.diff(prevStart);
          const newStart = DateTime.fromISO(value, { zone: "utc" });
          if (newStart.isValid) {
            rule.end_date = newStart
              .plus(duration)
              .toUTC()
              .toISO({ suppressMilliseconds: true });
          }
        }
      }

      updated[index] = rule;
      setEvent((prev) => ({ ...prev, recurrence_rules: updated }));
    },
    [rules, setEvent]
  );

  const updateMultiple = useCallback(
    (index, updates) => {
      setEvent((prev) => {
        const updated = [...(prev.recurrence_rules || [])];
        const current = updated[index] || {};
        const next = { ...current, ...updates };

        const date = DateTime.fromISO(
          updates.start_date || current.start_date,
          { zone: "utc" }
        )
          .setZone(wpTz)
          .toJSDate();
        const isValidDate = date instanceof Date && !isNaN(date);

        if (
          isValidDate &&
          next.frequency === "week" &&
          "start_date" in updates
        ) {
          const weekday = getJsWeekdayFromLuxon(
            DateTime.fromISO(updates.start_date || current.start_date, {
              zone: "utc",
            }).setZone(wpTz)
          );
          if (weekday !== null) {
            next.weekdays = [weekday];
          }
        }

        // preserve duration if start_date changes
        if (updates.start_date && current.end_date) {
          const prevStart = DateTime.fromISO(current.start_date, {
            zone: "utc",
          });
          const prevEnd = DateTime.fromISO(current.end_date, { zone: "utc" });
          if (prevStart.isValid && prevEnd.isValid) {
            const duration = prevEnd.diff(prevStart);
            const newStart = DateTime.fromISO(updates.start_date, {
              zone: "utc",
            });
            if (newStart.isValid) {
              next.end_date = newStart
                .plus(duration)
                .toUTC()
                .toISO({ suppressMilliseconds: true });
            }
          }
        }

        updated[index] = next;
        return { ...prev, recurrence_rules: updated };
      });
    },
    [setEvent]
  );

  const deleteRule = useCallback(
    (index) => {
      const updated = [...rules];
      updated.splice(index, 1);
      setEvent((prev) => ({ ...prev, recurrence_rules: updated }));
    },
    [rules, setEvent]
  );

  const toggleItem = useCallback(
    (index, key, value) => {
      const list = rules[index][key] || [];
      const exists = list.includes(value);
      const updatedList = exists
        ? list.filter((v) => v !== value)
        : [...list, value];
      updateRule(index, key, updatedList);
    },
    [rules, updateRule]
  );

  return (
    <div className="flex flex-col gap-6">
      {rules.map((rule, index) => {
      const ruleKey = rule._uid
        || (rule.start_date ? `srv_${rule.start_date}_${rule.frequency || ""}_${rule.every || 1}` : `idx_${index}`);
      const start = normalizeJsDate(
        getDateInTimezone(ensureUtcZ(rule.start_date), wpTz)
      );
      const end = normalizeJsDate(
        getDateInTimezone(ensureUtcZ(rule.end_date), wpTz)
      );
      const endsOnWall = recurrenceUntilWall(rule.ends_on, wpTz);
      const endsOn = endsOnWall?.isValid
        ? endsOnWall.startOf("day").toJSDate()
        : null;
      const safeWeekdays = (() => {
        const raw = Array.isArray(rule.weekdays)
          ? rule.weekdays
              .map((value) => parseInt(value, 10))
              .filter(
                (value) => Number.isInteger(value) && value >= 0 && value <= 6
              )
          : [];

        if (rule.frequency !== "week" || raw.length !== 1 || !rule.start_date) {
          return raw;
        }

        const startDay = getJsWeekdayFromLuxon(
          DateTime.fromISO(rule.start_date, { zone: "utc" }).setZone(wpTz)
        );

        return Number.isInteger(startDay) && startDay >= 0 && startDay <= 6
          ? [startDay]
          : raw;
      })();
        const safeMonths = Array.isArray(rule.months) ? rule.months : [];

        return (
          <div key={ruleKey} className="border rounded-md p-4 space-y-6">
            <div className="flex flex-wrap items-center gap-2 md:gap-4">
              <FloatingDatePicker
                value={start}
                wpTz={wpTz}
                onChange={(pickedDate) => {
                  if (!pickedDate) return;

                  const prevWallStart = start
                    ? DateTime.fromJSDate(start, { zone: wpTz })
                    : DateTime.fromObject(
                        { hour: 9, minute: 0 },
                        { zone: wpTz }
                      );

                  const dtWallStart = pickedDate.set({
                    hour: prevWallStart.hour,
                    minute: prevWallStart.minute,
                    second: 0,
                    millisecond: 0,
                  });

                  const prevWallEnd = end
                    ? DateTime.fromJSDate(end, { zone: wpTz })
                    : null;
                  const newWallEnd = !rule.all_day
                    ? getEndAfterStartChange(
                        prevWallStart,
                        prevWallEnd,
                        dtWallStart
                      )
                    : null;
                  const endUTC = newWallEnd
                    ? newWallEnd.toUTC().toISO({ suppressMilliseconds: true })
                    : null;

                  const startUTC = dtWallStart
                    .toUTC()
                    .toISO({ suppressMilliseconds: true });

                  updateMultiple(index, {
                    start_date: startUTC,
                    ...(endUTC && { end_date: endUTC }),
                  });
                }}
                className={cn(
                  "disabled:bg-muted disabled:text-muted-foreground/40 disabled:cursor-not-allowed disabled:opacity-100"
                )}
                disabled={tbc}
              />

              {!rule.all_day && (
                <>
                  <TimeInput
                    date={start}
                    wpTz={wpTz}
                    commitOnValidChange
                    setDate={(utcDate) => {
                      if (!utcDate) return;

                      const newWallStart = DateTime.fromJSDate(utcDate, {
                        zone: "utc",
                      }).setZone(wpTz);
                      const prevWallStart = start
                        ? DateTime.fromJSDate(start, { zone: "utc" }).setZone(
                            wpTz
                          )
                        : null;
                      const prevWallEnd = end
                        ? DateTime.fromJSDate(end, { zone: "utc" }).setZone(
                            wpTz
                          )
                        : null;

                      let updates = {
                        start_date: newWallStart
                          .toUTC()
                          .toISO({ suppressMilliseconds: true }),
                      };

                      const newWallEnd = getEndAfterStartChange(
                        prevWallStart,
                        prevWallEnd,
                        newWallStart
                      );
                      updates.end_date = newWallEnd
                        .toUTC()
                        .toISO({ suppressMilliseconds: true });

                      updateMultiple(index, updates);
                    }}
                    disabled={tbc}
                  />

                  <MoveRight
                    className="w-6 h-6 text-muted-foreground"
                    strokeWidth={1.5}
                  />

                  <TimeInput
                    date={end}
                    wpTz={wpTz}
                    setDate={(jsDate) => {
                      if (!jsDate) return;

                      // take rule.start_date as the base calendar day
                      const base = DateTime.fromISO(rules[index].start_date, {
                        zone: "utc",
                      }).setZone(wpTz);

                      // take only the hour/minute from the picked time
                      const picked = DateTime.fromJSDate(jsDate, {
                        zone: wpTz,
                      });

                      const combined = base.set({
                        hour: picked.hour,
                        minute: picked.minute,
                        second: 0,
                        millisecond: 0,
                      });

                      const endISO = combined
                        .toUTC()
                        .toISO({ suppressMilliseconds: true });

                      updateMultiple(index, { end_date: endISO });
                    }}
                    disabled={tbc}
                  />
                </>
              )}

              <div className="flex items-center gap-2">
                <Switch
                  aria-label={__("All day", "eventkoi-lite")}
                  checked={rule.all_day}
                  onCheckedChange={(val) => updateRule(index, "all_day", val)}
                  disabled={tbc}
                />
                <span className="text-sm text-muted-foreground">{__("All day", "eventkoi-lite")}</span>
              </div>

              <Button
                type="button"
                size="icon"
                variant="ghost"
                onClick={() => deleteRule(index)}
                className="h-7 w-7 ml-auto p-0"
                aria-label={__("Delete rule", "eventkoi-lite")}
              >
                <Trash2 className="h-4 w-4 text-muted-foreground" aria-hidden="true" />
              </Button>
            </div>
            {showAttributes && (
              <ShortcodeBox
                attribute={`event_datetime_${index + 1}`}
                data={`datetime_${index + 1}`}
                eventId={event?.id}
              />
            )}
            <div className="flex items-center gap-2">
              <span className="text-sm font-medium text-foreground">
                {__("Repeats every", "eventkoi-lite")}
              </span>
              <Input
                type="number"
                min={1}
                value={rule.every}
                onChange={(e) =>
                  updateRule(index, "every", parseInt(e.target.value))
                }
                className="w-16 h-9"
              />
              <Select
                value={rule.frequency}
                onValueChange={(val) => updateRule(index, "frequency", val)}
              >
                <SelectTrigger className="w-[100px] h-9">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="day">{__("Day", "eventkoi-lite")}</SelectItem>
                  <SelectItem value="week">{__("Week", "eventkoi-lite")}</SelectItem>
                  <SelectItem value="month">{__("Month", "eventkoi-lite")}</SelectItem>
                  <SelectItem value="year">{__("Year", "eventkoi-lite")}</SelectItem>
                </SelectContent>
              </Select>
            </div>

            {rule.frequency === "day" && (
              <div className="flex items-center gap-2">
                <Checkbox
                  checked={rule.working_days_only}
                  onCheckedChange={(val) =>
                    updateRule(index, "working_days_only", val)
                  }
                  id={`working-days-${index}`}
                />
                <label
                  htmlFor={`working-days-${index}`}
                  className="text-sm text-muted-foreground"
                >
                  {createInterpolateElement(
                    __("Only count <link>working days</link>.", "eventkoi-lite"),
                    {
                      link: (
                        <Link
                          to="/settings"
                          className="underline text-muted-foreground hover:text-primary/80"
                          onClick={(e) => e.stopPropagation()}
                        />
                      ),
                    }
                  )}
                </label>
              </div>
            )}
            {rule.frequency === "week" && (
              <div className="flex items-center gap-2 flex-wrap">
                <span className="text-sm font-medium text-foreground">{__("On", "eventkoi-lite")}</span>

                {getOrderedWeekdays(
                  parseInt(settings?.week_starts_on ?? "0", 10)
                ).map(({ key, short }) => (
                  <Button
                    key={key}
                    type="button"
                    size="sm"
                    variant={
                      safeWeekdays.includes(key) ? "default" : "secondary"
                    }
                    className={cn(
                      "rounded-full w-8 h-8 p-0 transition-none",
                      safeWeekdays.includes(key)
                        ? "bg-foreground"
                        : "bg-secondary border border-input"
                    )}
                    onClick={() => toggleItem(index, "weekdays", key)}
                  >
                    {short}
                  </Button>
                ))}
              </div>
            )}
            {rule.frequency === "month" && (
              <div className="flex items-center gap-2">
                <span className="text-sm font-medium text-foreground">{__("On", "eventkoi-lite")}</span>
                <Select
                  value={rule.month_day_rule}
                  onValueChange={(val) =>
                    updateRule(index, "month_day_rule", val)
                  }
                >
                  <SelectTrigger className="w-[220px] h-9">
                    <SelectValue placeholder={__("Pick rule", "eventkoi-lite")} />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="day-of-month">
                      {sprintf(
                        /* translators: %s: day of the month. */
                        __("day %s", "eventkoi-lite"),
                        start ? start.getDate() : ""
                      )}
                    </SelectItem>
                    <SelectItem value="weekday-of-month">
                      {sprintf(
                        /* translators: 1: ordinal week in month, 2: weekday name. */
                        __("the %1$s %2$s", "eventkoi-lite"),
                        getOrdinal(start),
                        WEEKDAY_NAMES[
                          getJsWeekdayFromLuxon(
                            DateTime.fromISO(rule.start_date, { zone: "utc" }).setZone(
                              wpTz
                            )
                          ) ?? 0
                        ]
                      )}
                    </SelectItem>
                  </SelectContent>
                </Select>
              </div>
            )}
            {rule.frequency === "year" && (
              <div className="space-y-6">
                {/* In: Month selector */}
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-foreground">
                    {__("In", "eventkoi-lite")}
                  </span>
                  <Popover>
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        className={cn(
                          "min-w-[260px] w-full px-2 h-9 justify-start items-center overflow-x-auto whitespace-nowrap",
                          "scrollbar-hide appearance-none",
                          "hover:bg-transparent hover:text-foreground"
                        )}
                      >
                        {safeMonths.length === 0 ? (
                          <span className="text-muted-foreground">
                            {__("Select months", "eventkoi-lite")}
                          </span>
                        ) : (
                          <div className="flex gap-1.5 items-center">
                            {[...safeMonths]
                              .sort((a, b) => a - b)
                              .map((i) => (
                                <div
                                  key={i}
                                  className="flex items-center px-2 py-0.5 text-sm rounded-sm bg-[#eeeeee] text-foreground"
                                >
                                  {MONTHS[i]}
                                  <span
                                    role="button"
                                    tabIndex={0}
                                    aria-label={sprintf(__("Remove %s", "eventkoi-lite"), MONTHS[i])}
                                    onClick={(e) => {
                                      e.stopPropagation();
                                      toggleItem(index, "months", i);
                                    }}
                                    onKeyDown={(e) => {
                                      if (e.key === "Enter" || e.key === " ") {
                                        e.preventDefault();
                                        e.stopPropagation();
                                        toggleItem(index, "months", i);
                                      }
                                    }}
                                    className="ml-1 hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring rounded-sm"
                                  >
                                    <X className="h-3 w-3" aria-hidden="true" />
                                  </span>
                                </div>
                              ))}
                          </div>
                        )}
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent align="start" className="w-[260px] p-0">
                      <Command>
                        <CommandGroup>
                          {MONTHS.map((month, i) => {
                            const selected = safeMonths.includes(i);
                            return (
                              <CommandItem
                                key={i}
                                value={month}
                                onSelect={() => toggleItem(index, "months", i)}
                                className={cn("cursor-pointer px-3 py-2")}
                              >
                                <span className="flex-1">{month}</span>
                                {selected && <span>✓</span>}
                              </CommandItem>
                            );
                          })}
                        </CommandGroup>
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>

                {/* On: Day rule selector */}
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-foreground">
                    {__("On", "eventkoi-lite")}
                  </span>
                  <Select
                    value={rule.month_day_rule}
                    onValueChange={(val) =>
                      updateRule(index, "month_day_rule", val)
                    }
                  >
                    <SelectTrigger className="w-[220px] h-9">
                      <SelectValue placeholder={__("Pick rule", "eventkoi-lite")} />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="day-of-month">
                        {sprintf(
                          /* translators: %s: day of the month. */
                          __("day %s", "eventkoi-lite"),
                          start ? start.getDate() : ""
                        )}
                      </SelectItem>
                      <SelectItem value="weekday-of-month">
                        {sprintf(
                          /* translators: 1: ordinal week in month, 2: weekday name. */
                          __("the %1$s %2$s", "eventkoi-lite"),
                          getOrdinal(start),
                          WEEKDAY_NAMES[
                            getJsWeekdayFromLuxon(
                              DateTime.fromISO(rule.start_date, { zone: "utc" }).setZone(
                                wpTz
                              )
                            ) ?? 0
                          ]
                        )}
                      </SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>
            )}
            <div className="flex items-center gap-2">
              <span className="text-sm font-medium text-foreground">{__("Ends", "eventkoi-lite")}</span>
              <Select
                value={rule.ends}
                onValueChange={(val) => updateRule(index, "ends", val)}
              >
                <SelectTrigger className="w-[100px] h-9">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="never">{__("Never", "eventkoi-lite")}</SelectItem>
                  <SelectItem value="after">{__("After", "eventkoi-lite")}</SelectItem>
                  <SelectItem value="on">{__("On", "eventkoi-lite")}</SelectItem>
                </SelectContent>
              </Select>

              {rule.ends === "after" && (
                <>
                  <Input
                    type="number"
                    min={1}
                    value={rule.ends_after}
                    onChange={(e) =>
                      updateRule(index, "ends_after", parseInt(e.target.value))
                    }
                    className="w-20 h-9"
                  />
                  <span className="text-sm text-muted-foreground">{__("events", "eventkoi-lite")}</span>
                </>
              )}

              {rule.ends === "on" && (
                <FloatingDatePicker
                  value={endsOn}
                  wpTz={wpTz}
                  onChange={(dt) => {
                    if (!dt) return;

                    const utc = dt
                      .startOf("day")
                      .toUTC()
                      .toISO({ suppressMilliseconds: true });

                    if (utc) {
                      updateRule(index, "ends_on", utc);
                    }
                  }}
                />
              )}
            </div>
            <div className="space-y-1">
              <label className="text-sm font-medium text-foreground">
                {__("Recurring rule summary", "eventkoi-lite")}
              </label>

              <div className="relative max-w-[450px]">
                <Input
                  type="text"
                  readOnly
                  value={getRecurringSummary(rule, wpTz)}
                  className="w-full text-sm pr-[100px]"
                />
                <Button
                  variant="secondary"
                  type="button"
                  className="absolute h-8 px-2 right-[5px] top-[4px] border-none cursor-pointer hover:bg-input text-sm"
                  onClick={() => {
                    setCopyingIndex(index); // See below hook
                    navigator.clipboard.writeText(
                      getRecurringSummary(rule, wpTz)
                    );
                    setTimeout(() => setCopyingIndex(null), 1200);
                  }}
                >
                  {copyingIndex === index ? (
                    <CheckCheck className="mr-2 h-4 w-4" />
                  ) : (
                    <Copy className="mr-2 h-4 w-4" />
                  )}
                  {copyingIndex === index ? __("Copied!", "eventkoi-lite") : __("Copy", "eventkoi-lite")}
                </Button>
              </div>
            </div>
            {showAttributes && (
              <ShortcodeBox
                attribute={`event_rulesummary_${index + 1}`}
                data={`rulesummary_${index + 1}`}
                eventId={event?.id}
              />
            )}
          </div>
        );
      })}

      <div>
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={addRule}
          className="w-auto justify-start text-sm"
        >
          <Plus className="w-4 h-4 mr-2" />
          {__("Add recurring rule", "eventkoi-lite")}
        </Button>
      </div>

      <EventDateTBCSetting event={event} setEvent={setEvent} />
      <EventDateTimezoneSetting event={event} setEvent={setEvent} />
    </div>
  );
});
