/**
 * Schedule start page -- search form for route-based schedule search.
 *
 * No API calls on load. Pure form that navigates to the appropriate
 * search route on submit.
 *
 * @module
 */

import { type FC, useState, useCallback, useEffect, useRef, type FormEvent } from "react";
import { useNavigate } from "@modern-js/runtime/router";
import { useLocale } from "@/i18n/useLocale.js";
import { Calendar } from "primereact/calendar";
import { Slider, type SliderChangeEvent } from "primereact/slider";
import { useTranslation } from "@/i18n/provider.js";
import { PageLayout } from "@/ui/layout/PageLayout.js";
import { PageTabs } from "@/ui/layout/PageTabs.js";
import { SearchHistory } from "@/ui/layout/SearchHistory.js";
import { CityAutocomplete } from "@/ui/city-autocomplete/index.js";
import { PopularRequestsPanel } from "@/features/popular-requests/components/PopularRequestsPanel.js";
import type { PopularRequest } from "@/features/popular-requests/types.js";
import { SCHEDULE_PREFILL_SLOT } from "@/features/online-board/components/OnlineBoardStartPage.js";
import { readAndClearTransientPrefill } from "@/shared/state/transientPrefill.js";
import {
  getScheduleFilter,
  getBoardFilter,
  setScheduleFilter,
  projectBoardToSchedule,
} from "@/shared/state/crossSectionNavigation.js";
import {
  useDictionaries,
  getCityCodeByAirportCode,
} from "@/shared/dictionaries/index.js";
import type { IDictionaries } from "@/shared/dictionaries/index.js";
import { useGeoCityDefault } from "@/shared/hooks/useGeoCityDefault.js";
import { buildScheduleUrl } from "../url.js";
import { scheduleWindowBounds } from "@/shared/dateWindow.js";
import { formatScheduleDateRangeWithCurrentWeek } from "../dateLabels.js";
import "./ScheduleStartPage.scss";

function toCityCode(code: string, dictionaries: IDictionaries | null): string {
  if (!dictionaries) return code;
  return getCityCodeByAirportCode(dictionaries, code) ?? code;
}

function minutesToTime(minutes: number): string {
  const h = Math.floor(minutes / 60);
  const m = minutes % 60;
  return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
}

function dateToYyyymmdd(value: Date): string {
  const y = value.getFullYear().toString();
  const m = (value.getMonth() + 1).toString().padStart(2, "0");
  const d = value.getDate().toString().padStart(2, "0");
  return `${y}${m}${d}`;
}

function addDays(base: Date, days: number): Date {
  const result = new Date(base);
  result.setDate(result.getDate() + days);
  return result;
}

function yyyymmddToDate(yyyymmdd: string): Date {
  const y = parseInt(yyyymmdd.slice(0, 4), 10);
  const m = parseInt(yyyymmdd.slice(4, 6), 10) - 1;
  const d = parseInt(yyyymmdd.slice(6, 8), 10);
  return new Date(y, m, d);
}

/**
 * Returns Mon–Sun bounds of the ISO week containing `base` (or today),
 * clamped to today − 1 on the `from` end so the range is always inside
 * Schedule's [−1, +330] date window. TZ §4.1.5 says "показать расписание
 * на = текущая неделя"; when today falls mid-week the unclamped Monday
 * would be past the window's lower edge and the route guard would redirect
 * the search back to the start page.
 */
function currentWeekBounds(base = new Date()): { from: Date; to: Date } {
  const d = new Date(base);
  d.setHours(0, 0, 0, 0);
  // ISO week starts Monday (day 1); Sunday is day 0 → treat as 7.
  const dow = d.getDay() === 0 ? 7 : d.getDay();
  const mon = new Date(d);
  mon.setDate(d.getDate() - (dow - 1));
  const sun = new Date(mon);
  sun.setDate(mon.getDate() + 6);
  const minFrom = new Date(d);
  minFrom.setDate(d.getDate() - 1);
  const from = mon.getTime() < minFrom.getTime() ? minFrom : mon;
  return { from, to: sun };
}

/**
 * Returns Mon–Sun bounds of the week *after* the ISO week containing `base`.
 * TZ §4.1.5: "дата обратного рейса = следующая неделя".
 *
 * Derived from the raw Monday of `base`'s ISO week (not the clamped
 * `currentWeekBounds().from`) so the return-leg always starts on the true
 * next Monday regardless of how mid-week `base` is.
 */
function nextWeekBounds(base = new Date()): { from: Date; to: Date } {
  const d = new Date(base);
  d.setHours(0, 0, 0, 0);
  const dow = d.getDay() === 0 ? 7 : d.getDay();
  const thisMon = new Date(d);
  thisMon.setDate(d.getDate() - (dow - 1));
  const nextMon = new Date(thisMon);
  nextMon.setDate(thisMon.getDate() + 7);
  const nextSun = new Date(nextMon);
  nextSun.setDate(nextMon.getDate() + 6);
  return { from: nextMon, to: nextSun };
}

// Mirrors Angular AppSettings.scheduleSearchFrom (1 day back) and
// scheduleSearchTo (330 days forward). Constrains both the outbound and
// return-flight calendar pickers on the Schedule start page.
/**
 * Snap a date to the Mon-Sun week containing it. Angular parity:
 * the schedule list is week-granular (TZ §4.1.9.4) — a single click
 * on any day in the picker commits the whole week.
 */
function snapToWeek(date: Date): { from: Date; to: Date } {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  const dow = d.getDay() === 0 ? 7 : d.getDay();
  const mon = new Date(d);
  mon.setDate(d.getDate() - (dow - 1));
  const sun = new Date(mon);
  sun.setDate(mon.getDate() + 6);
  return { from: mon, to: sun };
}

function getScheduleMinDate(): Date {
  return scheduleWindowBounds()[0];
}

function getScheduleMaxDate(): Date {
  return scheduleWindowBounds()[1];
}

/**
 * Transient prefill state handed from a popular-request click via
 * sessionStorage. Mirrors Angular's `ScheduleFiltersStateService`
 * cross-page singleton: URL stays clean of query strings while the
 * form seeds from the click. Read-and-cleared on mount, so reload
 * gives a pristine form (matching Angular).
 */
export interface SchedulePrefillState {
  departure?: string;
  arrival?: string;
  withReturn?: boolean;
  /**
   * Outbound date range (yyyyMMdd). TZ §4.1.5: popular-request one-way
   * click prefills the current ISO week (Mon–Sun).
   */
  dateFrom?: string;
  dateTo?: string;
  /**
   * Return date range (yyyyMMdd). TZ §4.1.5: popular-request round-trip
   * click prefills the *next* ISO week.
   */
  returnDateFrom?: string;
  returnDateTo?: string;
}

export const ScheduleStartPage: FC = () => {
  const navigate = useNavigate();
  const { t } = useTranslation();
  const { locale, language } = useLocale();
  const { dictionaries } = useDictionaries(language);

  // One-shot read of any prefill the previous page wrote.
  // Falls back to cross-section store projection (Board → Schedule) per
  // TZ §4.1.8 Table 10 when no transient prefill is present.
  const [prefill] = useState<SchedulePrefillState>(() => {
    const transient = readAndClearTransientPrefill<SchedulePrefillState>(
      SCHEDULE_PREFILL_SLOT,
    );
    if (transient) return transient;

    // TZ §4.1.8: try own snapshot first, then project from Board.
    const schedSnap = getScheduleFilter();
    if (schedSnap) {
      return {
        ...(schedSnap.departure ? { departure: schedSnap.departure } : {}),
        ...(schedSnap.arrival ? { arrival: schedSnap.arrival } : {}),
        withReturn: schedSnap.showReturn,
      };
    }
    const boardSnap = getBoardFilter();
    if (boardSnap) {
      const projected = projectBoardToSchedule(boardSnap);
      return {
        ...(projected.departure ? { departure: projected.departure } : {}),
        ...(projected.arrival ? { arrival: projected.arrival } : {}),
        withReturn: false,
      };
    }
    return {};
  });

  const today = new Date();

  // State is the IATA city code (string). The shared CityAutocomplete
  // resolves the code to a localized display name internally — same
  // component used on OnlineBoard and FlightsMap, so the clear (×)
  // button, regional picker, and airport→city resolution come for free.
  const [departureCode, setDepartureCode] = useState<string>(prefill.departure ?? "");
  const [arrivalCode, setArrivalCode] = useState<string>(prefill.arrival ?? "");

  // TZ §4.1.1-R8: on first session entry with geo consent, auto-fill
  // departure city with the user's nearest city when:
  //   - no stored schedule filter is present (fresh session), AND
  //   - the current departure is empty (not populated by prefill or user).
  useGeoCityDefault({
    dictionaries,
    shouldApply: () => !getScheduleFilter() && !departureCode,
    onCity: (cityCode) => {
      setDepartureCode((prev) => (prev ? prev : cityCode));
    },
  });

  // TZ §4.1.5: popular-request click provides dateFrom/dateTo (current week)
  // and, for round-trips, returnDateFrom/returnDateTo (next week). When
  // absent (manual form visit) the fields start blank — submit handler
  // then defaults to current-week range (Angular's "by default current week").
  const [dateFrom, setDateFrom] = useState<Date | null>(
    prefill.dateFrom ? yyyymmddToDate(prefill.dateFrom) : null,
  );
  const [dateTo, setDateTo] = useState<Date | null>(
    prefill.dateTo ? yyyymmddToDate(prefill.dateTo) : null,
  );
  const [timeRange, setTimeRange] = useState<[number, number]>([0, 1440]);
  const [directOnly, setDirectOnly] = useState(false);
  const [isRoundTrip, setIsRoundTrip] = useState(prefill.withReturn === true);
  const [returnDateFrom, setReturnDateFrom] = useState<Date | null>(
    prefill.returnDateFrom ? yyyymmddToDate(prefill.returnDateFrom) : null,
  );
  const [returnDateTo, setReturnDateTo] = useState<Date | null>(
    prefill.returnDateTo ? yyyymmddToDate(prefill.returnDateTo) : null,
  );
  const [returnTimeRange, setReturnTimeRange] = useState<[number, number]>([0, 1440]);

  const scheduleMinDate = useRef(getScheduleMinDate()).current;
  const scheduleMaxDate = useRef(getScheduleMaxDate()).current;

  // TZ §4.1.9 Table 14 / Angular CalendarInputWeekComponent: when the
  // selected date range contains today, the Calendar input shows
  // "Текущая неделя" instead of the formatted dd.MM.yyyy-dd.MM.yyyy.
  // PrimeReact's Calendar always re-renders its own formatted value into
  // the input, so we override the .value via inputRef after each update.
  const dateRangeInputRef = useRef<HTMLInputElement>(null);
  const returnDateRangeInputRef = useRef<HTMLInputElement>(null);
  // Refs to the PrimeReact Calendar instances so we can call hide()
  // after a single-click commits the snap-to-week selection (Angular
  // closes its picker on selection — TZ §4.1.9.4).
  const outboundCalendarRef = useRef<Calendar | null>(null);
  const returnCalendarRef = useRef<Calendar | null>(null);

  const onOutboundDateSelect = useCallback(
    (e: { value: unknown }): void => {
      const v = e.value;
      if (!v) return;
      const picked = Array.isArray(v) ? (v[0] ?? v[1]) : v;
      if (!(picked instanceof Date)) return;
      const { from, to } = snapToWeek(picked);
      setDateFrom(from);
      setDateTo(to);
      outboundCalendarRef.current?.hide();
    },
    [],
  );

  const onReturnDateSelect = useCallback(
    (e: { value: unknown }): void => {
      const v = e.value;
      if (!v) return;
      const picked = Array.isArray(v) ? (v[0] ?? v[1]) : v;
      if (!(picked instanceof Date)) return;
      const { from, to } = snapToWeek(picked);
      setReturnDateFrom(from);
      setReturnDateTo(to);
      returnCalendarRef.current?.hide();
    },
    [],
  );

  useEffect(() => {
    if (!dateRangeInputRef.current || !dateFrom || !dateTo) return;
    const label = formatScheduleDateRangeWithCurrentWeek(dateFrom, dateTo, t);
    if (label === t("SCHEDULE.CURRENT-WEEK")) {
      dateRangeInputRef.current.value = label;
    }
  }, [dateFrom, dateTo, t]);
  useEffect(() => {
    if (!returnDateRangeInputRef.current || !returnDateFrom || !returnDateTo) return;
    const label = formatScheduleDateRangeWithCurrentWeek(returnDateFrom, returnDateTo, t);
    if (label === t("SCHEDULE.CURRENT-WEEK")) {
      returnDateRangeInputRef.current.value = label;
    }
  }, [returnDateFrom, returnDateTo, t]);

  // Same-cities validation mirrors ScheduleFilter (Angular's
  // ScheduleFilterValidationService): reject departure === arrival with
  // the shared translation key.
  const [sameCitiesError, setSameCitiesError] = useState<string | null>(null);

  const handleSubmit = useCallback(
    (e: FormEvent) => {
      e.preventDefault();

      const dep = departureCode.trim().toUpperCase();
      const arr = arrivalCode.trim().toUpperCase();
      if (!dep || !arr) return;

      if (dep === arr) {
        setSameCitiesError("SHARED.ARRIVAL-EQUALS-DEPARTURE-ERROR");
        return;
      }
      setSameCitiesError(null);

      // Empty dates default to the current week (today → today + 7) so
      // the search proceeds even when the user leaves the placeholder
      // untouched. Mirrors Angular's "by default it's the current week"
      // hint copy on the start page.
      const effectiveDateFrom = dateFrom ?? today;
      const effectiveDateTo = dateTo ?? addDays(today, 7);
      const dateFromParam = dateToYyyymmdd(effectiveDateFrom);
      const dateToParam = dateToYyyymmdd(effectiveDateTo);

      let url: string;

      const outbound: { departure: string; arrival: string; dateFrom: string; dateTo: string; timeFrom?: string; timeTo?: string } = {
        departure: dep, arrival: arr, dateFrom: dateFromParam, dateTo: dateToParam,
      };
      if (timeRange[0] > 0) outbound.timeFrom = minutesToTime(timeRange[0]).replace(":", "");
      if (timeRange[1] < 1440) outbound.timeTo = minutesToTime(timeRange[1]).replace(":", "");

      if (isRoundTrip) {
        const effectiveReturnFrom = returnDateFrom ?? addDays(today, 7);
        const effectiveReturnTo = returnDateTo ?? addDays(today, 14);
        const retDateFromParam = dateToYyyymmdd(effectiveReturnFrom);
        const retDateToParam = dateToYyyymmdd(effectiveReturnTo);

        const inbound: { departure: string; arrival: string; dateFrom: string; dateTo: string; timeFrom?: string; timeTo?: string } = {
          departure: arr, arrival: dep, dateFrom: retDateFromParam, dateTo: retDateToParam,
        };
        if (returnTimeRange[0] > 0) inbound.timeFrom = minutesToTime(returnTimeRange[0]).replace(":", "");
        if (returnTimeRange[1] < 1440) inbound.timeTo = minutesToTime(returnTimeRange[1]).replace(":", "");

        url = buildScheduleUrl({
          type: "roundtrip",
          outbound,
          inbound,
        });
      } else {
        url = buildScheduleUrl({
          type: "route",
          outbound,
        });
      }

      // TZ §4.1.8: persist filter snapshot for cross-section hydration.
      setScheduleFilter({
        mode: "route",
        departure: dep,
        arrival: arr,
        dateFrom: dateFromParam,
        dateTo: dateToParam,
        timeFrom: outbound.timeFrom ?? "0000",
        timeTo: outbound.timeTo ?? "2400",
        onlyDirect: directOnly,
        showReturn: isRoundTrip,
        searchExecuted: true,
      });

      void navigate(`/${locale}/${url}`);
    },
    [departureCode, arrivalCode, dateFrom, dateTo, timeRange, directOnly, isRoundTrip, returnDateFrom, returnDateTo, returnTimeRange, navigate, locale],
  );

  const handlePopularRequestClick = useCallback(
    (request: PopularRequest) => {
      // Popular route clicks prefill the Schedule form from the clicked
      // item. This mirrors Angular: users land on the Schedule page with
      // route/date fields ready, then submit when they want results.
      switch (request.mode) {
        case "Route":
        case "RouteWithBack": {
          const curWeek = currentWeekBounds();
          setDepartureCode(toCityCode(request.departure, dictionaries));
          setArrivalCode(toCityCode(request.arrival, dictionaries));
          setIsRoundTrip(request.mode === "RouteWithBack");
          setDateFrom(curWeek.from);
          setDateTo(curWeek.to);
          if (request.mode === "RouteWithBack") {
            const nxt = nextWeekBounds();
            setReturnDateFrom(nxt.from);
            setReturnDateTo(nxt.to);
          } else {
            setReturnDateFrom(null);
            setReturnDateTo(null);
          }
          break;
        }
        case "Arrival":
          setArrivalCode(toCityCode(request.arrival, dictionaries));
          break;
        case "Departure":
          setDepartureCode(toCityCode(request.departure, dictionaries));
          break;
        case "FlightNumber":
          // Schedule has no flight-number field — ignore.
          break;
      }
      if (sameCitiesError) setSameCitiesError(null);
    },
    [dictionaries, sameCitiesError],
  );

  const scheduleFilter = (
    <form
      className="schedule-start__form"
      data-testid="schedule-search-form"
      aria-label={t("SCHEDULE.TITLE")}
      onSubmit={handleSubmit}
    >
      <CityAutocomplete
        label={t("SHARED.DEPARTURE_CITY")}
        placeholder={t("SHARED.CITY_PLACEHOLDER")}
        value={departureCode}
        onChange={(code) => {
          setDepartureCode(code);
          if (sameCitiesError) setSameCitiesError(null);
        }}
        dictionaries={dictionaries}
        testIdPrefix="schedule-departure"
      />

      <div className="change-container">
        <button
          className="button-change"
          type="button"
          onClick={() => {
            const tmp = departureCode;
            setDepartureCode(arrivalCode);
            setArrivalCode(tmp);
          }}
          data-testid="swap-cities-button"
        >
          <svg className="svg--change-city">
            <use xlinkHref="/assets/img/sprite.svg#changeCity" />
          </svg>
        </button>
      </div>

      <CityAutocomplete
        label={t("SHARED.ARRIVAL_CITY")}
        placeholder={t("SHARED.CITY_PLACEHOLDER")}
        value={arrivalCode}
        onChange={(code) => {
          setArrivalCode(code);
          if (sameCitiesError) setSameCitiesError(null);
        }}
        dictionaries={dictionaries}
        testIdPrefix="schedule-arrival"
      />
      {sameCitiesError && (
        <div
          className="validation-tooltip"
          data-testid="schedule-same-cities-error"
          role="alert"
        >
          {t(sameCitiesError)}
        </div>
      )}

      <div className="schedule-start__field">
        <label htmlFor="schedule-date-from">{t("SHARED.SCHEDULES_DATE")}</label>
        <Calendar
          ref={outboundCalendarRef}
          value={dateFrom && dateTo ? [dateFrom, dateTo] : null}
          onChange={onOutboundDateSelect}
          selectionMode="range"
          minDate={scheduleMinDate}
          maxDate={scheduleMaxDate}
          selectOtherMonths
          dateFormat="dd.mm.yy"
          placeholder={`${t("SHARED.DATE_FORMAT")} - ${t("SHARED.DATE_FORMAT")}`}
          showIcon
          className="input--filter"
          inputId="schedule-date-from"
          inputRef={dateRangeInputRef}
          data-testid="date-range-input"
          readOnlyInput
        />
      </div>

      <div className="wrapper--time-selector full-view" data-testid="time-selector">
        <div className="time-selector__label">{t("SHARED.DEPARTURE_TIME")}</div>
        <div className="time-selector">
          <Slider
            value={timeRange}
            onChange={(e: SliderChangeEvent) => setTimeRange(e.value as [number, number])}
            range
            min={0}
            max={1440}
            step={60}
          />
        </div>
        <div className="time-selector__value">
          {minutesToTime(timeRange[0])} — {minutesToTime(timeRange[1])}
        </div>
      </div>

      <div className="schedule-start__field">
        <label>
          <input
            type="checkbox"
            checked={directOnly}
            onChange={(e) => setDirectOnly(e.target.checked)}
            data-testid="direct-only-toggle"
          />
          {t("SHARED.DIRECT_FLIGHT_ONLY")}
        </label>
      </div>

      <div className="schedule-start__field">
        <label>
          <input
            type="checkbox"
            checked={isRoundTrip}
            onChange={(e) => setIsRoundTrip(e.target.checked)}
            data-testid="round-trip-toggle"
          />
          {t("SHARED.RETURN_FLIGHT_VIEW")}
        </label>
      </div>

      {isRoundTrip && (
        <>
          {/* Angular's schedule-filter renders return dates as a single
              calendar-input-week range, not two separate pickers. */}
          <div className="schedule-start__field">
            <label htmlFor="schedule-return-date-range">{t("SHARED.RETURN_FLIGHT_DATE")}</label>
            <Calendar
              ref={returnCalendarRef}
              value={returnDateFrom && returnDateTo ? [returnDateFrom, returnDateTo] : null}
              onChange={onReturnDateSelect}
              selectionMode="range"
              minDate={scheduleMinDate}
              maxDate={scheduleMaxDate}
              selectOtherMonths
              dateFormat="dd.mm.yy"
              placeholder={`${t("SHARED.DATE_FORMAT")} - ${t("SHARED.DATE_FORMAT")}`}
              showIcon
              className="input--filter"
              inputId="schedule-return-date-range"
              inputRef={returnDateRangeInputRef}
              data-testid="return-date-range-input"
              readOnlyInput
            />
          </div>

          <div className="wrapper--time-selector full-view" data-testid="return-time-selector">
            <div className="time-selector__label">{t("SHARED.RETURN_FLIGHT_TIME")}</div>
            <div className="time-selector">
              <Slider
                value={returnTimeRange}
                onChange={(e: SliderChangeEvent) => setReturnTimeRange(e.value as [number, number])}
                range
                min={0}
                max={1440}
                step={60}
              />
            </div>
            <div className="time-selector__value">
              {minutesToTime(returnTimeRange[0])} — {minutesToTime(returnTimeRange[1])}
            </div>
          </div>
        </>
      )}

      <button
        type="submit"
        className="schedule-start__submit"
        data-testid="schedule-search-submit"
      >
        {t("SHARED.SCHEDULES_VIEW")}
      </button>
    </form>
  );

  return (
    <div className="schedule-start-page" data-testid="schedule-start">
      <PageLayout
        headerLeft={
          <PageTabs viewType="schedule" />
        }
        title={
          <h1 className="text--white page-title">
            {t("SCHEDULE.TITLE")}
          </h1>
        }
        breadcrumbs={[]}
        contentLeft={
          <>
            {scheduleFilter}
            <SearchHistory />
          </>
        }
      >
        <section className="frame">
          <h2>{t("SCHEDULE.SCHEDULE-START")}</h2>

          <div className="titles-container">
            <div className="title title1">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE1")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE1-DESCRIPTION")}
              </div>
            </div>

            <div className="title title2">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE2")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE2-DESCRIPTION")}
              </div>
            </div>

            <div className="title title3">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE3")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE3-DESCRIPTION")}
              </div>
            </div>

            <div className="title title4">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE4")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE4-DESCRIPTION")}
              </div>
            </div>
          </div>

          {/*
            TZ Table 9 prescribes a second info section "Возможности расписания"
            (Title5 + Title6), but the Angular reference baseline has it commented
            out (see `ClientApp/.../schedule-start-page.component.html`). Following
            Angular here — the block duplicates the "Купить билет / Расписание"
            info already shown in the OB start-page table and breaks the visual
            rhythm. The i18n keys are retained for future work if needed.
          */}

          <PopularRequestsPanel onRequestClick={handlePopularRequestClick} />
        </section>

        <section className="frame bottom-description-frame">
          <div className="bottom-description-container">
            <h3 className="bottom-description-title">
              {t("SCHEDULE.SCHEDULE-BOTTOM-DESCRIPTION")}
            </h3>
            <div
              className="bottom-description-text"
              dangerouslySetInnerHTML={{
                __html: t("SCHEDULE.SCHEDULE-BOTTOM-DESCRIPTION-TEXT"),
              }}
            />
          </div>
        </section>
      </PageLayout>
    </div>
  );
};
