import React, { useCallback, useContext, useEffect, useState } from 'react'
import DateSelector from '../DateSelector/DateSelector'
import { NewsletterService } from '../../services/newsletter.service'
import { UserContext, UserContextProps } from '../../hooks/userContext'
import { IMonthlyNews } from '../../models/monthlyNews.model'
import { IMonthlyInfo } from '../../models/monthlyInfo.model'
import { IPoll } from '../../models/poll.model'
import Poll from '../Poll/Poll'
import MonthlyInfo from '../MonthlyInfo/MonthlyInfo'
import MonthlyNews from '../MonthlyNews/MonthlyNews'
import Loader from '../Loader/Loader'
import Modal from '../Modal/Modal'
import './editing.scss'

export type ContentItems = 'monthlyInfo' | 'monthlyNews' | 'poll' | ''

const Editing: React.FC = () => {
  // Fonctional rule :
  // Display next month after the 3rd of the current month
  const getCurrentNewsletterDate = (): Date => {
    let newsletterDate = new Date()
    if (newsletterDate.getDate() >= 3) {
      newsletterDate.setMonth(newsletterDate.getMonth() + 1)
    }
    return newsletterDate
  }

  const [date, setDate] = useState<Date>(getCurrentNewsletterDate())
  const [info, setInfo] = useState<string>('')
  const [title, setTitle] = useState<string>('')
  const [imageURL, setImageURL] = useState<string>('')
  const [content, setContent] = useState<string>('')
  const [question, setQuestion] = useState<string>('')
  const [link, setLink] = useState<string>('')
  const [isTouched, setIsTouched] = useState<boolean>(false)
  const [refreshData, setRefreshData] = useState(false)
  const [isLoading, setisLoading] = useState<boolean>(false)
  const [warningModal, setwarningModal] = useState<boolean>(false)
  const [toDelete, settoDelete] = useState<ContentItems>('')
  const { user }: Partial<UserContextProps> = useContext(UserContext)
  const newsletterService = new NewsletterService()

  const handleSaveMonthlyInfo = async (): Promise<void> => {
    if (user) {
      const newsletterService = new NewsletterService()
      await newsletterService.saveMonthlyInfo(
        date,
        info,
        imageURL,
        user.xsrftoken
      )
      setIsTouched(false)
    }
  }

  const handleSaveMonthlyNews = async (): Promise<void> => {
    if (user) {
      const newsletterService = new NewsletterService()
      await newsletterService.saveMonthlyNews(
        date,
        title,
        content,
        user.xsrftoken
      )
      setIsTouched(false)
    }
  }
  const handleSavePoll = async (): Promise<void> => {
    if (user) {
      await newsletterService.savePoll(date, question, link, user.xsrftoken)
      setIsTouched(false)
    }
  }
  const handleCancel = useCallback(() => {
    setRefreshData(true)
  }, [])

  const handleDeleteMonthlyInfo = async (): Promise<void> => {
    if (user) {
      await newsletterService.deleteMonthlyInfo(date, user.xsrftoken)
      setRefreshData(true)
    }
  }
  const handleDeleteMonthlyNews = async (): Promise<void> => {
    if (user) {
      await newsletterService.deleteMonthlyNews(date, user.xsrftoken)
      setRefreshData(true)
    }
  }
  const handleDeletePoll = async (): Promise<void> => {
    if (user) {
      await newsletterService.deletePoll(date, user.xsrftoken)
      setRefreshData(true)
    }
  }
  const handleOpenDeleteModal = (target: ContentItems) => {
    settoDelete(target)
    setwarningModal(true)
  }
  const handleConfirmAlert = () => {
    if (toDelete === 'monthlyInfo') {
      handleDeleteMonthlyInfo()
    }
    if (toDelete === 'monthlyNews') {
      handleDeleteMonthlyNews()
    }
    if (toDelete === 'poll') {
      handleDeletePoll()
    }
    setwarningModal(false)
  }

  const isEmpty = (): boolean => {
    if (
      (info !== '' ||
        title !== '' ||
        content !== '' ||
        question !== '' ||
        imageURL !== '' ||
        link !== '') &&
      isTouched
    ) {
      return false
    } else return true
  }

  const handleEditorChange = useCallback(
    (
      value: string,
      type: 'info' | 'title' | 'content' | 'question' | 'link' | 'image'
    ): void => {
      setIsTouched(true)
      if (type === 'info') {
        setInfo(value)
      }
      if (type === 'title') {
        setTitle(value)
      }
      if (type === 'content') {
        setContent(value)
      }
      if (type === 'question') {
        setQuestion(value)
      }
      if (type === 'link') {
        setLink(value)
      }
      if (type === 'image') {
        setImageURL(value)
      }
    },
    []
  )

  const resetFields = useCallback(() => {
    setImageURL('')
    setInfo('')
    setTitle('')
    setContent('')
    setLink('')
    setQuestion('')
  }, [])

  useEffect(() => {
    let subscribed = true
    resetFields()
    setisLoading(true)
    async function getCurrentMonthlyNews() {
      if (user) {
        const newsletterService = new NewsletterService()
        const montlhyInfo: IMonthlyInfo | null =
          await newsletterService.getSingleMonthlyInfo(date, user.xsrftoken)
        const montlhyNews: IMonthlyNews | null =
          await newsletterService.getSingleMonthlyNews(date, user.xsrftoken)
        const poll: IPoll | null = await newsletterService.getSinglePoll(
          date,
          user.xsrftoken
        )
        if (montlhyInfo) {
          setInfo(montlhyInfo.info)
          setImageURL(montlhyInfo.image)
          setIsTouched(false)
        }
        if (montlhyNews) {
          setTitle(montlhyNews.title)
          setContent(montlhyNews.content)
          setIsTouched(false)
        }
        if (poll) {
          setLink(poll.link)
          setQuestion(poll.question)
          setIsTouched(false)
        }
      }
      setisLoading(false)
    }
    if (subscribed) {
      getCurrentMonthlyNews()
    }
    return () => {
      subscribed = false
      setRefreshData(false)
    }
  }, [date, user, refreshData, resetFields])

  return (
    <>
      <div className="header">
        <p className="title pagetitle">Édition de la newsletter</p>
        <DateSelector date={date} setDate={setDate} isEmpty={isEmpty} />
      </div>
      {isLoading ? (
        <Loader />
      ) : (
        <div className="content">
          <MonthlyInfo
            info={info}
            onSave={handleSaveMonthlyInfo}
            onCancel={handleCancel}
            handleChange={handleEditorChange}
            onDelete={handleOpenDeleteModal}
            imageURL={imageURL}
          />
          <hr />
          <MonthlyNews
            title={title}
            content={content}
            onSave={handleSaveMonthlyNews}
            onCancel={handleCancel}
            handleChange={handleEditorChange}
            onDelete={handleOpenDeleteModal}
          />
          <hr />
          <Poll
            question={question}
            link={link}
            onSave={handleSavePoll}
            onCancel={handleCancel}
            handleChange={handleEditorChange}
            onDelete={handleOpenDeleteModal}
          />
        </div>
      )}
      {warningModal && (
        <Modal>
          <>
            <div className="modal-text">
              Etes-vous sûr de vouloir supprimer{' '}
              {toDelete === 'monthlyInfo'
                ? 'cette info mensuelle '
                : toDelete === 'monthlyNews'
                ? 'cette news mensuelle'
                : 'ce sondage'}{' '}
              ?
            </div>
            <div className="buttons">
              <button
                className="btnCancel"
                onClick={() => setwarningModal(false)}
              >
                Annuler
              </button>
              <button className="btnValid" onClick={handleConfirmAlert}>
                Continuer
              </button>
            </div>
          </>
        </Modal>
      )}
    </>
  )
}

export default Editing