"use client";

/**
 * The two greeting sentences an event may override (design D9, D11).
 *
 * English only. Bangla stays wedding-wide, so this section deliberately shows two boxes
 * rather than four — the stored map is still keyed by locale, so adding Bangla later is a
 * change here and not a migration.
 *
 * The boxes open showing the wording a guest would otherwise read, as real editable text.
 * That is what makes "store on difference" necessary: if a prefilled box were saved verbatim
 * every time, an event would override the wedding-wide panel the first time anyone pressed
 * Save, and the panel would quietly stop meaning anything.
 */

const MAX = 100;

export type MessageValues = { single: string; family: string };

export type LocaleMessages = Record<string, Record<string, string>>;

/** Mirrors `DEFAULTS` in `api/app/services/greeting.py`; the server is still the authority. */
const BUILT_IN: MessageValues = {
  single: "You are cordially invited",
  family: "You and your family are cordially invited",
};

/**
 * What an event reads when it stores nothing of its own: the wedding-wide wording, or the
 * built-in default. The same fallback the API applies, computed here only so the boxes can
 * show it — nothing is decided on this value.
 */
export function inheritedMessages(wedding: LocaleMessages | null | undefined): MessageValues {
  const en = wedding?.en ?? {};
  return {
    single: en.single?.trim() || BUILT_IN.single,
    family: en.family?.trim() || BUILT_IN.family,
  };
}

/** What the event's own boxes should show: its override if it has one, else what it inherits. */
export function seedMessages(
  event: LocaleMessages | null | undefined,
  inherited: MessageValues,
): MessageValues {
  const en = event?.en ?? {};
  return {
    single: en.single?.trim() || inherited.single,
    family: en.family?.trim() || inherited.family,
  };
}

/**
 * The map to store, given what is in the boxes and what they inherited (design D11).
 *
 * A box left at the value it inherited stores nothing, so the event keeps following the
 * wedding-wide panel — including when that panel changes later. An emptied box also stores
 * nothing, which is how an existing override is cleared.
 */
export function messagesPayload(
  values: MessageValues,
  inherited: MessageValues,
): LocaleMessages {
  const en: Record<string, string> = {};
  for (const key of ["single", "family"] as const) {
    const value = values[key].trim();
    if (!value || value === inherited[key].trim()) continue;
    en[key] = value;
  }
  return Object.keys(en).length > 0 ? { en } : {};
}

export function isOverLimit(values: MessageValues): boolean {
  return values.single.length > MAX || values.family.length > MAX;
}

const FIELDS: { key: keyof MessageValues; label: string }[] = [
  { key: "single", label: "Single guest" },
  { key: "family", label: "Family / multiple guests" },
];

export default function EventMessages({
  values,
  inherited,
  canEdit,
  onChange,
}: {
  values: MessageValues;
  inherited: MessageValues;
  canEdit: boolean;
  onChange: (values: MessageValues) => void;
}) {
  return (
    <div>
      <p className="mb-3 text-xs text-stone-500">
        The sentence under the guest&apos;s name on this event&apos;s invitation. Each is
        limited to {MAX} characters — the greeting sits above the card artwork, and a
        paragraph there crowds the design it is meant to introduce. Leave one as it is to keep
        following the wedding-wide wording.
      </p>

      <div className="grid gap-4 sm:grid-cols-2">
        {FIELDS.map(({ key, label }) => {
          const value = values[key];
          const over = value.length > MAX;
          const overridden = value.trim() !== inherited[key].trim() && value.trim() !== "";
          return (
            <div key={key}>
              <label
                htmlFor={`event-msg-${key}`}
                className="mb-1 flex items-baseline justify-between text-xs font-medium text-stone-600"
              >
                <span>
                  {label}
                  {overridden && (
                    <span className="ml-1 font-normal text-stone-400">— overridden</span>
                  )}
                </span>
                <span className={over ? "font-semibold text-red-700" : "text-stone-400"}>
                  {value.length}/{MAX}
                </span>
              </label>
              <textarea
                id={`event-msg-${key}`}
                rows={2}
                disabled={!canEdit}
                value={value}
                onChange={(e) => onChange({ ...values, [key]: e.target.value })}
                // No maxLength: truncating as they type hides that they went over. The
                // counter turning red says it, and the API says it again on save.
                className={
                  over
                    ? "block w-full rounded-md border border-red-400 px-3 py-2 text-sm"
                    : "block w-full rounded-md border border-stone-300 px-3 py-2 text-sm"
                }
              />
            </div>
          );
        })}
      </div>
    </div>
  );
}
