import { range } from 'lodash';
import React, { useContext, useEffect, useState } from 'react';
import { buildClassName } from '../../shared/utils/class-util';
import { getTranslations } from '../../shared/utils/localization-util';
import SettingsContext from '../settings-context';
import { ProductRoom } from '../types';
import AgeSelect from './age-select';
import AmountInput from './amount-input';
import Icon from '../../shared/components/icon';

interface RoomsProps {
  rooms: ProductRoom[];
  isDisabled: boolean;
  setIsDisabled: (isOpen: boolean) => void;
  onChange: (rooms: ProductRoom[]) => void;
}

const Rooms: React.FC<RoomsProps> = ({ rooms, isDisabled, setIsDisabled, onChange }) => {
  const [isTouched, setIsTouched] = useState<boolean>(false);
  const [currentRooms, setRoomState] = useState<ProductRoom[]>(rooms);

  useEffect(() => {
    setRoomState(rooms);
  }, [rooms]);

  const { language, customTranslations, disableRooms } = useContext(SettingsContext);
  const translations = getTranslations(language, customTranslations);

  // When `disableRooms` is set, the adults/children inputs are always editable
  // (no edit/apply gate) and changes are propagated immediately.
  const effectiveIsDisabled = disableRooms ? false : isDisabled;

  // Notify parent that the form is always "applied" when rooms editing is
  // disabled — otherwise the Book button would never enable (it watches
  // `roomsIsDisabled`).
  useEffect(() => {
    if (disableRooms && !isDisabled) {
      setIsDisabled(true);
    }
  }, [disableRooms]);

  const commitIfDisabledMode = (nextRooms: ProductRoom[]) => {
    if (disableRooms) {
      onChange(nextRooms);
    } else {
      setIsTouched(true);
    }
  };

  const handleCloseClick = () => {
    setIsDisabled(true);
    if (isTouched) onChange(currentRooms);
  };

  return (
    <div className="booking-product__rooms">
      <div className="booking-product__rooms-title">
        <Icon name="ui-user" width={25} height={25} />
        {translations.PRODUCT.WHO_YOU_TRAVELING_WITH}
      </div>
      <div className="booking-product__rooms__container">
        <div className="booking-product__rooms__wrapper">
          {!disableRooms && (
            <div className="booking-product__rooms__header">
              <div className="booking-product__rooms__heading">{translations.SHARED.ROOMS}</div>
              <div className="booking-product__rooms__actions">
                <AmountInput
                  label={translations.PRODUCT.NUMBER_OF_ROOMS}
                  value={currentRooms.length}
                  disabled={effectiveIsDisabled}
                  min={1}
                  onChange={(value) => {
                    setRoomState(
                      range(0, value).map(
                        (roomIndex) =>
                          currentRooms[roomIndex] ?? {
                            adults: 2,
                            children: 0,
                            childAges: []
                          }
                      )
                    );

                    setIsTouched(true);
                  }}
                />
              </div>
            </div>
          )}
          <div className="booking-product__rooms-body">
            {currentRooms.map((room, roomIndex) => (
              <div className="booking-product__room" key={roomIndex}>
                <div className="booking-product__room__header">
                  {!disableRooms && <h3 className="booking-product__room__heading">{translations.SHARED.ROOM + ' ' + (roomIndex + 1)}</h3>}
                  <div className="booking-product__room__actions">
                    <AmountInput
                      label={translations.SHARED.ADULTS}
                      value={room.adults}
                      disabled={effectiveIsDisabled}
                      min={1}
                      onChange={(value) => {
                        const next = currentRooms.map((room, i) => (i === roomIndex ? { ...room, adults: value } : room));
                        setRoomState(next);
                        commitIfDisabledMode(next);
                      }}
                    />
                    <AmountInput
                      label={translations.SHARED.CHILDREN}
                      value={room.children}
                      disabled={effectiveIsDisabled}
                      onChange={(value) => {
                        const next = currentRooms.map((room, i) =>
                          i === roomIndex
                            ? {
                                ...room,
                                children: value,
                                childAges: range(0, value).map((childIndex) => room.childAges[childIndex] ?? 0)
                              }
                            : room
                        );
                        setRoomState(next);
                        commitIfDisabledMode(next);
                      }}
                    />
                  </div>
                </div>
                {room.children > 0 && (
                  <div className="booking-product__room-children">
                    <label className="booking-product__room-children-label">{translations.PRODUCT.AGE_BY_DEPARTURE_DATE}</label>
                    <div className="booking-product__room-children-ages">
                      {range(0, room.children).map((childIndex) => (
                        <AgeSelect
                          key={childIndex}
                          value={room.childAges[childIndex]}
                          disabled={effectiveIsDisabled}
                          onChange={(value) => {
                            const next = currentRooms.map((room, selectorRoomIndex) =>
                              roomIndex === selectorRoomIndex
                                ? {
                                    ...room,
                                    childAges: room.childAges.map((age, i) => (childIndex === i ? value : age)).sort((a, b) => b - a)
                                  }
                                : room
                            );
                            setRoomState(next);
                            commitIfDisabledMode(next);
                          }}
                        />
                      ))}
                    </div>
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
        {!disableRooms && (
          <div className="booking-product__rooms-footer">
            {isDisabled ? (
              <button
                type="button"
                className={buildClassName(['cta--secondary', 'cta--add'])}
                title={translations.PRODUCT.EDIT}
                onClick={() => {
                  setIsDisabled(false);
                  setIsTouched(false);
                }}>
                <span>
                  <Icon name="ui-pencil" width={25} height={25} />
                  {translations.PRODUCT.EDIT}
                </span>
              </button>
            ) : (
              <button
                type="button"
                className={buildClassName(['cta', isTouched ? 'cta--secondary' : 'cta--secondary', 'cta--add'])}
                title={translations.PRODUCT.APPLY}
                onClick={handleCloseClick}>
                <span>
                  <Icon name="ui-check" />
                  {translations.PRODUCT.APPLY}
                </span>
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

export default Rooms;
