import { compact, findIndex, isEmpty, isNil, uniqBy } from 'lodash';
import React, { ReactNode, useEffect, useState } from 'react';
import { SummaryCheckbox, TravelersFormValues } from '../../booking-wizard/types';
import { buildClassName } from '../utils/class-util';
import Icon from '../components/icon';
import Spinner from '../../search-results/components/spinner/spinner';

export interface SummaryNotification {
  id: number;
  title?: string | null;
  description?: string | null;
  hasToBeConfirmed?: boolean;
  isConfirmed?: boolean;
}

export interface SummaryVoucherState {
  code?: string;
  isValidated?: boolean;
  isValid?: boolean;
}

export interface SharedSummaryProps {
  translations: any;
  travelerFormValues: TravelersFormValues;
  checkboxes?: SummaryCheckbox[] | null;
  notifications?: SummaryNotification[] | null;
  remarks?: string;
  voucher?: SummaryVoucherState;
  voucherCodes?: string[];
  enableVoucher?: boolean;
  allowOption?: boolean;
  isOffer?: boolean;
  customValidateText?: string;
  isSubmitting?: boolean;
  skipPayment?: boolean;
  userValidated?: boolean;
  renderOptions: () => ReactNode;
  renderPreviousButton: () => ReactNode;
  renderLoader?: () => ReactNode;
  onSubmit: React.FormEventHandler<HTMLFormElement>;
  onRemarksChange?: (text: string) => void;
  onCheckboxesChange?: (checkboxes: SummaryCheckbox[]) => void;
  onNotificationsChange?: (notifications: SummaryNotification[]) => void;
  onVoucherChange?: (voucher: SummaryVoucherState) => void;
  onValidateVoucher?: () => void;
  onAddVoucher?: React.MouseEventHandler<HTMLButtonElement>;
  onRemoveVoucher?: (code: string) => void;
  onUserValidatedChange?: (isValid: boolean) => void;
}

const formatBirthDate = (birthDate?: string | null) => {
  if (!birthDate) return '';

  return birthDate.split('T')[0].split('-').reverse().join('/');
};

const SharedSummary: React.FC<SharedSummaryProps> = ({
  translations,
  travelerFormValues,
  checkboxes,
  notifications,
  remarks = '',
  voucher = {},
  voucherCodes = [],
  enableVoucher = false,
  allowOption = false,
  isOffer = false,
  customValidateText,
  isSubmitting = false,
  skipPayment = false,
  userValidated = true,
  renderOptions,
  renderPreviousButton,
  renderLoader,
  onSubmit,
  onRemarksChange,
  onCheckboxesChange,
  onNotificationsChange,
  onVoucherChange,
  onValidateVoucher,
  onAddVoucher,
  onRemoveVoucher,
  onUserValidatedChange
}) => {
  const [localCheckboxes, setLocalCheckboxes] = useState<SummaryCheckbox[] | undefined | null>(checkboxes);

  useEffect(() => {
    setLocalCheckboxes(checkboxes);
  }, [checkboxes]);

  useEffect(() => {
    const checkboxesValidated = !isNil(localCheckboxes) ? localCheckboxes.every((checkbox) => checkbox.isSelected) : true;
    const notificationsValidated = !isNil(notifications)
      ? notifications.filter((notification) => notification.hasToBeConfirmed).every((notification) => notification.isConfirmed)
      : true;

    onUserValidatedChange?.(checkboxesValidated && notificationsValidated);
  }, [localCheckboxes, notifications, onUserValidatedChange]);

  const handleNotificationChange = (id: number, checked: boolean) => {
    const updatedNotifications = (notifications ?? []).map((notification) =>
      notification.id === id ? { ...notification, isConfirmed: checked } : notification
    );

    onNotificationsChange?.(updatedNotifications);
  };

  const handleCheckboxChange = (id: string) => {
    if (isNil(localCheckboxes)) return;

    const newCheckboxes = [...localCheckboxes];
    const index = findIndex(localCheckboxes, (checkbox) => checkbox.id === id);

    if (index < 0) return;

    newCheckboxes[index] = {
      ...newCheckboxes[index],
      isSelected: !newCheckboxes[index].isSelected
    };

    setLocalCheckboxes(newCheckboxes);
    onCheckboxesChange?.(newCheckboxes);
  };

  return (
    <>
      {isSubmitting && <Spinner label={skipPayment ? translations.SUMMARY.PROCESS_BOOKING : translations.SUMMARY.REDIRECT} />}
      {!isSubmitting && (
        <form className="form" name="booking--summary" id="booking--summary" onSubmit={onSubmit}>
          <div className="form__booking--summary">
            <div className="form__region">
              <div className="form__row">
                <div className="form__group">
                  <div className="form__region-header">
                    <h5 className="form__region-heading">{translations.SUMMARY.PERSONAL_DETAILS}</h5>
                  </div>
                </div>
              </div>

              {travelerFormValues.rooms.map((room, roomIndex) => (
                <div className="form__row" key={roomIndex}>
                  <div className="form__group">
                    <div className="form__region-header">
                      <h5 className="form__region-heading">
                        {travelerFormValues.rooms.length > 1 ? `${translations.SHARED.ROOM} ${roomIndex + 1}` : translations.ROOM_OPTIONS_FORM.TRAVELER_GROUP}
                      </h5>
                      <p className="form__region-label">
                        {`${room.adults.length + room.children.length} ${
                          room.adults.length + room.children.length === 1 ? translations.SUMMARY.TRAVELER : translations.SUMMARY.TRAVELERS
                        }: ${compact([
                          room.adults.length,
                          room.adults.length === 1 && ` ${translations.SUMMARY.ADULT}`,
                          room.adults.length > 1 && ` ${translations.SUMMARY.ADULTS}`,
                          room.adults?.length && room.children?.length && ', ',
                          room.children.length,
                          room.children.length === 1 && ` ${translations.SUMMARY.CHILD}`,
                          room.children.length > 1 && ` ${translations.SUMMARY.CHILDREN}`
                        ]).join('')}`}
                      </p>
                    </div>
                  </div>

                  {[...room.adults, ...room.children].map((traveler) => {
                    const isMainBooker = traveler.id === travelerFormValues.mainBookerId;

                    return (
                      <div className="form__group form__group--sm-50" key={traveler.id}>
                        <ul className="list list--plain">
                          <li className="list__item">
                            <strong>
                              {traveler.firstName} {traveler.lastName}
                            </strong>{' '}
                            {isMainBooker && <em>({translations.SUMMARY.MAIN_BOOKER})</em>}
                          </li>
                          <li className="list__item">{formatBirthDate(traveler.birthDate)}</li>
                          {isMainBooker && (
                            <>
                              {travelerFormValues.street && (
                                <li className="list__item">{`${travelerFormValues.street} ${compact([
                                  travelerFormValues.houseNumber,
                                  travelerFormValues.box
                                ]).join(' ')}, ${travelerFormValues.zipCode} ${travelerFormValues.place}`}</li>
                              )}
                              {travelerFormValues.phone && <li className="list__item">{travelerFormValues.phone}</li>}
                              {travelerFormValues.email && <li className="list__item">{travelerFormValues.email}</li>}
                            </>
                          )}
                        </ul>
                      </div>
                    );
                  })}
                </div>
              ))}
            </div>

            <div className="form__region">
              <div className="form__row">
                <div className="form__group">
                  <div className="form__region-header">
                    <h5 className="form__region-heading">{translations.SUMMARY.OPTIONS}</h5>
                  </div>
                </div>
              </div>
              <div className="form__row">
                <div className="form__group">
                  <ul className="list list--booking-summary">{renderOptions()}</ul>
                </div>
              </div>
            </div>

            {enableVoucher && (
              <div className="form__region">
                <div className="form__row">
                  <div className="form__group">
                    <div className="form__region-header">
                      <h5 className="form__region-heading">{translations.SUMMARY.VOUCHERS}</h5>
                    </div>
                  </div>
                </div>
                <div className="form__row">
                  <div className="form__group">
                    <input
                      type="text"
                      className="form__input info-message__voucher__input"
                      value={voucher.code ?? ''}
                      onChange={(event) => onVoucherChange?.({ code: event.target.value })}
                    />
                    <button type="button" className={buildClassName(['cta', !voucher.code && 'cta--disabled'])} onClick={onValidateVoucher}>
                      {translations.SUMMARY.VOUCHER_VALIDATE}
                    </button>
                  </div>
                </div>
                <div className="form__row">
                  <div className="form__group info-message__voucher">
                    {voucher.isValid && voucher.isValidated && (
                      <div className="info-message info-message__voucher__valid">
                        <span>{translations.SUMMARY.VOUCHER_VALID}</span>
                        <button type="button" className="cta cta--secondary" onClick={onAddVoucher}>
                          {translations.SUMMARY.ADD_VOUCHER}
                        </button>
                      </div>
                    )}
                    {!voucher.isValid && voucher.isValidated && <div className="info-message--error">{translations.SUMMARY.VOUCHER_INVALID}</div>}
                  </div>
                </div>
                <div className="form__row">
                  <ul className="info-message__voucher">
                    {!isEmpty(voucherCodes) &&
                      voucherCodes.map((code, index) => (
                        <li key={`${code}-${index}`}>
                          <div className="info-message__voucher__list">
                            {code}{' '}
                            <button type="button" className="cta--add-remove" onClick={() => onRemoveVoucher?.(code)}>
                              <Icon height={16} name="ui-trashcan" />
                            </button>
                          </div>
                        </li>
                      ))}
                  </ul>
                </div>
              </div>
            )}

            {!isEmpty(notifications) && (
              <div className="form__region">
                <div className="form__row">
                  <div className="form__group">
                    <div className="info-message">
                      <Icon name="ui-tooltip" className="icon--secondary-color" />
                      <div className="info-message__copy">
                        <h5>{translations.SUMMARY.NOTIFICATIONS_TITLE}</h5>
                        {uniqBy(
                          (notifications ?? []).filter((notification) => !notification.hasToBeConfirmed),
                          'id'
                        ).map((notification) => (
                          <span key={notification.id} className="checkbox__label-text">
                            <strong className="checkbox__label-text--title">{notification.title}</strong>
                            <span className="checkbox__label-text--description">{notification.description}</span>
                          </span>
                        ))}
                        {uniqBy(
                          (notifications ?? []).filter((notification) => notification.hasToBeConfirmed),
                          'id'
                        ).map((notification) => (
                          <div className="checkbox" key={notification.id}>
                            <label className="checkbox__label">
                              <input
                                type="checkbox"
                                className="checkbox__input"
                                checked={notification.isConfirmed}
                                onChange={(event) => handleNotificationChange(notification.id, event.target.checked)}
                              />
                              <span className="checkbox__label-text">
                                <strong className="checkbox__label-text--title">{notification.title}</strong>
                                <span className="checkbox__label-text--description">{notification.description}</span>
                              </span>
                            </label>
                          </div>
                        ))}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            )}

            <div className="form__region">
              <div className="form__row">
                <div className="form__group">
                  <div className="form__region-header">
                    <h5 className="form__region-heading">{translations.SUMMARY.REMARKS}</h5>
                  </div>
                </div>
              </div>
              <div className="form__row">
                <div className="form__group">
                  <textarea className="form__input" value={remarks} onChange={(event) => onRemarksChange?.(event.target.value)} />
                </div>
              </div>
            </div>

            <div className="form__region">
              <div className="form__row">
                <div className="form__group">
                  <div className="info-message">
                    <Icon name="ui-tooltip" className="icon--secondary-color" />
                    <div className="info-message__copy">
                      <h5>{translations.SUMMARY.VALIDATE_TITLE}</h5>
                      {customValidateText ? (
                        <div dangerouslySetInnerHTML={{ __html: customValidateText }} />
                      ) : (
                        <>
                          <p>{isOffer ? translations.SUMMARY.VALIDATE_TEXT_OFFER : translations.SUMMARY.VALIDATE_TEXT_BOOKING}</p>
                          {allowOption && <p>{translations.SUMMARY.VALIDATE_TEXT_OPTION}</p>}
                        </>
                      )}
                      {localCheckboxes?.map((checkbox) => (
                        <div className="checkbox" key={checkbox.id}>
                          <label className="checkbox__label">
                            <input
                              type="checkbox"
                              className="checkbox__input"
                              checked={checkbox.isSelected}
                              onChange={() => handleCheckboxChange(checkbox.id)}
                            />
                            <span className="checkbox__label-text" dangerouslySetInnerHTML={{ __html: checkbox.text }} />
                          </label>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div className="booking__navigator">
            {renderPreviousButton()}
            {allowOption && (
              <button
                title={translations.STEPS.SUBMIT_OPTION}
                className={buildClassName(['cta', !userValidated && 'cta--disabled'])}
                disabled={!userValidated}
                name="option">
                {translations.STEPS.SUBMIT_OPTION}
              </button>
            )}
            <button
              title={isOffer ? translations.STEPS.SUBMIT_OFFER : translations.STEPS.SUBMIT_BOOKING}
              className={buildClassName(['cta', !userValidated && 'cta--disabled'])}
              disabled={!userValidated}
              name="default">
              {isOffer ? translations.STEPS.SUBMIT_OFFER : translations.STEPS.SUBMIT_BOOKING}
            </button>
          </div>
        </form>
      )}
    </>
  );
};

export default SharedSummary;
