/* eslint-disable @typescript-eslint/no-explicit-any */
import clsx from 'clsx';
import React, { PropsWithChildren } from 'react';
import { noop } from '../../../helpers/utils';
import { Button, ButtonContext } from '../../Buttons';
import { IconName } from '../../Icons';
import { TransformerFunction } from '../../Utils';
import { BaseFormElement } from '../Form.models';
import { FormElementContainer } from '../FormElementContainer';
import classes from './ReadOnlyTextField.scss';

export interface ReadOnlyTextFieldProps<T = any> extends BaseFormElement {
  /** Value to be displayed */
  value?: any;
  /** Hide copy to the clipboard button */
  hideCopyButton?: boolean;
  /** Transform functions */
  transform?: TransformerFunction<T>;
}
/**
 * This component renders a read only field into a form.
 * @props **transform**: an array of transform functions which will be executed sequentially during render time passing the output from each function to the next.
 * The last transform function must return a single object or array of a type which can be rendered directly _( i.e. string | number | string[] | number[] )_.
 */
export const ReadOnlyTextField = <T,>({
  value = '',
  transform,
  className = '',
  hideCopyButton = false,
  id,
  ...rest
}: PropsWithChildren<ReadOnlyTextFieldProps<T>>): JSX.Element => {
  const nonNullableValue = value === null ? '' : value;
  const transformedValue = transform
    ? transform(nonNullableValue)
    : nonNullableValue;
  const displayValue = Array.isArray(transformedValue)
    ? transformedValue.join(', ')
    : transformedValue;

  return (
    <FormElementContainer
      {...rest}
      className={clsx('read-only-field-container', className)}
      dataTestFieldType="ReadOnlyText"
      htmlFor={id}
    >
      <div className={clsx(classes.container)}>
        <input
          value={displayValue}
          onChange={noop}
          data-test-id="form-field-value"
          id={id}
        />
        {!hideCopyButton && (
          <Button
            type="button"
            icon={IconName.Copy}
            buttonContext={ButtonContext.Icon}
            className={clsx(classes.button)}
            onButtonClicked={() => {
              try {
                // copy display value to clipboard
                navigator.clipboard.writeText(displayValue ?? '');
              } catch (error) {
                // eslint-disable-next-line no-console
                console.warn('Failed to copy to clipboard');
              }
            }}
          />
        )}
      </div>
    </FormElementContainer>
  );
};
