import { BookingOptionGroup, BookingOptionPax, PerPackageOption, PerUnitPackageOption } from '@qite/tide-client/build/types';
import { isEmpty } from 'lodash';
import React from 'react';
import { buildClassName } from '../../../shared/utils/class-util';
import NoneOption from './none-option';
import OptionItem from './option-item';
import OptionPaxCard from './option-pax-card';

interface OptionUnitGroupProps {
  unitIndex: number;
  optionId?: string;
  group: BookingOptionGroup<PerUnitPackageOption>;
  firstClassName: string;
  secondClassName: string;
  parentId: string;
  onGroupChange?: (group: BookingOptionGroup<PerUnitPackageOption>, unitIndex: number, optionId?: string) => void;
}

const OptionUnitGroup: React.FC<OptionUnitGroupProps> = ({ unitIndex, optionId, group, firstClassName, secondClassName, parentId, onGroupChange }) => {
  const handleOptionChange = (option: PerPackageOption, index: number) => {
    const updatedGroup = {
      ...group,
      options: group.options.map((o, i) => {
        return i === index
          ? option
          : {
              ...o,
              isSelected: option.requirementType === 2 || option.requirementType === 3 ? false : o.isSelected
            };
      })
    } as BookingOptionGroup<PerUnitPackageOption>;

    if (onGroupChange) onGroupChange(updatedGroup, unitIndex, optionId);
  };

  const handleChildGroupChange = (childGroup: BookingOptionGroup<PerUnitPackageOption>, unitIndex: number, optionId?: string) => {
    const updatedGroup = {
      ...group,
      options: group.options.map((groupOption) => {
        return groupOption.line.entryLineGuid === optionId
          ? {
              ...groupOption,
              groups: groupOption.groups.map((optionGroup) => {
                return optionGroup.name === childGroup.name ? childGroup : optionGroup;
              })
            }
          : groupOption;
      })
    };

    if (onGroupChange) onGroupChange(updatedGroup, unitIndex, optionId);
  };

  const handleOnPaxChange = (pax: BookingOptionPax[], index?: number) => {
    const updatedGroup = {
      ...group,
      options: group.options.map((groupOption, i) => {
        return {
          ...groupOption,
          pax: i === index ? pax : groupOption.pax
        };
      })
    };

    if (onGroupChange) onGroupChange(updatedGroup, unitIndex, optionId);
  };

  const handleNoneSelectionChanged = () => {
    const updatedGroup = {
      ...group,
      options: group.options.map((groupOption) => ({
        ...groupOption,
        isSelected: false
      }))
    };

    if (onGroupChange) onGroupChange(updatedGroup, unitIndex, optionId);
  };

  const selectedPrice = group.name === '' ? 0 : group.options.find((x) => x.isSelected)?.line.price ?? 0;

  return (
    <div className={firstClassName}>
      {group.title && <h4 className={secondClassName}>{group.title}</h4>}
      <table className={buildClassName(['table', 'table--striped'])}>
        <tbody>
          {group.options.map((option, index) => (
            <tr key={option.line.entryLineGuid}>
              <td>
                <div className={buildClassName(['tree', option.isSelected && 'tree--selected'])}>
                  <div className="tree__level">
                    <div className="tree__header">
                      <div className="tree__description-collapse">
                        <div
                          className={buildClassName([
                            (option.requirementType === 0 || option.requirementType === 1) && 'checkbox',
                            (option.requirementType === 2 || option.requirementType === 3) && 'radiobutton'
                          ])}>
                          <label
                            htmlFor={`${parentId}_${index}`}
                            className={buildClassName([
                              (option.requirementType === 0 || option.requirementType === 1) && 'checkbox__label',
                              (option.requirementType === 2 || option.requirementType === 3) && 'radiobutton__label'
                            ])}>
                            <OptionItem option={option} parentId={parentId} index={index} selectedPrice={selectedPrice} onOptionChange={handleOptionChange} />
                            {!isEmpty(option.groups) && (
                              <div className="tree__body">
                                {option.groups.map((optionGroup) => (
                                  <OptionUnitGroup
                                    unitIndex={unitIndex}
                                    optionId={option.line.entryLineGuid}
                                    group={optionGroup}
                                    firstClassName={'tree__level'}
                                    secondClassName={'tree__level-heading'}
                                    parentId={`${parentId}_${optionGroup.name}`}
                                    onGroupChange={handleChildGroupChange}
                                  />
                                ))}
                              </div>
                            )}
                            {!isEmpty(option.pax) && <OptionPaxCard pax={option.pax} parentIndex={index} onPaxChange={handleOnPaxChange} />}
                          </label>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </td>
            </tr>
          ))}
          <NoneOption group={group} parentId={parentId} handleNoneSelectionChanged={handleNoneSelectionChanged} />
        </tbody>
      </table>
    </div>
  );
};

export default OptionUnitGroup;
