"use client"

import { AnimatePresence, motion } from "motion/react"
import { useCallback, useEffect, useRef, useState } from "react"
import { Dialog, Modal, ModalOverlay } from "react-aria-components"
import { useIntl } from "react-intl"

import { Button } from "@scandic-hotels/design-system/Button"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import ScandicLogoIcon from "@scandic-hotels/design-system/Icons/ScandicLogoIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { trpc } from "@scandic-hotels/trpc/client"

import { useUpdateProfilingConsent } from "@/hooks/useUpdateProfilingConsent"
import {
  setDismissed as persistDismissed,
  profilingConsentOpenEvent,
  readDismissed,
} from "@/utils/profilingConsent"
import { trackConsentAction } from "@/utils/tracking/profilingConsent"

import ProfilingConsentAccordion from "../Accordion"
import { GetMainIconByCSIdentifier } from "../utils"
import BenefitCards from "./BenefitCards"

import styles from "./profilingConsentModal.module.css"

import type { ProfilingConsentModal as ProfilingConsentModalType } from "@scandic-hotels/trpc/types/profilingConsent"

type ProfilingConsentModalProps = {
  memberKey?: string
  content: ProfilingConsentModalType
  iconIdentifier: string
  readOnly?: boolean
}

const MotionModal = motion.create(Modal)

function usePromptInitialization(memberKey: string | undefined) {
  const utils = trpc.useUtils()

  const updateConsentPromptDate =
    trpc.user.profilingConsentPromptDate.update.useMutation({
      onSuccess: () => utils.user.get.invalidate(),
    })

  const mutationRef = useRef(updateConsentPromptDate)
  // eslint-disable-next-line react-hooks/refs
  mutationRef.current = updateConsentPromptDate

  const [shouldOpenInitially, setShouldOpenInitially] = useState(false)
  const hasSentPromptDate = useRef(false)

  const sendPromptDate = useCallback((date: string) => {
    mutationRef.current.mutate({
      profilingConsentPromptDate: date,
    })
  }, [])

  useEffect(() => {
    if (!memberKey) return

    const dismissed = readDismissed(memberKey)
    const firstOpen = !dismissed

    setShouldOpenInitially(firstOpen)

    if (firstOpen && !hasSentPromptDate.current) {
      hasSentPromptDate.current = true
      sendPromptDate(new Date().toISOString())
    }
  }, [memberKey, sendPromptDate])

  return shouldOpenInitially
}

function useModalEvents(setOpen: (s: boolean) => void) {
  useEffect(() => {
    const handleOpen: EventListener = () => setOpen(true)
    window.addEventListener(profilingConsentOpenEvent, handleOpen)
    return () =>
      window.removeEventListener(profilingConsentOpenEvent, handleOpen)
  }, [setOpen])
}

export default function ProfilingConsentModal({
  memberKey,
  content,
  iconIdentifier,
  readOnly = false,
}: ProfilingConsentModalProps) {
  const intl = useIntl()

  const [open, setOpen] = useState(false)
  const [activeChoice, setActiveChoice] = useState<boolean | null>(null)

  const shouldOpenInitially = usePromptInitialization(memberKey)

  const { initiateUpdateConsent, isLoading, isSuccess } =
    useUpdateProfilingConsent()

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    if (shouldOpenInitially) setOpen(true)
  }, [shouldOpenInitially])

  useModalEvents(setOpen)

  const onClose = useCallback(() => {
    if (memberKey) {
      persistDismissed(memberKey)
    }
    setOpen(false)
  }, [memberKey])

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    if (isSuccess) onClose()
  }, [isSuccess, onClose])

  if (!memberKey && !readOnly) return null

  const handleConsentClick = (consent: boolean) => {
    setActiveChoice(consent)
    initiateUpdateConsent(consent)
  }

  return (
    <ModalOverlay
      className={styles.overlay}
      isOpen={open}
      onOpenChange={(state) => !state && onClose()}
      isKeyboardDismissDisabled
      isDismissable={false}
    >
      <AnimatePresence mode="wait">
        {open && (
          <MotionModal
            className={styles.modal}
            initial={{ y: 32, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            exit={{ y: 32, opacity: 0 }}
            transition={{
              y: { duration: 0.4, ease: "easeInOut" },
              opacity: { duration: 0.4, ease: "easeInOut" },
            }}
          >
            <Dialog
              aria-label={intl.formatMessage({
                id: "profilingConsent.profilingConsent",
                defaultMessage: "Profiling consent",
              })}
              className={styles.dialog}
            >
              <header className={styles.header}>
                <div className={styles.logoWrap}>
                  <ScandicLogoIcon height={20} width={94} />
                </div>
                <Button
                  type="button"
                  variant="Text"
                  size="lg"
                  color="Primary"
                  className={styles.closeBtn}
                  onPress={() => {
                    trackConsentAction({ position: "modal", name: "close" })
                    onClose()
                  }}
                  aria-label={intl.formatMessage({
                    id: "common.close",
                    defaultMessage: "Close",
                  })}
                >
                  <MaterialIcon color="CurrentColor" icon="close" />
                </Button>
              </header>

              <main className={styles.content}>
                <GetMainIconByCSIdentifier identifier={iconIdentifier} />
                <div className={styles.textContent}>
                  <Typography className={styles.heading} variant="Title/md">
                    <h2>{content.header}</h2>
                  </Typography>
                  <Typography className={styles.text} variant="Body/Lead text">
                    <p>{content.sub_header}</p>
                  </Typography>
                </div>
                <BenefitCards cards={content.cards} />

                <section className={styles.container}>
                  <header className={styles.header}>
                    <Typography variant="Title/Subtitle/lg">
                      <h3>
                        {intl.formatMessage({
                          id: "profilingConsent.personalization&privacy",
                          defaultMessage: "Personalization & privacy",
                        })}
                      </h3>
                    </Typography>
                    <Typography variant="Body/Paragraph/mdRegular">
                      <p>
                        {intl.formatMessage({
                          id: "profilingConsent.byAcceptingThisIConsent",
                          defaultMessage:
                            "By accepting this I consent to Scandic using my information to give me even more personalized travel inspiration and offers from Scandic and trusted Scandic Friends partners. This means Scandic may use information about my interactions with Scandic Friends partners, and share details of my interactions with Scandic with those partners, to make the experience even more relevant to me.",
                        })}
                      </p>
                    </Typography>
                  </header>
                  <ProfilingConsentAccordion component="modal" />
                </section>
              </main>

              {!readOnly && (
                <footer className={styles.actions}>
                  <Button
                    variant="Primary"
                    color="Primary"
                    size="lg"
                    type="button"
                    isDisabled={isLoading}
                    isPending={isLoading && activeChoice === true}
                    onPress={() => {
                      trackConsentAction({
                        position: "modal",
                        name: "accept personalization",
                      })
                      handleConsentClick(true)
                    }}
                  >
                    {intl.formatMessage({
                      id: "profilingConsent.acceptPersonalization",
                      defaultMessage: "Accept Personalization",
                    })}
                  </Button>
                  <Button
                    variant="Secondary"
                    size="lg"
                    color="Primary"
                    type="button"
                    isDisabled={isLoading}
                    isPending={isLoading && activeChoice === false}
                    onPress={() => {
                      trackConsentAction({ position: "modal", name: "decline" })
                      handleConsentClick(false)
                    }}
                  >
                    {intl.formatMessage({
                      id: "profilingConsent.decline",
                      defaultMessage: "Decline",
                    })}
                  </Button>
                </footer>
              )}
            </Dialog>
          </MotionModal>
        )}
      </AnimatePresence>
    </ModalOverlay>
  )
}
