import * as React from 'react';
import { useEffect } from 'react';
import styled from 'styled-components';

import type { JSX } from 'react';
import type { OptionalEmailSettings } from '@redocly/config';
import type { ReasonsProps } from '@redocly/theme/components/Feedback/Reasons';

import { breakpoints } from '@redocly/theme/core/utils';
import { useThemeHooks } from '@redocly/theme/core/hooks';
import { RadioCheckButtonIcon } from '@redocly/theme/icons/RadioCheckButtonIcon/RadioCheckButtonIcon';
import { Comment } from '@redocly/theme/components/Feedback/Comment';
import { Reasons } from '@redocly/theme/components/Feedback/Reasons';
import { Button } from '@redocly/theme/components/Button/Button';
import { MAX_EMAIL_LENGTH } from '@redocly/theme/core/constants';

export const MAX_SCALE = 10;

export type ScaleProps = {
  onSubmit: (value: {
    score: number;
    comment?: string;
    reasons?: string[];
    max?: number;
    email?: string;
  }) => void;
  settings?: {
    label?: string;
    submitText?: string;
    leftScaleLabel?: string;
    rightScaleLabel?: string;
    comment?: {
      hide?: boolean;
      label?: string;
    };
    reasons?: {
      hide?: boolean;
      label?: string;
      component?: string;
      items: string[];
    };
    optionalEmail?: OptionalEmailSettings;
  };
  className?: string;
};

export function Scale({ settings, onSubmit, className }: ScaleProps): JSX.Element {
  const {
    label,
    submitText,
    leftScaleLabel,
    rightScaleLabel,
    comment: commentSettings,
    reasons: reasonsSettings,
    optionalEmail: optionalEmailSettings,
  } = settings || {};
  const [score, setScore] = React.useState(0);
  const [isSubmitted, setIsSubmitted] = React.useState(false);
  const [comment, setComment] = React.useState('');
  const [reasons, setReasons] = React.useState([] as ReasonsProps['settings']['items']);
  const [email, setEmail] = React.useState<string>();
  const { useTranslate, useUserMenu } = useThemeHooks();
  const { userData } = useUserMenu();
  const { translate } = useTranslate();

  const onEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setEmail(value || undefined);
  };

  const scaleOptions = [];

  for (let i = 1; i <= MAX_SCALE; i++) {
    scaleOptions.push(
      <Button
        id={`scale-option-${i}`}
        key={`scale-option-${i}`}
        type="button"
        onClick={() => setScore(i)}
        className={`${score === i ? 'active' : ''}`}
      >
        {i}
      </Button>,
    );
  }

  const displayReasons = !!score && reasonsSettings && !reasonsSettings.hide;
  const displayComment = !!(score && !commentSettings?.hide);
  const displaySubmitBnt = !!score && (displayReasons || displayComment);
  const displayFeedbackEmail = !!score && !optionalEmailSettings?.hide && !userData.isAuthenticated;

  const handleCancel = () => {
    setScore(0);
    setComment('');
    setReasons([]);
    setEmail(undefined);
  };

  const onSubmitScaleForm = () => {
    const trimmedComment = comment?.trim() || undefined;
    const trimmedEmail = email?.trim() || undefined;
    onSubmit({
      score,
      comment: trimmedComment,
      reasons,
      max: MAX_SCALE,
      email: trimmedEmail,
    });
    setIsSubmitted(true);
  };

  useEffect(() => {
    if (score && !displayComment && !displayReasons && !displayFeedbackEmail) {
      onSubmitScaleForm();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [score, displayComment, displayReasons, displayFeedbackEmail]);

  if (isSubmitted) {
    return (
      <ScaleWrapper data-component-name="Feedback/Scale">
        <Label data-translation-key="feedback.settings.submitText">
          {submitText ||
            translate(
              'feedback.settings.submitText',
              'Thank you for helping improve our documentation!',
            )}
        </Label>
        <RadioCheckButtonIcon />
      </ScaleWrapper>
    );
  }

  return (
    <ScaleWrapper data-component-name="Feedback/Scale" className={className}>
      <StyledForm onSubmit={onSubmitScaleForm}>
        <StyledFormMandatoryFields>
          <Label data-translation-key="feedback.settings.label">
            {label || translate('feedback.settings.label', 'Was this helpful?')}
          </Label>

          <ScaleOptionsWrapper>{scaleOptions}</ScaleOptionsWrapper>

          <SubLabelContainer>
            <SubLabel data-translation-key="feedback.settings.leftScaleLabel">
              {leftScaleLabel ||
                translate('feedback.settings.leftScaleLabel', 'Not helpful at all')}
            </SubLabel>
            <SubLabel data-translation-key="feedback.settings.rightScaleLabel">
              {rightScaleLabel ||
                translate('feedback.settings.rightScaleLabel', 'Extremely helpful')}
            </SubLabel>
          </SubLabelContainer>
        </StyledFormMandatoryFields>
        <StyledFormOptionalFields>
          {displayReasons && (
            <Reasons
              settings={{
                label: reasonsSettings?.label,
                items: reasonsSettings?.items || [],
                component: reasonsSettings?.component,
              }}
              onChange={setReasons}
            />
          )}

          {displayComment && (
            <Comment
              standAlone={false}
              onSubmit={({ comment }) => setComment(comment)}
              settings={{
                label:
                  commentSettings?.label ||
                  translate(
                    'feedback.settings.comment.label',
                    'Please share your feedback with us.',
                  ),
              }}
            />
          )}
        </StyledFormOptionalFields>

        {displayFeedbackEmail && (
          <StyledFormOptionalFields>
            <InputLabel data-translation-key="feedback.settings.optionalEmail.label">
              {optionalEmailSettings?.label ||
                translate(
                  'feedback.settings.optionalEmail.label',
                  'Your email (optional, for follow-up)',
                )}
            </InputLabel>
            <EmailInput
              onChange={onEmailChange}
              placeholder={
                optionalEmailSettings?.placeholder ||
                translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
              }
              type="email"
              maxLength={MAX_EMAIL_LENGTH}
              required={!!email}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.preventDefault();
                  onSubmitScaleForm();
                }
              }}
            />
          </StyledFormOptionalFields>
        )}

        {displaySubmitBnt && (
          <ButtonsContainer>
            <Button
              data-translation-key="feedback.settings.comment.cancel"
              onClick={handleCancel}
              variant="text"
              size="small"
            >
              {translate('feedback.settings.comment.cancel', 'Cancel')}
            </Button>

            <Button
              data-translation-key="feedback.submit"
              type="submit"
              variant="secondary"
              size="small"
            >
              {translate('feedback.submit', 'Submit')}
            </Button>
          </ButtonsContainer>
        )}
      </StyledForm>
    </ScaleWrapper>
  );
}

const ScaleWrapper = styled.div`
  font-family: var(--feedback-font-family);
  display: flex;
  justify-content: space-between;
  align-items: center;
`;

const Label = styled.h4`
  font-family: var(--feedback-font-family);
  font-weight: var(--font-weight-regular);
  font-size: var(--feedback-header-font-size);
  line-height: var(--feedback-header-line-height);
  color: var(--feedback-header-text-color);
  margin: 0;
  width: 100%;
`;

const InputLabel = styled.h4`
  font-weight: var(--font-weight-regular);
  font-size: var(--feedback-font-size);
  line-height: var(--feedback-line-height);
  margin: 0;
`;

const SubLabelContainer = styled.div`
  display: flex;
  justify-content: space-between;
  width: 100%;
  flex-direction: row;
`;

const SubLabel = styled(Label)`
  width: fit-content;
  color: var(--text-color-description);
  font-size: var(--feedback-font-size);
  margin-bottom: var(--spacing-xxs);
`;

const StyledForm = styled.form`
  width: 100%;
  gap: var(--spacing-sm);
  display: flex;
  flex-direction: column;
`;

const ButtonsContainer = styled.div`
  display: flex;
  justify-content: end;
  margin-bottom: var(--spacing-xxs);
  gap: var(--spacing-xxs);
`;

const StyledFormOptionalFields = styled.div`
  display: flex;
  flex-flow: column;

  &:empty {
    display: none;
  }
`;

const StyledFormMandatoryFields = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-sm);
  align-items: center;
`;

const ScaleOptionsWrapper = styled.div`
  display: flex;
  justify-content: space-between;
  flex-direction: row;
  gap: var(--spacing-xxs);
  width: 100%;

  ${Button} {
    margin-left: 0;
  }

  @media screen and (max-width: ${breakpoints.small}) {
    gap: 2px;
  }
`;

const EmailInput = styled.input`
  background-color: var(--bg-color);
  border-radius: var(--border-radius-lg);
  border: var(--input-border);
  outline: none;
  color: var(--feedback-text-color);
  font-family: var(--feedback-font-family);
  padding: 10px;
`;
