import * as React from "react"
import styled, { css } from "styled-components"
import breakpoint from "styled-components-breakpoint"
import { RatingStarIndicator } from "../Book"
import withTranslate from "jamplay-common/i18n/withTranslate"
import gql from "graphql-tag"
import { Header, HeaderSize } from "../Header"
import { Textarea } from "../Textarea"
import { RatingStarInput } from "./RatingStarInput"
import { getConfig } from "jamplay-common/remote-config"
import { Primary } from "../Button"

// default constant
const DEFAULT_MAX_REVIEW_CHARACTER_LENGTH = 200

// utility
function calculateTotalCount(ratingInfo: RatingInfoData[]) {
  return ratingInfo.reduce((prev, current) => {
    return prev + current.count
  }, 0)
}

export function calculateRatingResult(ratingInfo: RatingInfoData[]) {
  // finding average of result
  const sum = ratingInfo.reduce((prev, current) => {
    return prev + current.count * current.rating
  }, 0)

  const totalCount = calculateTotalCount(ratingInfo)

  const result = sum / totalCount

  if (isNaN(result)) {
    return 0
  }
  return Number(result.toFixed(2))
}

export function calculatePercentPerBar(ratingInfo: RatingInfoData[]) {
  // calculate each bar percent
  const totalCount = calculateTotalCount(ratingInfo)

  return ratingInfo.map((item) => {
    let indicatorLevel = item.count / totalCount
    if (isNaN(indicatorLevel)) {
      indicatorLevel = 0
    }
    return {
      ...item,
      indicatorLevel: Number(indicatorLevel.toFixed(2))
    }
  })
}

const ReviewSummaryMobileStyle = css``

const ReviewSummaryStyleContainer = styled.div.attrs({
  className: "ReviewSummary"
})`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;

  .RatingStarIndicator--stars-container {
    margin: 0;
  }

  .ReviewSummary__rating-summary {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    .ReviewSummary__rating-statistic {
      display: flex;
      width: 100%;
      flex-direction: column;
      align-items: center;
    }
  }

  .ReviewSummary__rating-input--disabled {
    padding-top: 20px;
    white-space: pre-line;
    text-align: center;

    margin: 21px 0;
    font-weight: normal;

    color: #bbb;
  }
  .ReviewSummary__rating-input {
    padding-top: 20px;
    width: 100%;
    flex: 1 1 auto;
    text-align: center;
    .StarIndicator {
      justify-content: center;
    }
  }

  ${breakpoint("mobile", "tablet")`${ReviewSummaryMobileStyle}`};
  h3,
  h4,
  .RatingStarContainer__label {
    white-space: nowrap;
  }

  .RatingStarContainer span {
    display: none;
  }
  .RatingStarIndicator--stars-container .jamplay-icon {
    font-size: 1.2rem;
    line-height: 1.2rem;
  }
  .ReviewSummary__star-input {
    margin: 13px 0;
  }
  .ReviewSummary__star-input
    .RatingStarIndicator--stars-container
    .jamplay-icon {
    font-size: 2rem;
    line-height: 2rem;
  }
  .ReviewSummary__rating-wrap {
    display: flex;
    padding: 0px 8px;
    line-height: 15px;
  }
  .ReviewSummary__rating-bar {
    height: 15px;
    width: 180px;
    position: relative;
    background-color: ${(props) => props.theme.borderGrey};
    margin: 3px 5px;
    border-radius: 4px;
    box-sizing: border-box;
    overflow: hidden;
    margin-left: 3px;
  }
  .ReviewSummary__labels {
    min-width: 42px;
  }
  .ReviewSummary__rating-bar__indicator {
    position: absolute;
    left: 0%;
    top: 0%;
    height: 100%;
    background-color: ${(props) => props.theme.pumpkin};
  }
  .ReviewSummary__confirm-review-button {
    margin-top: 10px;
  }
`

// Review Component section
export type ReviewValue = {
  content: string
  rating: number
}
export interface ReviewSummaryInputState {
  // Review Input value
  disabledReviewButton?: boolean
  isEdit?: boolean
  onReviewConfirm: (value: ReviewValue) => void
  onReviewChange: (value: ReviewValue) => void
  reviewValue: ReviewValue
  showReviewForm?: boolean
  disabledReviewFormReason?: string | null
  style?: any
}
export interface ReviewSummaryPropTypes {
  ref?: any
  bookRating: {
    eachCount: RatingInfoData[]
    count: number
    average: number
  }
}
type ReviewSummaryComponent = React.SFC<
  ReviewSummaryPropTypes & withTranslatePropType & ReviewSummaryInputState
> & { fragments?: { bookRating: any } }

export const ReviewSummary: ReviewSummaryComponent = (props) => {
  const result = calculateRatingResult(props.bookRating.eachCount)
  const total = calculateTotalCount(props.bookRating.eachCount)
  const bars = calculatePercentPerBar(props.bookRating.eachCount)

  let { t } = props
  if (!t) {
    t = (s) => s
  }

  const translate = t

  const onConfirmReviewClick = () => props.onReviewConfirm(props.reviewValue)

  const onStarChange = (starIndex) =>
    props.onReviewChange({
      ...props.reviewValue,
      rating: starIndex
    })
  const onTextChange = (e) =>
    props.onReviewChange({
      ...props.reviewValue,
      content: e.target.value
    })

  return (
    <ReviewSummaryStyleContainer style={props.style} innerRef={props.ref}>
      <div className="ReviewSummary__rating-summary">
        <div className="ReviewSummary__rating-statistic">
          <Header size={HeaderSize.three}>
            {t("review/rating-header", {
              avg: (props.bookRating.average || 0).toFixed(2)
            })}
          </Header>
          <RatingStarIndicator average={result} count={total} />
          <Header size={HeaderSize.four}>
            {translate("book/review-infomation-header", {
              count: props.bookRating.count
            })}
          </Header>
        </div>
        {bars.map((bar) => {
          return (
            <div key={bar.rating} className="ReviewSummary__rating-wrap">
              <span className="ReviewSummary__labels">
                {translate("review/rating", { rating: bar.rating })}
              </span>
              <div className="ReviewSummary__rating-bar">
                <div
                  style={{ width: `${bar.indicatorLevel * 100}%` }}
                  className="ReviewSummary__rating-bar__indicator"
                />
              </div>
              <span>{`(${bar.count})`}</span>
            </div>
          )
        })}
      </div>
      {props.disabledReviewFormReason ? (
        <Header size={HeaderSize.four} className="ReviewSummary__rating-input--disabled">
          {translate(props.disabledReviewFormReason)}
        </Header>
      ) : (
        <div className="ReviewSummary__rating-input">
          <Header size={HeaderSize.four}>{translate("review/rating-start-input-label")}</Header>
          <div className="ReviewSummary__star-input">
            <RatingStarInput
              value={props.reviewValue.rating}
              onChange={onStarChange}
            />
          </div>
          <div style={{ width: 310, margin: "auto" }}>
            <Textarea
              value={props.reviewValue.content}
              maxLength={
                getConfig().remoteRuntimeConfig.MAX_REVIEW_CHARACTER_LENGTH
                  ? Number(
                      getConfig().remoteRuntimeConfig
                        .MAX_REVIEW_CHARACTER_LENGTH
                    )
                  : DEFAULT_MAX_REVIEW_CHARACTER_LENGTH
              }
              placeholder={translate("review/input-placeholder")}
              onChange={onTextChange}
            />
          </div>
          <Primary
            disabled={
              props.reviewValue.content.length <= 0 ||
              props.reviewValue.rating <= 0 ||
              !!props.disabledReviewButton
            }
            className="ReviewSummary__confirm-review-button"
            onClick={onConfirmReviewClick}
          >
            {translate(
              props.isEdit
                ? "review/confirm-edit-review"
                : "review/confirm-review"
            )}
          </Primary>
        </div>
      )}
    </ReviewSummaryStyleContainer>
  )
}
ReviewSummary.defaultProps = {
  bookRating: {
    count: 0,
    average: 0,
    eachCount: []
  },
  reviewValue: {
    content: "",
    rating: 0
  }
}
ReviewSummary.fragments = {
  bookRating: gql`
    fragment ReviewSummary__BookRatingData on BookRating {
      count
      average
      eachCount {
        rating
        count
      }
    }
  `
}

export default withTranslate(ReviewSummary) as ReviewSummaryComponent & {
  fragments: { bookRating: any }
}
