import { forwardRef } from 'react';

import { Container } from '@cleartrip/ct-design-container';
import { Typography, TypographyVariant } from '@cleartrip/ct-design-typography';
import { makeStyles, useStyles, useWebMergeStyles } from '@cleartrip/ct-design-style-manager';
import { css } from '@emotion/css';

import { getBorderStyles, getLabelColor } from './style';
import { IRadio } from './type';

const webStaticStyles = {
  disabledRoot: css({
    cursor: 'not-allowed',
  }),
  hiddenInput: css({
    position: 'absolute',
    opacity: 0,
    width: 0,
    height: 0,
    margin: 0,
    padding: 0,
    border: 'none',
    pointerEvents: 'none',
  }),
};

const staticRadioStyles = makeStyles((theme) => ({
  root: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    gap: theme?.spacing[2],
    cursor: 'pointer',
    userSelect: 'none',
  },
  radioBtn: {
    width: theme?.spacing[5],
    height: theme?.spacing[5],
    borderRadius: theme?.border.radius[32],
    borderStyle: theme?.border.style.solid,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
}));

const Radio = forwardRef<HTMLInputElement, IRadio>(
  (
    { id, label, labelCTA, labelVariant, onChange, disabled = false, checked = false, styleConfig, rootProps = {} },
    ref,
  ) => {
    const dynamicStyles = useStyles(
      (theme) => ({
        radioBtn: getBorderStyles(theme, checked, disabled),
        label: {
          color: getLabelColor(disabled),
        },
      }),
      [checked, disabled],
    );

    const {
      root: customRootStyles = [],
      radioBtn: customRadioBtnStyles = [],
      labelContainer: customLabelContainerStyles = [],
    } = styleConfig || {};

    const handleRadioChange = () => {
      if (disabled) return;
      onChange?.();
    };

    const mergedRootClassName = useWebMergeStyles(
      [staticRadioStyles.root, ...(disabled ? [webStaticStyles.disabledRoot] : []), ...customRootStyles],
      [disabled, customRootStyles],
    );

    const mergedInputClassName = useWebMergeStyles([webStaticStyles.hiddenInput], []);

    const mergedRadioBtnClassName = useWebMergeStyles(
      [staticRadioStyles.radioBtn, dynamicStyles.radioBtn, ...customRadioBtnStyles],
      [dynamicStyles.radioBtn, customRadioBtnStyles],
    );

    return (
      <div id={`${id}-root`} className={mergedRootClassName} onClick={handleRadioChange} {...rootProps}>
        <input
          ref={ref}
          id={id}
          type='radio'
          checked={checked}
          disabled={disabled}
          onChange={handleRadioChange}
          className={mergedInputClassName}
          aria-labelledby={`${id}-label`}
        />
        <span className={mergedRadioBtnClassName} />
        <Container styleConfig={{ root: customLabelContainerStyles }}>
          {typeof label === 'string' ? (
            <Typography variant={TypographyVariant.B2} styleConfig={{ root: [dynamicStyles.label] }}>
              {label}
            </Typography>
          ) : (
            label
          )}
          {typeof labelCTA === 'string' ? (
            <Typography variant={labelVariant || TypographyVariant.B2} styleConfig={{ root: [dynamicStyles.label] }}>
              {labelCTA}
            </Typography>
          ) : (
            labelCTA
          )}
        </Container>
      </div>
    );
  },
);

Radio.displayName = 'Radio';

export default Radio;
