import './ExperienceInterActiveLiveClassModal.scss'
import React, { useRef, useState } from 'react'
import { Row } from 'antd/lib/grid'
import Modal from 'components/Modal'
import { Col } from 'antd/lib/grid'
import Button from 'antd/lib/button'
import { MediaUpload } from 'redux/Common/types'
import CoverUpload from './components/CoverUpload/CoverUpload'
import { Formik, FormikProps } from 'formik'
import ExperienceForm from './components/Form/Form'
import * as yup from 'yup'
import { useEffect } from 'react'
import isEmpty from 'lodash/isEmpty'
import pick from 'lodash/pick'
import notification from 'utils/notification'
import { selectExchangeRates } from 'redux/User/selector'
import { EXPERIENCE_STATUS, EXPERIENCE_TYPE } from 'redux/Experience/types'
import { getPriceWithExchangeRate } from 'utils/currency'
import useMiniumPrice from 'hooks/useMinimumPrice'
import { useSelector } from 'react-redux'
import momentTZ from 'moment-timezone'
import SelectTimeZoneDefault from 'components/SelectTimeZoneDefault'
import moment from 'moment'
import { JSONService } from 'utils/json-patch'
import { ExperienceItem } from 'models/talent/talent-profile-module.model'

export type ExperienceLiveClassFormValues = ExperienceItem & {
  timePicker?: momentTZ.Moment
  datePicker?: momentTZ.Moment
}

interface ExperienceInterActiveLiveClassModalProps {
  show: boolean
  isEdit: boolean
  item?: ExperienceItem
  onCancel?: () => void
  toggleModal: (value: boolean) => void
  onConfirmCallback: (item: ExperienceItem) => void
}

const initialFormValues: ExperienceLiveClassFormValues = {
  name: '',
  description: '',
  experiencePrice: undefined,
  duration: 0,
  timePicker: undefined,
  datePicker: undefined,
  visible: true
}

const ExperienceInterActiveLiveClassModal: React.FC<
  ExperienceInterActiveLiveClassModalProps
> = ({ show, isEdit, item, onCancel, toggleModal, onConfirmCallback }) => {
  const [minimumPrice, minimumPriceFormat] = useMiniumPrice()
  const formRef = useRef<FormikProps<ExperienceLiveClassFormValues>>(null)
  const exchangeRate = useSelector(selectExchangeRates)
  const [photo, setPhoto] = useState<MediaUpload>({})
  const [timezone, setTimeZone] = useState(momentTZ.tz.guess())
  const [initialValues, setInitialValues] =
    useState<ExperienceLiveClassFormValues>({ visible: true })

  const validateSchema = yup.object().shape({
    // Validate form field
    name: yup
      .string()
      .min(10, 'Minimum 10 characters.')
      .max(90, 'Maximum 90 characters.')
      .required('Enter your experience name'),
    description: yup.string().required('Enter your experience description'),
    duration: yup
      .number()
      .min(15 * 60, 'The minimum duration is 15 minutes')
      .max(120 * 60, 'The maximum duration is 120 minutes'),
    experiencePrice: yup
      .number()
      .typeError('Please enter the experience price')
      .required('Please enter the experience price')
      .test(
        'minimum',
        `The experience price must be at least ${minimumPriceFormat}.`,
        val => Number(val) >= minimumPrice || Number(val) === 0
      )
  })

  useEffect(() => {
    if (!show) return
    if (isEdit && item) {
      if (
        !!exchangeRate &&
        item?.experienceCreationCurrency?.toLowerCase() !==
          exchangeRate?.localCurrency.toLowerCase()
      ) {
        item.experiencePrice = getPriceWithExchangeRate(
          item.gbpExperiencePrice || 0,
          exchangeRate
        )
      }

      const baseTime = momentTZ(item.scheduleTime).tz(timezone)
      setInitialValues({
        ...pick(item, [
          'name',
          'description',
          'experiencePrice',
          'duration',
          'order',
          'scheduleTime',
          'visible'
        ]),
        datePicker: baseTime,
        timePicker: baseTime
      })
      setPhoto({ url: item.covers?.[0] })
    } else {
      const baseTime = momentTZ().tz(timezone)
      setInitialValues({
        ...initialFormValues,
        datePicker: baseTime,
        timePicker: baseTime
      })
      setPhoto({})
    }
  }, [show, isEdit, item, item])

  useEffect(() => {
    const date = formRef.current?.values.datePicker
    const time = momentTZ(formRef.current?.values.timePicker)
    const baseTime = momentTZ(date)
      .set({
        hour: time.get('hour'),
        minute: time.get('minute'),
        second: time.get('second')
      })
      .tz(timezone)
    formRef.current?.setValues(values => ({
      ...values,
      datePicker: baseTime,
      timePicker: baseTime
    }))
  }, [timezone])

  const uploadPhotoSuccess = (file: MediaUpload) => {
    setPhoto(file)
  }

  const removePhoto = () => {
    setPhoto({})
  }

  const handleSubmit = async (formProps: ExperienceLiveClassFormValues) => {
    if (!photo.url) {
      notification.warn({ message: 'Please add the Cover Photo' })
      return
    }

    if (formProps.timePicker && formProps.datePicker) {
      const date = formProps?.datePicker
      const time = moment(formProps?.timePicker)
      formProps.scheduleTime = moment(date)
        .set({
          hour: time.get('hour'),
          minute: time.get('minute'),
          second: time.get('second')
        })
        .utc()
        .toISOString()
    }

    const itemUpdate = {
      ...item,
      ...formProps,
      covers: [photo.url as string],
      experienceCreationCurrency:
        item?.experienceCreationCurrency || exchangeRate?.localCurrency,
      type: EXPERIENCE_TYPE.INTERACTIVE_LIVE_CLASS,
      status: EXPERIENCE_STATUS.PUBLISHED
    }

    const patch = JSONService.getPatch(itemUpdate, item, {
      actions: ['add', 'remove', 'replace'] // actions
    })

    onConfirmCallback({
      ...itemUpdate,
      isUpdate: item?.isUpdate ? item.isUpdate : !isEmpty(patch)
    })

    toggleModal(false)
  }

  const handleCancel = () => {
    if (!isEdit && onCancel) {
      onCancel()
    } else {
      toggleModal(false)
    }
  }

  return (
    <React.Fragment>
      <Modal
        width={664}
        closable
        centered
        className="experience-live-class-modal"
        title="Fill the details"
        visible={show}
        onCancel={() => toggleModal(false)}
        destroyOnClose
        maskClosable={false}
      >
        <div className="experience-live-class__content">
          <div className="m__b--32">
            <CoverUpload
              photo={photo}
              onUploadSuccess={uploadPhotoSuccess}
              onRemove={removePhoto}
            />
          </div>
          <Formik
            innerRef={formRef}
            enableReinitialize={isEdit}
            initialValues={initialValues}
            onSubmit={handleSubmit}
            validationSchema={validateSchema}
          >
            {props => (
              <React.Fragment>
                <ExperienceForm
                  {...props}
                  exchangeRate={exchangeRate}
                  isBooked={item?.isBooked}
                />
                <Row>
                  <Col span={24}>
                    <SelectTimeZoneDefault
                      selectClassName="experience-live-class__timezone"
                      onChange={value => setTimeZone(value)}
                    />
                  </Col>
                </Row>
              </React.Fragment>
            )}
          </Formik>
          <div className="experience-live-class__actions m__t--24">
            <Button
              className="ant-btn-xl ant-btn-uppercase"
              onClick={handleCancel}
            >
              {isEdit ? 'Cancel' : 'Go back'}
            </Button>
            <Button
              className="ant-btn-xl ant-btn-uppercase"
              type="primary"
              onClick={() => formRef.current?.handleSubmit()}
            >
              {isEdit ? 'Save' : 'Done'}
            </Button>
          </div>
        </div>
      </Modal>
    </React.Fragment>
  )
}

export default ExperienceInterActiveLiveClassModal
