import React, { forwardRef, useEffect, useState } from 'react';

import { Checkbox } from '@cleartrip/ct-design-checkbox';
import { Container } from '@cleartrip/ct-design-container';
import type { ContainerRef } from '@cleartrip/ct-design-container';
import { Typography, TypographyVariant } from '@cleartrip/ct-design-typography';
import { makeStyles } from '@cleartrip/ct-design-style-manager';

import { ICheckboxGroup, ICheckboxOption } from './type';

const staticCheckboxGroupStyles = makeStyles((theme) => {
  return {
    root: {
      padding: theme?.spacing[2],
    },
    heading: {
      display: 'flex',
      flexDirection: 'column',
      marginBottom: theme?.spacing[3],
      color: theme?.color.background.primary,
    },
    checkboxContainer: {
      display: 'flex',
      flexDirection: 'column',
      marginBottom: theme?.spacing[3],
    },
  };
});

const CheckboxGroup = forwardRef<ContainerRef, ICheckboxGroup>(
  ({ checkboxList, heading, onClick, styleConfig, isMulti = true }, ref) => {
    const [selectedOptions, setSelectedOptions] = useState<ICheckboxOption[]>([]);

    const {
      root: customRootStyles = [],
      heading: customHeadingStyles = [],
      checkboxContainer: customCheckboxContainerStyles = [],
    } = styleConfig || {};

    useEffect(() => {
      const initialSelectedOptions = checkboxList?.filter((option) => option?.checked) ?? [];
      if (!isMulti && initialSelectedOptions.length > 1) {
        throw new Error('Multiple selected options are not allowed in single selection mode');
      }
      setSelectedOptions(initialSelectedOptions);
    }, [checkboxList, isMulti]);

    const handleOptionClick = (selectedOption: ICheckboxOption) => {
      let newSelectedOptions = [...selectedOptions];
      const optionIndex = newSelectedOptions.findIndex((option) => option.id === selectedOption.id);
      if (optionIndex >= 0) {
        if (isMulti) newSelectedOptions.splice(optionIndex, 1);
        else newSelectedOptions = [];
      } else if (isMulti) {
        newSelectedOptions.push(selectedOption);
      } else {
        newSelectedOptions = [selectedOption];
      }
      setSelectedOptions(newSelectedOptions);
      onClick?.(selectedOption, newSelectedOptions);
    };

    return (
      <Container ref={ref} styleConfig={{ root: [staticCheckboxGroupStyles?.root, ...customRootStyles] }}>
        {!!heading &&
          (typeof heading === 'string' ? (
            <Typography
              variant={TypographyVariant.B2}
              styleConfig={{ root: [staticCheckboxGroupStyles?.heading, ...customHeadingStyles] }}
            >
              {heading}
            </Typography>
          ) : (
            heading
          ))}
        {checkboxList?.map((checkboxOption: ICheckboxOption) => {
          const isChecked = selectedOptions.some((option) => option?.id === checkboxOption?.id);
          return (
            <Container
              key={checkboxOption.id}
              styleConfig={{ root: [staticCheckboxGroupStyles?.checkboxContainer, ...customCheckboxContainerStyles] }}
            >
              <Checkbox {...checkboxOption} onChange={handleOptionClick} checked={isChecked} />
            </Container>
          );
        })}
      </Container>
    );
  },
);

CheckboxGroup.displayName = 'CheckboxGroup';

export default CheckboxGroup;
