department-of-veterans-affairs/vets-website

View on GitHub
src/applications/verify-your-enrollment/helpers.jsx

Summary

Maintainability
F
2 wks
Test Coverage
/* eslint-disable no-nested-ternary */
/* eslint-disable react/jsx-key */ // keys are defined, error being thrown in eslint even when key is defined
import React from 'react';
import ADDRESS_DATA from 'platform/forms/address/data';
import { v4 as uuidv4 } from 'uuid';
import {
  BAD_UNIT_NUMBER,
  MISSING_UNIT_NUMBER,
  TIMS_DOCUMENTS,
} from './constants';

export function splitAddressLine(addressLine, maxLength) {
  if (addressLine?.length <= maxLength) {
    return { line1: addressLine, line2: '' };
  }

  // Find the last space within the maxLength
  let lastSpaceIndex = addressLine?.lastIndexOf(' ', maxLength);

  // If there's no space, we can't split without breaking a word, so just split at maxLength
  if (lastSpaceIndex === -1) {
    lastSpaceIndex = maxLength;
  }

  return {
    line1: addressLine?.substring(0, lastSpaceIndex),
    line2: addressLine?.substring(lastSpaceIndex).trim(),
  };
}

export const sortedEnrollmentsDGIB = enrollmentVerifications =>
  enrollmentVerifications?.sort((a, b) => {
    return (
      new Date(a.verificationBeginDate) - new Date(b.verificationBeginDate)
    );
  });
export const translateDateIntoMonthYearFormat = dateString => {
  // Parse the date string as UTC
  if (dateString === null) {
    return 'Date unavailable';
  }

  const [year, month, day] = dateString
    ?.split('-')
    .map(num => parseInt(num, 10));
  const date = new Date(Date.UTC(year, month - 1, day));

  // Format the date with the full month name and year in UTC
  // Outputs: 'Month Year'
  return date.toLocaleDateString('en-US', {
    month: 'long',
    year: 'numeric',
    timeZone: 'UTC',
  });
};

export const toLocalISOString = date => {
  const pad = num => num.toString().padStart(2, '0');

  const year = date.getFullYear();
  const month = pad(date.getMonth() + 1); // Months are zero-indexed
  const day = pad(date.getDate());
  const hour = pad(date.getHours());
  const minute = pad(date.getMinutes());
  const second = pad(date.getSeconds());
  const ms = date
    .getMilliseconds()
    .toString()
    .padStart(3, '0');

  return `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}`;
};

export const translateDateIntoMonthDayYearFormat = (
  dateString,
  isDelimiting = false,
) => {
  // Parse the date string as UTC
  if (!dateString) return null;
  const [year, month, day] = dateString
    .split('-')
    .map(num => parseInt(num, 10));
  const validYear = isDelimiting && year < 2000 ? year + 100 : year; // check for invalid 1900s delimiting date
  const date = new Date(Date.UTC(validYear, month - 1, day));

  // Function to get the ordinal suffix for a given day
  function getOrdinalSuffix(dayOfTheMonth) {
    if (dayOfTheMonth > 3 && dayOfTheMonth < 21) return 'th'; // for dayOfTheMonths like 4th, 5th, ... 20th
    switch (dayOfTheMonth % 10) {
      case 1:
        return 'st';
      case 2:
        return 'nd';
      case 3:
        return 'rd';
      default:
        return 'th';
    }
  }

  // Get the day with ordinal suffix
  const dayWithSuffix = date.getUTCDate() + getOrdinalSuffix(date.getUTCDate());
  // Format the month and year
  const formattedMonth = date.toLocaleDateString('en-US', {
    month: 'long',
    timeZone: 'UTC',
  });

  // Combine everything
  return `${formattedMonth} ${dayWithSuffix}, ${date.getUTCFullYear()}`;
};

export const translateDatePeriod = (startDateString, endDateString) => {
  // Parse the date strings into Date objects as UTC
  const dateUnavailable = 'Date unavailable';
  const parseDateUTC = dateString => {
    const [year, month, day] = dateString
      ?.split('-')
      .map(num => parseInt(num, 10));
    return new Date(Date.UTC(year, month - 1, day));
  };

  const date1 =
    startDateString !== null ? parseDateUTC(startDateString) : dateUnavailable;
  const date2 =
    endDateString !== null ? parseDateUTC(endDateString) : dateUnavailable;

  // Function to format a date into MM/DD/YYYY in UTC
  function formatDate(date) {
    const day = String(date.getUTCDate()).padStart(2, '0');
    const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // Month is 0-indexed
    const year = date.getUTCFullYear();
    return `${month}/${day}/${year}`;
  }
  // Format both dates and concatenate them
  return `${date1 === dateUnavailable ? date1 : formatDate(date1)} - ${
    date2 === dateUnavailable ? date2 : formatDate(date2)
  }`;
};

export const formatCurrency = str => {
  // Convert the string to a number
  const number = Number(str);

  // Check if the conversion is successful
  if (Number.isNaN(number)) {
    return 'Invalid input';
  }

  // Format the number as a currency string
  return number.toLocaleString('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });
};

export const scrollToElement = el => {
  const element = document.getElementById(el);
  if (element) {
    element.scrollIntoView({ behavior: 'smooth' });
  }
};

// make an object of just the military state codes and names
export const MILITARY_STATES = Object.entries(ADDRESS_DATA.states).reduce(
  (militaryStates, [stateCode, stateName]) => {
    if (ADDRESS_DATA.militaryStates.includes(stateCode)) {
      return {
        ...militaryStates,
        [stateCode]: stateName,
      };
    }
    return militaryStates;
  },
  {},
);

export const getCurrentDateFormatted = () => {
  const today = new Date();

  const month = String(today.getMonth() + 1).padStart(2, '0'); // Months are 0-based
  const day = String(today.getDate()).padStart(2, '0');
  const year = today.getFullYear();

  return `${month}/${day}/${year}`;
};

export const getPendingDocumentDescription = docType => {
  const documentDisplayName = TIMS_DOCUMENTS?.[docType]?.displayName;
  const documentExplanation = TIMS_DOCUMENTS?.[docType]?.explanation;
  return { documentDisplayName, documentExplanation };
};
export const remainingBenefits = remEnt => {
  const remainingEntitlement = remEnt?.split('-');
  const month =
    parseInt(remEnt?.slice(0, 2), 10) ||
    (remainingEntitlement ? remainingEntitlement[0] : undefined);
  const rest = parseFloat(`0.${remEnt?.slice(2)}`);
  const day =
    Math.round(rest * 30) ||
    (remainingEntitlement ? Number(remainingEntitlement[1]) : undefined);

  return { month, day };
};

export const isSameMonth = (date1, date2) => {
  const [year1, month1] = date1.split('-').map(str => parseInt(str, 10));
  const [year2, month2] = date2.split('-').map(str => parseInt(str, 10));

  return month1 === month2 && year1 === year2;
};

export const getEndOfMonth = (year, month) => {
  return new Date(year, month, 0).getDate(); // Last day of the month
};

export const getDateRangesBetween = (date1, date2) => {
  const [year1, month1] = date1.split('-').map(str => parseInt(str, 10));
  const [year2, month2] = date2.split('-').map(str => parseInt(str, 10));

  const ranges = [];

  // Range for the first month
  const endOfMonth1 = getEndOfMonth(year1, month1);
  ranges.push(
    `${date1} - ${year1}-${String(month1).padStart(2, '0')}-${endOfMonth1}`,
  );

  // Add ranges for full months in between
  let currentYear = year1;
  let currentMonth = month1 + 1;
  while (
    currentYear < year2 ||
    (currentYear === year2 && currentMonth < month2)
  ) {
    const endOfMonth = getEndOfMonth(currentYear, currentMonth);
    ranges.push(
      `${currentYear}-${String(currentMonth).padStart(
        2,
        '0',
      )}-01 - ${currentYear}-${String(currentMonth).padStart(
        2,
        '0',
      )}-${endOfMonth}`,
    );

    if (currentMonth === 12) {
      currentMonth = 1;
      currentYear += 1;
    } else {
      currentMonth += 1;
    }
  }

  // Range for the last month
  ranges.push(`${year2}-${String(month2).padStart(2, '0')}-01 - ${date2}`);

  return ranges;
};
const enrollmentInfoClassName = 'vads-u-margin--0 vads-u-font-size--base';
export const getPeriodsToVerify = pendingEnrollments => {
  return pendingEnrollments
    .map(enrollmentToBeVerified => {
      const {
        actBegin,
        actEnd,
        monthlyRate,
        numberHours,
      } = enrollmentToBeVerified;
      const myUUID = uuidv4();

      return (
        <div
          className="vads-u-margin-y--2"
          key={`Enrollment-to-be-verified-${myUUID}`}
        >
          <p className={enrollmentInfoClassName}>
            <span className="vads-u-font-weight--bold">
              {translateDatePeriod(actBegin, actEnd)}
            </span>
          </p>
          <p className={enrollmentInfoClassName}>
            <span className="vads-u-font-weight--bold">
              Total credit hours:
            </span>{' '}
            {numberHours === null ? 'Hours unavailable' : numberHours}
          </p>
          <p className={enrollmentInfoClassName}>
            <span className="vads-u-font-weight--bold">Monthly rate:</span>{' '}
            {monthlyRate === null
              ? 'Rate unavailable'
              : formatCurrency(monthlyRate)}
          </p>
        </div>
      );
    })
    .reverse();
};
export const isVerificationEndDateValid = verificationEndDate => {
  const today = new Date();
  const endDate = new Date(verificationEndDate);

  return endDate <= today;
};
export const getPeriodsToVerifyDGIB = (
  pendingEnrollments,
  shouldReverse = false,
) => {
  // Sort the enrollments by verificationBeginDate
  const periodsToVerify = sortedEnrollmentsDGIB(pendingEnrollments).map(
    enrollmentToBeVerified => {
      const {
        verificationBeginDate,
        verificationEndDate,
        // lastDepositAmount,
        totalCreditHours,
        verificationMethod,
      } = enrollmentToBeVerified;
      const myUUID = uuidv4();

      return (
        <div key={`Enrollment-to-be-verified-${myUUID}`}>
          {!verificationMethod &&
            isVerificationEndDateValid(verificationEndDate) && (
              <div className="vads-u-margin-y--2">
                <p className={enrollmentInfoClassName}>
                  <span className="vads-u-font-weight--bold">
                    {translateDatePeriod(
                      verificationBeginDate,
                      verificationEndDate,
                    )}
                  </span>
                </p>
                <p
                  className={enrollmentInfoClassName}
                  data-testid="total-credit-hours"
                >
                  <span className="vads-u-font-weight--bold">
                    Total credit hours:
                  </span>{' '}
                  {totalCreditHours === null
                    ? 'Hours unavailable'
                    : totalCreditHours}
                </p>
                {/* <p
                  className={enrollmentInfoClassName}
                  data-testid="monthly-rate"
                >
                  <span className="vads-u-font-weight--bold">
                    Monthly rate:
                  </span>{' '}
                  {lastDepositAmount === null
                    ? 'Rate unavailable'
                    : formatCurrency(lastDepositAmount)}
                </p> */}
              </div>
            )}
        </div>
      );
    },
  );
  return shouldReverse ? periodsToVerify.reverse() : periodsToVerify;
};

export const getGroupedPreviousEnrollments = month => {
  const { transactDate, actBegin, actEnd, id, paymentDate } = month[0];
  const myUUID = uuidv4();

  return (
    <div className="vye-top-border" key={id || myUUID}>
      {transactDate && paymentDate ? (
        <>
          <h3 className="vads-u-font-size--h4 vads-u-display--flex vads-u-align-items--center">
            <span className="vads-u-display--inline-block ">
              {actBegin !== null
                ? translateDateIntoMonthYearFormat(actBegin)
                : translateDateIntoMonthYearFormat(actEnd)}
            </span>{' '}
            <va-icon
              icon="check_circle"
              class="icon-color"
              aria-hidden="true"
            />{' '}
            <span className="vads-u-display--block">Verified</span>
          </h3>
          <p>We processed your payment for this month.</p>
          <va-additional-info
            trigger={`
              ${
                actBegin !== null
                  ? translateDateIntoMonthYearFormat(actBegin)
                  : translateDateIntoMonthYearFormat(actEnd)
              } verification details
            `}
            class="vads-u-margin-bottom--4"
          >
            {month.map((monthAward, index) => {
              const { numberHours, monthlyRate } = monthAward;
              return (
                <div key={index}>
                  <p className="vads-u-font-weight--bold vads-u-margin--0">
                    {translateDatePeriod(
                      monthAward.actBegin,
                      monthAward.actEnd,
                    )}
                  </p>
                  <p className="vads-u-margin--0">
                    <span className="vads-u-font-weight--bold">
                      Total credit hours:
                    </span>{' '}
                    {numberHours === null ? 'Hours unavailable' : numberHours}
                  </p>
                  <p className="vads-u-margin--0">
                    <span className="vads-u-font-weight--bold">
                      Monthly Rate:
                    </span>{' '}
                    {monthlyRate === null
                      ? 'Rate unavailable'
                      : formatCurrency(monthlyRate)}
                  </p>
                  <div className="vads-u-font-style--italic vads-u-margin--0">
                    You verified on{' '}
                    {translateDateIntoMonthDayYearFormat(
                      monthAward.transactDate,
                    )}
                  </div>
                  <div
                    className={
                      index === month.length - 1
                        ? 'vads-u-margin-bottom--0'
                        : 'vads-u-margin-bottom--3'
                    }
                  />
                </div>
              );
            })}
          </va-additional-info>
        </>
      ) : transactDate && !paymentDate ? (
        <>
          <h3 className="vads-u-font-size--h4 vads-u-display--flex vads-u-align-items--center">
            <span className="vads-u-display--inline-block ">
              {actBegin !== null
                ? translateDateIntoMonthYearFormat(actBegin)
                : translateDateIntoMonthYearFormat(actEnd)}
            </span>{' '}
            <va-icon
              icon="check_circle"
              class="icon-color"
              aria-hidden="true"
            />{' '}
            <span className="vads-u-display--block">Verified</span>
          </h3>
          <va-additional-info
            trigger={`${translateDateIntoMonthYearFormat(
              actBegin,
            )} verification details`}
            class="vads-u-margin-bottom--4"
          >
            {month.map((monthAward, index) => {
              const { numberHours, monthlyRate } = monthAward;
              return (
                <div key={index}>
                  <p className="vads-u-font-weight--bold vads-u-margin--0">
                    {translateDatePeriod(
                      monthAward.actBegin,
                      monthAward.actEnd,
                    )}
                  </p>
                  <p className="vads-u-margin--0">
                    <span className="vads-u-font-weight--bold">
                      Total credit hours:
                    </span>{' '}
                    {numberHours === null ? 'Hours unavailable' : numberHours}
                  </p>
                  <p className="vads-u-margin--0">
                    <span className="vads-u-font-weight--bold">
                      Monthly Rate:
                    </span>{' '}
                    {monthlyRate === null
                      ? 'Rate unavailable'
                      : formatCurrency(monthlyRate)}
                  </p>
                  <div className="vads-u-font-style--italic vads-u-margin--0">
                    You verified on{' '}
                    {translateDateIntoMonthDayYearFormat(
                      monthAward.transactDate,
                    )}
                  </div>
                  <div
                    className={
                      index === month.length - 1
                        ? 'vads-u-margin-bottom--0'
                        : 'vads-u-margin-bottom--3'
                    }
                  />
                </div>
              );
            })}
          </va-additional-info>
        </>
      ) : (
        <>
          <h3 className="vads-u-font-size--h4">
            {translateDateIntoMonthYearFormat(actBegin)}
          </h3>
          <div>
            <va-alert
              background-only
              class="vads-u-margin-bottom--3"
              close-btn-aria-label="Close notification"
              disable-analytics="true"
              full-width="false"
              status="info"
              visible="true"
              slim
            >
              <p
                className="vads-u-margin-y--0 text-color vads-u-font-family--sans"
                data-testid="have-not-verified"
              >
                You haven’t verified your enrollment for the month.
              </p>
            </va-alert>
          </div>
        </>
      )}
    </div>
  );
};
export const getGroupedPreviousEnrollmentsDGIB = enrollment => {
  const {
    verificationBeginDate,
    verificationEndDate,
    verificationMethod,
  } = enrollment[0];
  const myUUID = uuidv4();

  return (
    <div className="vye-top-border" key={myUUID}>
      {verificationMethod && isVerificationEndDateValid(verificationEndDate) ? (
        <>
          <h3 className="vads-u-font-size--h4 vads-u-display--flex vads-u-align-items--center">
            <span className="vads-u-display--inline-block ">
              {verificationBeginDate !== null
                ? translateDateIntoMonthYearFormat(verificationBeginDate)
                : translateDateIntoMonthYearFormat(verificationEndDate)}
            </span>{' '}
            <va-icon
              icon="check_circle"
              class="icon-color"
              aria-hidden="true"
            />{' '}
            <span className="vads-u-display--block">Verified</span>
          </h3>
          <p>We processed your payment for this month.</p>
          <va-additional-info
            trigger={`
              ${
                verificationBeginDate !== null
                  ? translateDateIntoMonthYearFormat(verificationBeginDate)
                  : translateDateIntoMonthYearFormat(verificationEndDate)
              } verification details
            `}
            class="vads-u-margin-bottom--4"
          >
            {enrollment.map((monthAward, index) => {
              const { totalCreditHours } = monthAward;
              return (
                <div key={index}>
                  <p className="vads-u-font-weight--bold vads-u-margin--0">
                    {translateDatePeriod(
                      monthAward.verificationBeginDate,
                      monthAward.verificationEndDate,
                    )}
                    <span className="vads-u-display--inline-block vads-u-font-weight--normal vads-u-margin-left--0p5 vads-u-color--gray-dark">
                      at {monthAward?.facilityName?.toUpperCase()}
                    </span>
                  </p>
                  <p className="vads-u-margin--0">
                    <span className="vads-u-font-weight--bold">
                      Total credit hours:
                    </span>{' '}
                    {totalCreditHours === null
                      ? 'Hours unavailable'
                      : totalCreditHours}
                  </p>
                  {/* <p className="vads-u-margin--0">
                    <span className="vads-u-font-weight--bold">
                      Monthly Rate:
                    </span>{' '}
                    {lastDepositAmount === null
                      ? 'Rate unavailable'
                      : formatCurrency(lastDepositAmount)}
                  </p> */}
                  {/* <div className="vads-u-font-style--italic vads-u-margin--0">
                    You verified on{' '}
                    {translateDateIntoMonthDayYearFormat(
                      monthAward.transactDate,
                    )}
                  </div> */}
                  <div
                    className={
                      index === enrollment.length - 1
                        ? 'vads-u-margin-bottom--0'
                        : 'vads-u-margin-bottom--3'
                    }
                  />
                </div>
              );
            })}
          </va-additional-info>
        </>
      ) : (
        <>
          {!verificationMethod &&
            isVerificationEndDateValid(verificationEndDate) && (
              <>
                <h3 className="vads-u-font-size--h4">
                  {translateDateIntoMonthYearFormat(verificationBeginDate)}
                </h3>
                <div>
                  <va-alert
                    background-only
                    class="vads-u-margin-bottom--3"
                    close-btn-aria-label="Close notification"
                    disable-analytics="true"
                    full-width="false"
                    status="info"
                    visible="true"
                    slim
                  >
                    <p
                      className="vads-u-margin-y--0 text-color vads-u-font-family--sans"
                      data-testid="have-not-verified"
                    >
                      You haven’t verified your enrollment for the month.
                    </p>
                  </va-alert>
                </div>
              </>
            )}
        </>
      )}
    </div>
  );
};

export const getSignlePreviousEnrollmentsDGIB = enrollment => {
  const myUUID = uuidv4();
  return (
    <div className="vye-top-border" key={myUUID}>
      {!!enrollment?.verificationMethod &&
        isVerificationEndDateValid(enrollment.verificationEndDate) && (
          <>
            <h3 className="vads-u-font-size--h4 vads-u-display--flex vads-u-align-items--center">
              <span className="vads-u-display--inline-block ">
                {enrollment.verificationBeginDate !== null
                  ? translateDateIntoMonthYearFormat(
                      enrollment?.verificationBeginDate,
                    )
                  : translateDateIntoMonthYearFormat(
                      enrollment?.verificationEndDate,
                    )}
              </span>{' '}
              <va-icon
                icon="check_circle"
                class="icon-color"
                aria-hidden="true"
              />{' '}
              <span className="vads-u-display--block">Verified</span>
            </h3>
            <p>We processed your payment for this month.</p>
            <va-additional-info
              trigger={`
            ${
              enrollment.verificationBeginDate !== null
                ? translateDateIntoMonthYearFormat(
                    enrollment?.verificationBeginDate,
                  )
                : translateDateIntoMonthYearFormat(
                    enrollment?.verificationEndDate,
                  )
            } verification details
          `}
              class="vads-u-margin-bottom--4"
            >
              <p className="vads-u-font-weight--bold">
                {translateDatePeriod(
                  enrollment?.verificationBeginDate,
                  enrollment?.verificationEndDate,
                )}
                <span className="vads-u-display--inline-block vads-u-font-weight--normal vads-u-margin-left--0p5 vads-u-color--gray-dark">
                  at {enrollment?.facilityName?.toUpperCase()}
                </span>
              </p>
              <p>
                <span className="vads-u-font-weight--bold">
                  Total credit hours:
                </span>{' '}
                {enrollment?.totalCreditHours === null
                  ? 'Hours unavailable'
                  : enrollment?.totalCreditHours}
              </p>
              {/* <p>
                <span className="vads-u-font-weight--bold">Monthly Rate:</span>{' '}
                {enrollment?.lastDepositAmount === null
                  ? 'Rate unavailable'
                  : formatCurrency(enrollment?.lastDepositAmount)}
              </p> */}
              {/* <div className="vads-u-font-style--italic">
                You verified on{' '}
                {translateDateIntoMonthDayYearFormat(
                  enrollment?.verificationThroughDate,
                )}
              </div> */}
            </va-additional-info>
          </>
        )}
      {!enrollment?.verificationMethod &&
        isVerificationEndDateValid(enrollment.verificationEndDate) && (
          <>
            <h3 className="vads-u-font-size--h4">
              {translateDateIntoMonthYearFormat(
                enrollment?.verificationBeginDate,
              )}
            </h3>
            <va-alert
              background-only
              class="vads-u-margin-bottom--3"
              close-btn-aria-label="Close notification"
              disable-analytics="true"
              full-width="false"
              status="info"
              visible="true"
              slim
            >
              <p
                className="vads-u-margin-y--0 text-color vads-u-font-family--sans"
                data-testid="have-not-verified"
              >
                You haven’t verified your enrollment for the month.
              </p>
            </va-alert>
          </>
        )}
    </div>
  );
};
export const getSignlePreviousEnrollments = awards => {
  const myUUID = uuidv4();
  return (
    <div className="vye-top-border" key={myUUID}>
      {awards?.transactDate &&
        awards?.paymentDate && (
          <>
            <h3 className="vads-u-font-size--h4 vads-u-display--flex vads-u-align-items--center">
              <span className="vads-u-display--inline-block ">
                {awards.actBegin !== null
                  ? translateDateIntoMonthYearFormat(awards?.actBegin)
                  : translateDateIntoMonthYearFormat(awards?.actEnd)}
              </span>{' '}
              <va-icon
                icon="check_circle"
                class="icon-color"
                aria-hidden="true"
              />{' '}
              <span className="vads-u-display--block">Verified</span>
            </h3>
            <p>We processed your payment for this month.</p>
            <va-additional-info
              trigger={`
            ${
              awards.actBegin !== null
                ? translateDateIntoMonthYearFormat(awards?.actBegin)
                : translateDateIntoMonthYearFormat(awards?.actEnd)
            } verification details
          `}
              class="vads-u-margin-bottom--4"
            >
              <p className="vads-u-font-weight--bold">
                {translateDatePeriod(awards?.actBegin, awards?.actEnd)}
              </p>
              <p>
                <span className="vads-u-font-weight--bold">
                  Total credit hours:
                </span>{' '}
                {awards.numberHours === null
                  ? 'Hours unavailable'
                  : awards.numberHours}
              </p>
              <p>
                <span className="vads-u-font-weight--bold">Monthly Rate:</span>{' '}
                {awards.monthlyRate === null
                  ? 'Rate unavailable'
                  : formatCurrency(awards?.monthlyRate)}
              </p>
              <div className="vads-u-font-style--italic">
                You verified on{' '}
                {translateDateIntoMonthDayYearFormat(awards?.transactDate)}
              </div>
            </va-additional-info>
          </>
        )}
      {awards?.transactDate &&
        !awards?.paymentDate && (
          <>
            <h3 className="vads-u-font-size--h4 vads-u-display--flex vads-u-align-items--center">
              <span className="vads-u-display--inline-block ">
                {awards.actBegin !== null
                  ? translateDateIntoMonthYearFormat(awards?.actBegin)
                  : translateDateIntoMonthYearFormat(awards?.actEnd)}
              </span>{' '}
              <va-icon
                icon="check_circle"
                class="icon-color"
                aria-hidden="true"
              />{' '}
              <span className="vads-u-display--block">Verified</span>
            </h3>
            <va-additional-info
              trigger={`${translateDateIntoMonthYearFormat(
                awards?.actBegin,
              )} verification details`}
              class="vads-u-margin-bottom--4"
            >
              <p className="vads-u-font-weight--bold">
                {translateDatePeriod(awards?.actBegin, awards?.actEnd)}
              </p>
              <p>
                <span className="vads-u-font-weight--bold">
                  Total credit hours:
                </span>{' '}
                {awards?.numberHours === null
                  ? 'Hours unavailable'
                  : awards?.numberHours}
              </p>
              <p>
                <span className="vads-u-font-weight--bold">Monthly Rate:</span>{' '}
                {awards?.monthlyRate === null
                  ? 'Rate unavailable'
                  : formatCurrency(awards?.monthlyRate)}
              </p>
              <div className="vads-u-font-style--italic">
                You verified on{' '}
                {translateDateIntoMonthDayYearFormat(awards?.transactDate)}
              </div>
            </va-additional-info>
          </>
        )}
      {!awards?.transactDate &&
        !awards?.paymentDate && (
          <>
            <h3 className="vads-u-font-size--h4">
              {translateDateIntoMonthYearFormat(awards?.actBegin)}
            </h3>
            <va-alert
              background-only
              class="vads-u-margin-bottom--3"
              close-btn-aria-label="Close notification"
              disable-analytics="true"
              full-width="false"
              status="info"
              visible="true"
              slim
            >
              <p
                className="vads-u-margin-y--0 text-color vads-u-font-family--sans"
                data-testid="have-not-verified"
              >
                You haven’t verified your enrollment for the month.
              </p>
            </va-alert>
          </>
        )}
    </div>
  );
};

export const combineEnrollmentsWithStartMonth = enrollmentPeriods => {
  const isArray = Array.isArray(enrollmentPeriods);

  const trackDate = [];
  const combineMonths = {};
  const dateUnavailable = 'Date unavailable';

  if (isArray) {
    enrollmentPeriods.forEach(period => {
      // if award begin date is null, assign value as Date unavailable
      let tempMonthYear =
        period.actBegin !== null
          ? translateDateIntoMonthYearFormat(period.actBegin)
          : dateUnavailable;

      // if value is Date unavailable and there is an award end date, use the award end date instead
      if (tempMonthYear === dateUnavailable) {
        tempMonthYear =
          period.actEnd !== null
            ? translateDateIntoMonthYearFormat(period.actEnd)
            : dateUnavailable;
      }

      if (trackDate.includes(tempMonthYear)) {
        combineMonths[tempMonthYear].push({
          id: period.id,
          actBegin: period.actBegin,
          actEnd: period.actEnd,
          numberHours: period.numberHours,
          monthlyRate: period.monthlyRate,
          transactDate: period.transactDate,
          PendingVerificationSubmitted: period.PendingVerificationSubmitted,
          paymentDate: period.paymentDate,
        });
      } else {
        trackDate.push(tempMonthYear);
        combineMonths[tempMonthYear] = [
          {
            id: period.id,
            actBegin: period.actBegin,
            actEnd: period.actEnd,
            numberHours: period.numberHours,
            monthlyRate: period.monthlyRate,
            transactDate: period.transactDate,
            PendingVerificationSubmitted: period.PendingVerificationSubmitted,
            paymentDate: period.paymentDate,
          },
        ];
      }
    });
    return combineMonths;
  }
  return enrollmentPeriods;
};
export const combineEnrollmentsWithStartMonthDGIB = enrollmentPeriods => {
  const isArray = Array.isArray(enrollmentPeriods);

  const trackDate = [];
  const combineMonths = {};
  const dateUnavailable = 'Date unavailable';
  if (isArray) {
    enrollmentPeriods.forEach(period => {
      // if award begin date is null, assign value as Date unavailable
      let tempMonthYear =
        period.verificationBeginDate !== null
          ? translateDateIntoMonthYearFormat(period.verificationBeginDate)
          : dateUnavailable;

      // if value is Date unavailable and there is an award end date, use the award end date instead
      if (tempMonthYear === dateUnavailable) {
        tempMonthYear =
          period.verificationEndDate !== null
            ? translateDateIntoMonthYearFormat(period.verificationEndDate)
            : dateUnavailable;
      }

      if (trackDate.includes(tempMonthYear)) {
        combineMonths[tempMonthYear].push({
          verificationMonth: period.verificationMonth,
          verificationBeginDate: period.verificationBeginDate,
          verificationEndDate: period.verificationEndDate,
          createdDate: period.createdDate,
          verificationMethod: period.verificationMethod,
          verificationResponse: period.verificationResponse,
          facilityName: period.facilityName,
          totalCreditHours: period.totalCreditHours,
          paymentTransmissionDate: period.paymentTransmissionDate,
          lastDepositAmount: period.lastDepositAmount,
          remainingEntitlement: period.remainingEntitlement,
        });
      } else {
        trackDate.push(tempMonthYear);
        combineMonths[tempMonthYear] = [
          {
            verificationMonth: period.verificationMonth,
            verificationBeginDate: period.verificationBeginDate,
            verificationEndDate: period.verificationEndDate,
            createdDate: period.createdDate,
            verificationMethod: period.verificationMethod,
            verificationResponse: period.verificationResponse,
            facilityName: period.facilityName,
            totalCreditHours: period.totalCreditHours,
            paymentTransmissionDate: period.paymentTransmissionDate,
            lastDepositAmount: period.lastDepositAmount,
            remainingEntitlement: period.remainingEntitlement,
          },
        ];
      }
    });
    return combineMonths;
  }
  return enrollmentPeriods;
};
export const isMobileDevice = () => {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
    navigator.userAgent,
  );
};
export const noSuggestedAddress = deliveryPointValidation => {
  return (
    deliveryPointValidation === BAD_UNIT_NUMBER ||
    deliveryPointValidation === MISSING_UNIT_NUMBER ||
    deliveryPointValidation === 'MISSING_ZIP' ||
    deliveryPointValidation === 'UNDELIVERABLE'
  );
};

export const prepareAddressData = formData => {
  let addressData = {
    veteranName: formData.fullName,
    addressLine1:
      formData.addressLine1 || splitAddressLine(formData.street, 20).line1,
    addressLine2:
      formData.addressLine2 || splitAddressLine(formData.street, 20).line2,
    addressLine3: formData.addressLine3,
    addressLine4: formData.addressLine4,
    addressPou: 'CORRESPONDENCE',
    countryCodeIso3: formData.countryCodeIso3 || 'USA',
    city: formData.city,
  };
  const baseUSAData = {
    stateCode: formData.stateCode,
    zipCode: formData.zipCode,
    addressType: 'DOMESTIC',
  };
  if (formData['view:livesOnMilitaryBase']) {
    baseUSAData.addressType = 'OVERSEAS MILITARY';
  }
  addressData = { ...addressData, ...baseUSAData };
  addressData = { ...addressData };
  return addressData;
};
export const formatAddress = address => {
  const city = address?.city ?? '';
  const stateCode = address?.stateCode ?? '';
  const zipCode = address?.zipCode ?? '';

  return `${city}${
    stateCode || zipCode ? ',' : ''
  } ${stateCode} ${zipCode}`.trim();
};
export const addressLabel = address => {
  // Destructure address object for easier access
  const {
    addressLine1,
    addressLine2,
    addressLine3,
    addressLine4,
    city,
    province,
    stateCode,
    internationalPostalCode,
    zipCode,
  } = address;

  const line1 = addressLine1 || '';
  const line2 = addressLine2 || '';
  const line3 = addressLine3 || '';
  const line4 = addressLine4 || '';

  const cityState = city && (province || stateCode) ? `${city}, ` : city;

  const state = province || stateCode || '';

  const postalCode = internationalPostalCode || zipCode || '';

  return (
    <span>
      {line1 && <>{line1} </>}
      {line2 && <>{` ${line2}`}</>}
      {line3 && <br />}
      {line3 && <>{line3} </>}
      {line4 && <>{` ${line4}`}</>}
      {cityState && (
        <>
          <br /> {cityState}
        </>
      )}
      {state && <>{state}</>}
      {postalCode && (state || cityState) && ' '}
      {postalCode}
    </span>
  );
};

export const hasFormChanged = obj => {
  const keys = Object.keys(obj ?? {});
  for (const key of keys) {
    const value = obj[key];
    // Skip the specific key
    if (key === 'view:livesOnMilitaryBaseInfo') {
      // eslint-disable-next-line no-continue
      continue;
    }
    // Checking if there is value that is not undefined
    if (value !== undefined) {
      return true;
    }
  }
  return false;
};

export function compareAddressObjects(obj1, obj2) {
  const { hasOwnProperty } = Object.prototype;

  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length === 0 && keys2.length === 0) {
    return false;
  }
  for (const key of keys1) {
    if (key === 'view:livesOnMilitaryBaseInfo') {
      // eslint-disable-next-line no-continue
      continue;
    }
    if (
      hasOwnProperty.call(obj1, key) &&
      hasOwnProperty.call(obj2, key) &&
      obj1[key] !== obj2[key]
    ) {
      return true;
    }
  }

  for (const key of keys2) {
    if (key === 'view:livesOnMilitaryBaseInfo') {
      // eslint-disable-next-line no-continue
      continue;
    }
    if (
      hasOwnProperty.call(obj2, key) &&
      hasOwnProperty.call(obj1, key) &&
      obj2[key] !== obj1[key]
    ) {
      return true;
    }
  }

  return false;
}

function deepEqual(obj1, obj2) {
  if (obj1 === obj2) return true;

  if (
    typeof obj1 !== 'object' ||
    obj1 === null ||
    typeof obj2 !== 'object' ||
    obj2 === null
  ) {
    return false;
  }

  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (const key of keys1) {
    if (
      key === 'view:livesOnMilitaryBaseInfo' ||
      key === 'view:livesOnMilitaryBase'
    ) {
      // eslint-disable-next-line no-continue
      continue;
    }
    if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
      return false;
    }
  }

  return true;
}

const initialState = {
  addressLine1: undefined,
  addressLine2: undefined,
  addressLine3: undefined,
  addressLine4: undefined,
  city: undefined,
  countryCodeIso3: 'USA',
  internationalPostalCode: undefined,
  province: undefined,
  stateCode: '- Select -',
  'view:livesOnMilitaryBase': undefined,
  'view:livesOnMilitaryBaseInfo': {},
  zipCode: undefined,
};

// Function to check if the object has changed
export function hasAddressFormChanged(currentState) {
  const filledCurrentState = {
    ...initialState,
    ...currentState,
    stateCode:
      currentState.stateCode !== undefined
        ? currentState.stateCode
        : initialState.stateCode,
  };
  return !deepEqual(initialState, filledCurrentState);
}

export function removeCommas(obj) {
  const newObj = {};

  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === 'string') {
      newObj[key] = obj[key].replace(/,/g, '');
    } else if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
      newObj[key] = removeCommas(obj[key]);
    } else {
      newObj[key] = obj[key];
    }
  });
  return newObj;
}
export const groupVerificationsByMonth = verifications => {
  const grouped = new Map();

  verifications?.forEach(verification => {
    const monthKey = verification.verificationMonth;

    if (!grouped.has(monthKey)) {
      grouped.set(monthKey, { ...verification });
    } else {
      const existing = grouped.get(monthKey);
      existing.totalCreditHours += verification.totalCreditHours;
    }
  });
  return Array.from(grouped.values());
};

export const toSnakeCase = obj => {
  return Object.keys(obj).reduce((acc, key) => {
    const snakeKey = key.replace(/([A-Z])/g, '_$1').toLowerCase();
    acc[snakeKey] = obj[key];
    return acc;
  }, {});
};