import clsx from 'clsx';
import {BaseFieldProps} from './base-field-props';
import {getButtonSizeStyle, getIconSizeStyle} from '../../buttons/button-size';

export interface InputFieldStyle {
  label: string;
  input: string;
  wrapper: string;
  inputWrapper: string;
  adornment: string;
  append: {size: string; radius: string};
  size: {font: string; height: string};
  description: string;
  error: string;
}

export function getInputFieldClassNames(
  props: Omit<BaseFieldProps, 'value' | 'defaultValue' | 'onChange'> = {}
): InputFieldStyle {
  const {
    size = 'md',
    startAdornment,
    endAdornment,
    startAppend,
    endAppend,
    className,
    labelPosition,
    labelDisplay = 'block',
    inputClassName,
    inputWrapperClassName,
    unstyled,
    invalid,
    disabled,
    background = 'transparent',
    flexibleHeight,
  } = {...props};

  if (unstyled) {
    return {
      label: '',
      input: inputClassName || '',
      wrapper: className || '',
      inputWrapper: inputWrapperClassName || '',
      adornment: '',
      append: {size: '', radius: ''},
      size: {font: '', height: ''},
      description: '',
      error: '',
    };
  }

  const sizeClass = inputSizeClass({
    size: props.size,
    flexibleHeight,
  });
  const isInputGroup = startAppend || endAppend;
  const borderColor = invalid ? 'border-danger' : 'border-divider';
  const ringColor = invalid
    ? 'focus:ring-danger/focus focus:border-danger/60'
    : 'focus:ring-primary/focus focus:border-primary/60';

  return {
    label: clsx(
      labelDisplay,
      'first-letter:capitalize text-left',
      disabled && 'text-disabled',
      sizeClass.font,
      labelPosition === 'side' ? 'mr-16' : 'mb-4'
    ),
    input: clsx(
      'block text-left relative w-full appearance-none transition-shadow text',
      background === 'transparent' && 'bg-transparent',
      background === 'bg-alt' && 'bg-alt',
      background === 'bg-paper' && 'bg-paper',

      // radius
      !isInputGroup && 'rounded',
      startAppend && 'rounded-r rounded-l-none',
      endAppend && 'rounded-l rounded-r-none',

      // border
      !isInputGroup && `${borderColor} border`,
      startAppend && `${borderColor} border-y border-r`,
      endAppend && `${borderColor} border-y border-l`,
      !disabled && `focus:ring ${ringColor} focus:outline-none shadow-sm`,
      disabled && 'text-disabled cursor-not-allowed',
      inputClassName,
      sizeClass.font,
      sizeClass.height,
      startAdornment ? 'pl-46' : 'pl-12',
      endAdornment ? 'pr-46' : 'pr-12'
    ),
    adornment: getIconSizeStyle(size),
    append: {
      size: getButtonSizeStyle(size),
      radius: startAppend ? 'rounded-l' : 'rounded-r',
    },
    wrapper: clsx(className, sizeClass.font, {
      'flex items-center': labelPosition === 'side',
    }),
    inputWrapper: clsx(
      'relative',
      inputWrapperClassName,
      isInputGroup && 'flex items-stretch'
    ),
    size: sizeClass,
    description: 'text-muted pt-10 text-xs',
    error: 'text-danger pt-10 text-xs',
  };
}

export function inputSizeClass({size, flexibleHeight}: BaseFieldProps) {
  switch (size) {
    case 'xs':
      return {font: 'text-xs', height: flexibleHeight ? 'min-h-30' : 'h-30'};
    case 'sm':
      return {font: 'text-sm', height: flexibleHeight ? 'min-h-36' : 'h-36'};
    case 'lg':
      return {font: 'text-lg', height: flexibleHeight ? 'min-h-50' : 'h-50'};
    case 'xl':
      return {font: 'text-xl', height: flexibleHeight ? 'min-h-60' : 'h-60'};
    default:
      return {font: 'text-sm', height: flexibleHeight ? 'min-h-42' : 'h-42'};
  }
}
