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;
