import { Alert, Button, Checkbox, Col, Row, Switch, Tooltip } from 'antd'
import ConfirmDeleteModal from 'components/ConfirmDeleteModal'
import DotLoading from 'components/DotLoading'
import DragDropContext from 'components/DragDropContext'
import { AntInputNumber } from 'components/Form/FormItem'
import { Icon, IconName } from 'components/Icon'
import PodcastFieldItem from 'components/PodcastFieldItem'
import PortalComponent from 'components/PortalComponent/PortalComponent'
import { Paragraph } from 'components/Typography'
import { defaultPodcastTags } from 'constants/social'
import { Field, Form, Formik } from 'formik'
import reduce from 'lodash/reduce'
import { PodcastItem } from 'models/talent/talent-profile-module.model'
import * as React from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { SocialProfileLinkTypes } from 'redux/User/types'
import { talentService } from 'services'
import { PodcastSyncLatestParams, PodcastValidateParams } from 'types'
import notification from 'utils/notification'
import { ValidatePodcast, validatePodcastByType } from 'utils/validate'
import PodCastAutomationReview from './PodCastAutomationReview'
import includes from 'lodash/includes'
import PodcastWarningModal from 'components/PodcastWarningModal'

const PodcastFieldItemMemo = React.memo(PodcastFieldItem)
const defaultSyncPodcasts = [
  {
    key: SocialProfileLinkTypes.APPLE_PODCAST,
    icon: 'apple-podcast',
    name: 'Apple Podcast',
    active: false,
    isFirstActive: true
  },
  {
    key: SocialProfileLinkTypes.SPOTIFY,
    icon: 'spotify',
    name: 'Spotify',
    active: false,
    isFirstActive: true
  }
]

interface SyncLatestPodcastContentProps {
  show?: boolean
  cancellable?: boolean
  item?: PodcastItem
  step?: number
  setStep?: (value: number) => void
  close?: () => void
  back?: () => void
  callback: (values: any, action?: any) => void
  onConnectSpotify?: () => void
}
const SyncLatestPodcastContent = ({
  show,
  item,
  cancellable,
  close,
  back,
  callback,
  step,
  setStep,
  onConnectSpotify
}: SyncLatestPodcastContentProps) => {
  const [loading, setLoading] = useState(false)
  const [podcastLinks, setPodcastLinks] = useState(defaultSyncPodcasts)

  const [submitData, setSubmitData] = useState<any>({})
  const [visibleWarning, setVisibleWarning] = useState(false)
  const [visibleWarningValidate, setVisibleWarningValidate] = useState(false)
  const [responseValidate, setResponseValidate] = useState(false)
  const [errors, setErrors] = useState<any>({})
  const [activeLatestPodcast, setActiveLatestPodcast] = useState(true)
  const [allowBypassWarning, setAllowBypassWarning] = useState(false)
  const [initValues, setInitValues] = useState({
    numberOfEpisodes: item?.numberOfEpisodes || 1
  })
  const [episodes, setEpisodes] = useState([])

  useEffect(() => {
    if (show) {
      if (item) {
        const editLinks: any = item.links.map((item: any) => {
          const link = defaultPodcastTags.find(el => el.key === item.type)
          return {
            ...link,
            value: item.url,
            active: item.active,
            isFirstActive: !item.url
          }
        })
        setPodcastLinks(editLinks)
        const initValues = item.links.reduce((values: any, item: any) => {
          return { ...values, [item.type as string]: item.url }
        }, {})
        setInitValues({
          numberOfEpisodes: item?.numberOfEpisodes || 1,
          ...initValues
        })
        setActiveLatestPodcast(item.activeLatestPodcast as boolean)
        return
      }
      setPodcastLinks(
        defaultSyncPodcasts.map((item: any) => ({
          ...item,
          active: false,
          isFirstActive: true
        }))
      )
    }
  }, [item, show])

  const caption = useMemo(() => {
    return !!item || cancellable ? 'CANCEL' : 'PREVIOUS'
  }, [item, cancellable])
  const action = useCallback(() => {
    if (step === 2) {
      setStep?.(1)
      setTimeout(() => {
        const initValues = submitData.links?.reduce(
          (values: any, item: any) => {
            return { ...values, [item.type as string]: item.url }
          },
          {}
        )
        setInitValues({
          numberOfEpisodes: submitData?.numberOfEpisodes || 1,
          ...initValues
        })
      }, 150)
      return
    }
    if (!!item || cancellable) {
      close?.()
      return
    }
    back?.()
  }, [item, close, back, cancellable, step, submitData])
  const onDropEndModules = (list: any) => {
    setPodcastLinks(list)
  }
  const onCheckTurnOn = useCallback(
    item => (value: string) => {
      if (item.isFirstActive && value.trim().length) {
        setPodcastLinks(values => {
          const links = values.slice()
          const podcast = links.find((el: any) => el.key === item.key)
          if (podcast) {
            podcast.isFirstActive = false
            podcast.active = true
          }
          return links
        })
      }
    },
    []
  )

  const onChangeSwitch = (key: string) => (value: boolean) => {
    const data = [...podcastLinks]
    const item = data.find(el => el.key === key)
    if (item) {
      item.active = value
    }
    setPodcastLinks?.(data)
    if (errors[key]) {
      setErrors({
        ...errors,
        [key]: undefined
      })
    }
  }
  const fetchPreviewData = async (params: PodcastSyncLatestParams) => {
    const result: any = await talentService().getSyncLatestPodcasts(params)

    if (result.ok) {
      if (
        result.response.message ===
          ValidatePodcast.APPLE_PODCAST_SHOW_DO_NOT_EXISTS &&
        !result.response?.episodes?.length
      ) {
        setErrors({
          [SocialProfileLinkTypes.APPLE_PODCAST]:
            ValidatePodcast.APPLE_PODCAST_SHOW_DO_NOT_EXISTS
        })
        return
      }

      setErrors({})
      setStep?.(2)
      setEpisodes(result.response.episodes)
    }
  }
  const onSubmit = async (values: any) => {
    try {
      setLoading(true)
      const isEmpty = podcastLinks.every(
        item => !item.active || (!values[item.key] && item.active)
      )
      if ((!values.SPOTIFY && !values.APPLE_PODCAST) || isEmpty) {
        notification.warn({
          message:
            !values[SocialProfileLinkTypes.APPLE_PODCAST] &&
            !values[SocialProfileLinkTypes.SPOTIFY]
              ? 'Please add at least one show link'
              : 'Please select at least one platform'
        })
        return
      }
      if (values.SPOTIFY) {
        const isToken = await onConnectSpotify?.()
        if (!isToken) {
          notification.success({
            message: 'Connection to spotify is failed'
          })
          return
        }
      }
      const links = podcastLinks.map(item => ({
        type: item.key,
        url: values[item.key],
        active: item.active
      }))
      const params = reduce(
        links,
        (result, item) => {
          if (!item.url) {
            return result
          }
          const value = { url: item.url, active: item.active }
          if (item.type === SocialProfileLinkTypes.APPLE_PODCAST) {
            return {
              ...result,
              apple: value
            }
          }
          return { ...result, spotify: value }
        },
        {}
      )
      const result: any = await talentService().validatePodcastLinks({
        ...params,
        numberOfEpisodes: values.numberOfEpisodes
      } as PodcastValidateParams)

      if (result.ok) {
        if (
          (result.response &&
            result.response.message &&
            result.response.message === ValidatePodcast.Success) ||
          allowBypassWarning
        ) {
          setSubmitData({
            numberOfEpisodes: values.numberOfEpisodes,
            links,
            isDifferent:
              result.response &&
              result.response.message &&
              result.response.message === ValidatePodcast.Success
                ? false
                : true
          })
          const syncParams = reduce(
            links,
            (result, item) => {
              if (!item.url) {
                return result
              }
              if (item.type === SocialProfileLinkTypes.APPLE_PODCAST) {
                return {
                  ...result,
                  appleUrl: item.url,
                  appleActive: item.active
                }
              }
              return {
                ...result,
                spotifyUrl: item.url,
                spotifyActive: item.active
              }
            },
            {}
          )
          await fetchPreviewData({
            ...syncParams,
            totalSelected: values.numberOfEpisodes,
            firstIndex: links[0].type,
            isDifferent:
              result.response &&
              result.response.message &&
              result.response.message === ValidatePodcast.Success
                ? false
                : true
          })
          setAllowBypassWarning(false)
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.DifferentPodcastShow
          )
        ) {
          setSubmitData({
            numberOfEpisodes: values.numberOfEpisodes,
            links,
            isDifferent: true
          })
          setVisibleWarning(true)
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.InvalidApplePodcast
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.APPLE_PODCAST]:
              ValidatePodcast.InvalidApplePodcast
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.InvalidSpotifyPodcast
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.SPOTIFY]:
              ValidatePodcast.InvalidSpotifyPodcast
          })
          return
        } else if (
          includes(result.response.messages, ValidatePodcast.InvalidQuery)
        ) {
          setErrors({
            [SocialProfileLinkTypes.APPLE_PODCAST]:
              ValidatePodcast.InvalidApplePodcast,
            [SocialProfileLinkTypes.SPOTIFY]:
              ValidatePodcast.InvalidSpotifyPodcast
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.APPLE_PODCAST_CONNECTION_FAILED
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.APPLE_PODCAST]:
              ValidatePodcast.APPLE_PODCAST_CONNECTION_FAILED
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.SPOTIFY_CONNECTION_FAILED
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.SPOTIFY]:
              ValidatePodcast.SPOTIFY_CONNECTION_FAILED
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.SPOTIFY_CONNECTION_FAILED
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.SPOTIFY]:
              ValidatePodcast.SPOTIFY_CONNECTION_FAILED
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.APPLE_PODCAST_SHOW_DO_NOT_EXISTS
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.APPLE_PODCAST]:
              ValidatePodcast.APPLE_PODCAST_SHOW_DO_NOT_EXISTS
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.SPOTIFY_SHOW_DO_NOT_EXISTS
          )
        ) {
          setErrors({
            [SocialProfileLinkTypes.SPOTIFY]:
              ValidatePodcast.SPOTIFY_SHOW_DO_NOT_EXISTS
          })
          return
        } else if (
          includes(
            result.response.messages,
            ValidatePodcast.DIFFERENT_PODCAST_NAME
          ) ||
          includes(
            result.response.messages,
            ValidatePodcast.DIFFERENT_PODCAST_AUTHOR
          ) ||
          includes(
            result.response.messages,
            ValidatePodcast.DIFFERENT_PODCAST_EPISODES
          )
        ) {
          setResponseValidate(result.response)
          setVisibleWarningValidate(true)
          // setErrors({
          //   [SocialProfileLinkTypes.SPOTIFY]:
          //     ValidatePodcast.SPOTIFY_SHOW_DO_NOT_EXISTS,
          // });
          // return;
        }
      }
      if (result.kind === 'cannot-connect') {
        const error = reduce(
          links,
          (result, link) => {
            if (link.active && link.url) {
              return {
                ...result,
                [link.type]:
                  link.type === SocialProfileLinkTypes.APPLE_PODCAST
                    ? ValidatePodcast.APPLE_PODCAST_CONNECTION_FAILED
                    : ValidatePodcast.SPOTIFY_CONNECTION_FAILED
              }
            }
            return result
          },
          {}
        )
        setErrors(error)
      }
    } catch (error) {
    } finally {
      setLoading(false)
    }
  }
  const renderErrorMessage = (key: string) => {
    const isShow =
      (!errors[SocialProfileLinkTypes.APPLE_PODCAST] &&
        errors[SocialProfileLinkTypes.SPOTIFY]) ||
      (errors[SocialProfileLinkTypes.APPLE_PODCAST] &&
        !errors[SocialProfileLinkTypes.SPOTIFY])
    if (
      [
        ValidatePodcast.InvalidApplePodcast,
        ValidatePodcast.InvalidSpotifyPodcast
      ].includes(key as ValidatePodcast)
    ) {
      return (
        <div>
          {`Your podcast show could not be found on ${
            key === ValidatePodcast.InvalidApplePodcast
              ? 'Apple Podcast'
              : 'Spotify'
          }. Please make sure that your show link is correct.`}
          {isShow && (
            <div className="m__t--12">
              If the error persists, disable this link to proceed.
            </div>
          )}
        </div>
      )
    }
    if (
      [
        ValidatePodcast.APPLE_PODCAST_SHOW_DO_NOT_EXISTS,
        ValidatePodcast.SPOTIFY_SHOW_DO_NOT_EXISTS
      ].includes(key as ValidatePodcast)
    ) {
      return (
        <div>
          {`Your podcast show could not be found on ${
            key === ValidatePodcast.SPOTIFY_SHOW_DO_NOT_EXISTS
              ? 'Spotify'
              : 'Apple Podcast'
          }. Please make
          sure that your show link is correct. If so, try adding it again later.`}
          {isShow && (
            <div className="m__t--12">
              If the error persists, disable this link to proceed.
            </div>
          )}
        </div>
      )
    }

    if (
      [
        ValidatePodcast.APPLE_PODCAST_CONNECTION_FAILED,
        ValidatePodcast.SPOTIFY_CONNECTION_FAILED
      ].includes(key as ValidatePodcast)
    ) {
      return (
        <div>
          {`Connection with ${
            key === ValidatePodcast.APPLE_PODCAST_CONNECTION_FAILED
              ? 'Apple Podcast'
              : 'Spotify'
          } could not be established at this time.
          Please make sure that your show link is correct. If so, try adding it
          again later.`}
          {isShow && (
            <div className="m__t--12">
              If the error persists, disable this link to proceed.
            </div>
          )}
        </div>
      )
    }
    return null
  }
  const renderPodcastList = () => {
    return (
      <React.Fragment>
        <DragDropContext
          droppableId="modules-drop"
          listClassName={'modules-list m__t--14'}
          itemIdPrefix="module"
          list={podcastLinks}
          onDropEndCallback={onDropEndModules}
        >
          {(dragProvided, snapshot, item) => (
            <PortalComponent
              innerRef={dragProvided.innerRef}
              namespaceClass="module-list"
              provided={dragProvided}
              snapshot={snapshot}
            >
              <PodcastFieldItemMemo
                icon={item.icon as IconName}
                name={item.key}
                title={item.name}
                placeholder="Enter show link"
                dragHandleProps={dragProvided.dragHandleProps}
                validate={validatePodcastByType(item.key)}
                onChangeText={onCheckTurnOn(item)}
                rightContent={
                  <Switch
                    key={`switch-${item.key}`}
                    checked={item.active}
                    onChange={onChangeSwitch(item.key)}
                  />
                }
                errorAlert={
                  errors[item.key] && renderErrorMessage(errors[item.key])
                }
              />
            </PortalComponent>
          )}
        </DragDropContext>
      </React.Fragment>
    )
  }
  const onFinish = () => {
    const data = {
      ...submitData,
      activeLatestPodcast
    }
    callback?.(data)
  }
  const onChangeActiveLatest = (event: any) => {
    if (isOnlyLink) {
      return
    }
    const value = event.target.checked
    setActiveLatestPodcast(value)
  }
  const isOnlyLink = useMemo(() => {
    return submitData.numberOfEpisodes === 1
  }, [submitData])
  const renderContent = () => {
    if (step === 2) {
      return (
        <>
          <Row gutter={16}>
            <Col flex="1">
              <Paragraph preset="semibold18">Module Preview</Paragraph>
              <Checkbox
                className="m__t--16"
                checked={isOnlyLink || activeLatestPodcast}
                onChange={onChangeActiveLatest}
                disabled={isOnlyLink}
              >
                <span className="opacity--08 leading-22 text--default">
                  Display latest podcast as a feature element
                </span>
              </Checkbox>
              <Alert
                message={undefined}
                className={'p__x--8 p__y--8 bg--darkGray m__t--24'}
                description={
                  isOnlyLink
                    ? 'Your podcast will be displayed as a feature element because you’ve selected to only sync the latest episode.'
                    : 'Tip: if you want to separate your latest episode from the rest, you can create two different modules.'
                }
                icon={<Icon name="sm-info" />}
                showIcon
                closable={false}
              />
            </Col>
            <Col className=" p__t--4 p__b--4">
              <div className="divider-vertical border2 " />
            </Col>
            <Col flex="1">
              <PodCastAutomationReview
                data={episodes as any}
                activeLatestPodcast={activeLatestPodcast as any}
              />
            </Col>
          </Row>
          <Row className="m__y--24" gutter={16} justify="end" align="middle">
            <Col>
              <Button
                className="height--52 width--160 text__transform--uppercase letter__spacing--1"
                type="default"
                block
                onClick={action}
                size="large"
              >
                PREVIOUS
              </Button>
            </Col>
            <Col>
              <Button
                className="height--52 width--160 text__transform--uppercase letter__spacing--1"
                type="primary"
                block
                size="large"
                loading={loading}
                onClick={onFinish}
              >
                {!item ? 'DONE' : 'SAVE'}
              </Button>
            </Col>
          </Row>
        </>
      )
    }
    return (
      <>
        <Paragraph preset="semibold18">Add Your Show</Paragraph>
        <Paragraph
          className="opacity--08 m__t--4 leading-22 m__b--24"
          preset="regular16"
        >
          Enter Spotify and / or Apple Podcast links to your show and the number
          of most recent podcast episodes to be synced.
        </Paragraph>
        <Alert
          message={undefined}
          className={'m__b--24 p__x--8 p__y--8 bg--darkGray'}
          description={
            'Your episodes will be displayed from newest to oldest. Older episodes will be deleted automatically.'
          }
          icon={<Icon name="sm-info" />}
          showIcon
          closable={false}
        />

        <Formik
          enableReinitialize
          initialValues={initValues}
          onSubmit={onSubmit}
        >
          {({ handleSubmit, handleReset, values, setFieldValue }) => (
            <Form onSubmit={handleSubmit}>
              <div className="m__b--24">{renderPodcastList()}</div>

              <Field
                component={AntInputNumber}
                formItemClassName="number-input m__b--0"
                name="numberOfEpisodes"
                label={
                  <Row align="middle" gutter={4}>
                    <Col>
                      <Paragraph className="text--tundola leading-22">
                        Number of episodes
                      </Paragraph>
                    </Col>
                    <Col>
                      <Tooltip
                        overlayClassName="info-tooltip text"
                        placement="top"
                        title="You can sync up to 25 latest episodes"
                      >
                        <div className="height--16">
                          <Icon name="sm-info" width={16} height={16} />
                        </div>
                      </Tooltip>
                    </Col>
                  </Row>
                }
                min={1}
                max={25}
                className={values.numberOfEpisodes === 25 && 'number-of-video'}
                isInt
                controls={false}
                addonBefore={
                  <Button
                    disabled={values.numberOfEpisodes <= 1}
                    onClick={() => {
                      setFieldValue(
                        'numberOfEpisodes',
                        values.numberOfEpisodes - 1
                      )
                    }}
                    className="p--0"
                    type="text"
                  >
                    <div className="height--24">
                      <Icon
                        fill={
                          values.numberOfEpisodes > 1 ? '#636363' : '#C4C4C4'
                        }
                        name="input-minus"
                      />
                    </div>
                  </Button>
                }
                addonAfter={
                  <Button
                    onClick={() => {
                      setFieldValue(
                        'numberOfEpisodes',
                        values.numberOfEpisodes + 1
                      )
                    }}
                    className="p--0"
                    type="text"
                    disabled={values.numberOfEpisodes >= 25}
                  >
                    <div className="height--24">
                      <Icon
                        fill={
                          !values.numberOfEpisodes ||
                          values.numberOfEpisodes < 25
                            ? '#636363'
                            : '#C4C4C4'
                        }
                        name="input-plus"
                      />
                    </div>
                  </Button>
                }
              />
              {values.numberOfEpisodes === 25 && (
                <Paragraph className="m__t--4 m__b--24">
                  You can only sync up to 25 latest episodes
                </Paragraph>
              )}
              {values.numberOfEpisodes === 1 && (
                <Paragraph className="m__t--4 m__b--24">
                  The minimum number is 1
                </Paragraph>
              )}
              <PodcastWarningModal
                visible={visibleWarningValidate}
                data={responseValidate}
                onChangeVisible={setVisibleWarningValidate}
                onChangeAllowBypassWarning={setAllowBypassWarning}
                onSubmit={handleSubmit}
              />
              <Row
                className="m__y--24"
                gutter={16}
                justify="end"
                align="middle"
              >
                <Col>
                  <Button
                    className="height--52 width--160 text__transform--uppercase letter__spacing--1"
                    type="default"
                    block
                    onClick={() => {
                      action()
                      handleReset()
                    }}
                    size="large"
                  >
                    {caption}
                  </Button>
                </Col>
                <Col>
                  <Button
                    className="height--52 width--160 text__transform--uppercase letter__spacing--1"
                    type="primary"
                    block
                    size="large"
                    htmlType="submit"
                    loading={loading}
                  >
                    NEXT
                  </Button>
                </Col>
              </Row>
            </Form>
          )}
        </Formik>
      </>
    )
  }
  const handleWarningConfirm = async () => {
    try {
      setLoading(true)
      setVisibleWarning(false)
      const syncParams = reduce(
        submitData.links,
        (result, item) => {
          if (!item.url) {
            return result
          }
          if (item.type === SocialProfileLinkTypes.APPLE_PODCAST) {
            return {
              ...result,
              appleUrl: item.url,
              appleActive: item.active
            }
          }
          return {
            ...result,
            spotifyUrl: item.url,
            spotifyActive: item.active
          }
        },
        {}
      )
      await fetchPreviewData({
        ...syncParams,
        totalSelected: submitData.numberOfEpisodes,
        firstIndex: submitData.links[0].type,
        isDifferent: submitData.isDifferent
      })
    } catch (error) {
    } finally {
      setLoading(false)
    }
  }
  return (
    <div className="relative">
      {renderContent()}
      <ConfirmDeleteModal
        show={visibleWarning}
        toggleModal={setVisibleWarning}
        cancelLabel="CANCEL"
        confirmLabel={'Continue'}
        width={520}
        title={'Show Names Don’t Match'}
        description={
          'We’ve noticed that the links added have different show names associated with them, do you still want to proceed?'
        }
        handleConfirm={handleWarningConfirm}
        reverse
      />
      {loading && (
        <Row className="loading-content" justify="space-between" align="middle">
          <DotLoading />
        </Row>
      )}
    </div>
  )
}

export default SyncLatestPodcastContent
