import { useState } from 'react'
import dynamic from 'next/dynamic'
import { EditorState, ContentState, convertToRaw } from 'draft-js'
const Editor = dynamic(
  () => import('react-draft-wysiwyg').then(mod => mod.Editor),
  { ssr: false }
)
import draftToHtml from 'draftjs-to-html'
import htmlToDraft from 'html-to-draftjs'
import styled from 'styled-components'
import { useFormik } from 'formik'
import * as Yup from 'yup'

const schema = Yup.object().shape({
  name: Yup.string().min(1).max(20).required('Required'),
  email: Yup.string().min(6).max(50).required('Required'),
  message: Yup.string().min(1).max(100).required('Required')
})

export default function Reviews({ id, reviewList }) {

  const [ isEditorReadOnly, setIsEditorReadOnly ] = useState(false)
  const [ sameEmailError, setSameEmailError ] = useState(false)

  const formik = useFormik({
    initialValues: { name: '', email: '', message: '' },
    onSubmit: async (values, { resetForm }) => {

      setIsEditorReadOnly(true)

      await fetch(`/api/postReview?productId=${id}&name=${values.name}&email=${values.email}&reviewText=${encodeURIComponent(values.message)}`)
        .then(res => {
          if (res.status >= 400) {

            if (res.status === 400) {
              console.log(res.status, res)
              setSameEmailError(res.statusText)

              const err = new Error(res.statustext)

              setIsEditorReadOnly(false)

              throw err
            } else if (res.status > 400) {
              setSameEmailError(false)

              const err = new Error('Error')
  
              setIsEditorReadOnly(false)
  
              throw err
            }
          }
          return res.json()
        })
        .then(data => {
          resetForm()
          setEditorState(EditorState.push(editorState, ContentState.createFromText('')))

          setSameEmailError(false)
          
          const publishedReview = data.data.createReview.data    
          reviewList.push(publishedReview)
    
          setIsEditorReadOnly(false)

          const headingElement = document.getElementById('heading')
          headingElement.scrollIntoView({ behavior: 'smooth' })
        })
        .catch(err => console.error(err))
    },
    validationSchema: schema
  })

  const [ reviews, setReviews ] = useState(reviewList)

  const value = formik.values.message
  
  const prepareDraft = value => {
    const draft = htmlToDraft(value)
    const contentState = ContentState.createFromBlockArray(draft.contentBlocks)
    const editorState = EditorState.createWithContent(contentState)

    return editorState
  }

  const setFieldValue = val => formik.setFieldValue('message', val)

  const [ editorState, setEditorState ] = useState(value ? prepareDraft(value) : EditorState.createEmpty())

  const onEditorStateChange = editorState => {
    const forFormik = draftToHtml(
      convertToRaw(editorState.getCurrentContent())
    )
    setFieldValue(forFormik)
    setEditorState(editorState)
  }

  return (
    <ReviewsDiv>
      <div className="heading" id="heading">
        {
          reviews.length === 0
          ? 'No reviews so far. Be the first!'
          : 'Reviews'
        }
      </div>
      <div className="reviews">
        {
          reviews
            .sort((a, b) => (
              // sort by date, newest first ↓
              new Date(b.attributes.createdAt).getTime() - new Date(a.attributes.createdAt).getTime()
            ))
            .map(review => (
              <div className="review" key={review.id}>
                <div>
                  Reviewed at <b>{review.attributes.createdAt.slice(0, 10)}</b> by <b>{review.attributes.name}</b>:
                </div>
                <div dangerouslySetInnerHTML={{__html: review.attributes.reviewText}} className="review-text"></div>
              </div>
            ))
        }
      </div>
      <form className="form" onSubmit={formik.handleSubmit}>
        <div className="input-group">
          <div className="input-group-prepend">
            <span className="input-group-text" id="inputGroup-sizing-default">Name</span>
          </div>
          <input 
            type="text" 
            aria-label="Sizing example input" 
            aria-describedby="inputGroup-sizing-default" 
            pattern="[A-Za-z ]{1,32}"
            title="1 to 32 letters, no special symbols, except space"
            minLength="1"
            name="name"
            id="name" 
            required
            className="form-control" 
            value={formik.values.name}
            onChange={formik.handleChange}
          />
        </div>
        {formik.errors.name && <h1 className="feedback-msgs">{formik.errors.name}</h1>}
        <div className="input-group">
          <div className="input-group-prepend">
            <span className="input-group-text" id="inputGroup-sizing-default">E-mail</span>
          </div>
          <input 
            type="email" 
            aria-label="Sizing example input" 
            aria-describedby="inputGroup-sizing-default" 
            minLength="3"
            name="email"
            id="email"
            required
            className="form-control" 
            value={formik.values.email}
            onChange={formik.handleChange}
          />
        </div>
        {formik.errors.email && <h1 className="feedback-msgs">{formik.errors.email}</h1>}
        <div className="editor-top-wrapper">        
          <Editor
            editorState={editorState}
            readOnly={isEditorReadOnly}
            toolbarHidden={isEditorReadOnly}
            toolbarClassName="toolbar"
            wrapperClassName="wrapper"
            editorClassName="editor"
            onEditorStateChange={onEditorStateChange}
            toolbar={{
              options: ['inline', 'blockType', 'fontSize', 'fontFamily', 'list', 'textAlign', 'colorPicker', 'link', 'embedded', 'emoji', 'image', 'remove', 'history'],
              colorPicker: { popupClassName: 'colorPickerPopup' },
              link: { popupClassName: 'linkPopup' },
              emoji: { popupClassName: 'emojiPopup' },
              embedded: { popupClassName: 'embeddedPopup' },
              image: { popupClassName: 'imagePopup' }
            }}
          />
        </div>
        {formik.errors.message && <div className="feedback-msgs">{formik.errors.message}</div>}
        {
          sameEmailError 
          ? <div className="feedback-msgs">{sameEmailError}</div> 
          : null
        }
        <button type="submit" className="post-button btn btn-primary" disabled={isEditorReadOnly}>
          Post Review
        </button>
      </form>
    </ReviewsDiv>
  )
}

const ReviewsDiv = styled.div`
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: #ffffff;
  color: #212529;
  width: 100%;
  padding-bottom: 2em;
  padding-top: 2em;
  > .heading {
    align-self: stretch;
    padding: 0 2em .5em 2em;
    display: inline-block;
    text-align: center;
    vertical-align: middle;
    font-size: 1.5rem;
    line-height: 1.5;
    border-radius: 0.25rem;
  }
  > .reviews {
    display: flex;
    flex-direction: column;
    width: 100%;
    padding: 1em 2em 1em 2em;
    > .review {
      margin-bottom: 1em;
      > .review-text {
        border-radius: 5px;
        border: 1px solid grey;
        padding: 1rem;
      }
    } 
  }
  > .form {
    background: #e9e9e9;
    border: 1px solid #e9e9e9;
    padding: 1em;
    margin: 2em;
    max-width: 1136px;
    width: 100%;
    > .input-group {
      padding-bottom: 1em;
      align-items: stretch;
      width: 100%;
    }
    > .editor-top-wrapper {
      width: 100%;
      > .wrapper {
        width: 100%;
        .colorPickerPopup {
          top: 23px;
        }
        .linkPopup {
          left: -42px;
          top: 23px;
          height: 233px;
        }
        .emojiPopup {
          top: 23px;
          left: -148px;
        }
        .embeddedPopup {
          top: 23px;
          left: -111px;
        }
        .imagePopup {
          top: 23px;
          left: -186px;
        }
        > .toolbar {
          background: #e9e9e9;
          border: none;
        }
        > .editor {        
          width: 100%;
          padding: 0 1em 0 1em;
          background: #ffffff;
        }
      }
    }

    > .feedback-msgs {
      margin: 0 1em 1em 0;
      color: red;
      font-size: 1rem;
    }
    > .post-button {
      align-self: flex-start;
      margin: 1em 0 0 1em;
    }
  }


  @media only screen and (min-width: 850px) {
    grid-area: 4 / 1 / 6 / 3;
  }
`