import React, { forwardRef } from "react";
import styled, { css } from "styled-components";
import { theme } from "../../../css/globalStyle";
import { MdCancel } from "react-icons/md";
import { Box } from "../../layout/Box";

const inputStyle = css`
  width: 100%;
  height: 48px;
  border-radius: 5px;
  padding: 0.75rem 1rem;
  border: 1px solid ${theme.color.grey[400]};
  outline: none;
  font-weight: 400;
  transition: box-shadow 200ms;
  box-sizing: border-box;

  &:hover {
    box-shadow: ${theme.shadow.input.primary};
  }

  &:focus {
    border: 1px solid ${theme.color.primary[500]};
    box-shadow: ${theme.shadow.input.primary};
  }
`;

const standardInputStyle = css`
  border-color: ${theme.color.grey[400]};

  &:hover {
    box-shadow: ${theme.shadow.input.primary};
  }

  &:focus {
    border-color: ${theme.color.primary[500]};
    box-shadow: ${theme.shadow.input.primary};
  }
`;

const errorInputStyle = css`
  border: 1px solid ${theme.color.error[500]};

  &:hover {
    box-shadow: ${theme.shadow.input.error};
  }

  &:focus {
    border-color: ${theme.color.error[500]};
    box-shadow: ${theme.shadow.input.error};
  }
`;

const InputContainer = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0.5rem 0;
  position: relative;
`;

export const LabelContainer = styled.div`
  display: flex;
  justify-content: space-between;
`;

export const Title = styled.div<{ flex?: boolean }>`
  margin-bottom: ${({ flex }) => (flex ? "" : "0.5rem")};
`;

export const Label = styled.label`
  color: ${theme.color.grey[900]};
  display: inline-block;
`;

export const Description = styled.div`
  color: ${theme.color.grey[700]};
`;

export const FieldErrMessage = styled.div.attrs({
  className: "fw5 f6 animate__animated animate__fadeIn faster"
})`
  color: ${theme.color.error[500]};
  margin-top: 0.25rem;
`;

export const Input = styled.input<{ error: boolean }>`
  ${inputStyle};
  ${({ error }) => (error ? errorInputStyle : standardInputStyle)};
`;

export const TextArea = styled.textarea<{ error: boolean }>`
  ${inputStyle};
  ${({ error }) => (error ? errorInputStyle : standardInputStyle)};
`;

const Icon = styled(MdCancel)`
  position: absolute;
  right: 8px;
  top: 13px;
`;

interface TextFieldProps {
  textarea?: boolean;
  label?: string;
  description?: string;
  type?: string;
  name?: string;
  inputLabel?: string;
  placeholder?: string;
  onChange?: (
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => void;
  value?: string;
  reset?: () => void;
  id?: string;
  error?: string;
  subComponent?: JSX.Element;
}

type InputType = TextFieldProps &
  React.InputHTMLAttributes<HTMLInputElement> &
  React.InputHTMLAttributes<HTMLTextAreaElement>;

export const TextField = forwardRef<
  HTMLInputElement | HTMLTextAreaElement,
  InputType
>(
  (
    {
      name,
      description,
      label,
      textarea,
      error,
      subComponent,
      value,
      reset,
      ...rest
    },
    ref
  ) => {
    const displayTitle = !!label || !!subComponent || !!description;

    return (
      <InputContainer>
        {displayTitle && (
          <Title>
            <LabelContainer>
              {label && <Label htmlFor={name}>{label}</Label>}
              {subComponent && subComponent}
            </LabelContainer>
            {description && <Description>{description}</Description>}
          </Title>
        )}

        <Box position="relative">
          {textarea ? (
            <TextArea
              value={value}
              error={!!error}
              name={name}
              ref={ref as React.RefObject<HTMLTextAreaElement>}
              {...rest}
            />
          ) : (
            <Input
              value={value}
              error={!!error}
              name={name}
              ref={ref as React.RefObject<HTMLInputElement>}
              {...rest}
            />
          )}

          {!!value && !!reset && (
            <Icon size="22px" color={theme.color.grey[600]} onClick={reset} />
          )}
        </Box>

        {error && <FieldErrMessage>{error}</FieldErrMessage>}
      </InputContainer>
    );
  }
);
