"use client"

import { AnimatePresence, motion } from "framer-motion"
import { usePathname } from "next/navigation"
import React, { useState } from "react"
import { Dialog, Modal, ModalOverlay } from "react-aria-components"
import { useIntl } from "react-intl"

import { benefits } from "@/constants/routes/myPages"
import { dt } from "@/lib/dt"
import { trpc } from "@/lib/trpc/client"

import { ChevronRightSmallIcon, CloseLargeIcon } from "@/components/Icons"
import Image from "@/components/Image"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
import { toast } from "@/components/TempDesignSystem/Toasts"
import useLang from "@/hooks/useLang"

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

import type {
  Surprise,
  SurprisesProps,
} from "@/types/components/blocks/surprises"

const variants = {
  enter: (direction: number) => {
    return {
      x: direction > 0 ? 1000 : -1000,
      opacity: 0,
    }
  },
  center: {
    x: 0,
    opacity: 1,
  },
  exit: (direction: number) => {
    return {
      x: direction < 0 ? 1000 : -1000,
      opacity: 0,
    }
  },
}

export default function SurprisesNotification({
  surprises,
  membershipNumber,
}: SurprisesProps) {
  const lang = useLang()
  const pathname = usePathname()
  const [open, setOpen] = useState(true)
  const [[selectedSurprise, direction], setSelectedSurprise] = useState([0, 0])
  const [showSurprises, setShowSurprises] = useState(false)
  const unwrap = trpc.contentstack.rewards.unwrap.useMutation({
    onSuccess: () => {
      if (pathname.indexOf(benefits[lang]) !== 0) {
        toast.success(
          <>
            {intl.formatMessage(
              { id: "Gift(s) added to your benefits" },
              { amount: surprises.length }
            )}
            <br />
            <Link href={benefits[lang]} variant="underscored" color="burgundy">
              {intl.formatMessage({ id: "Go to My Benefits" })}
            </Link>
          </>
        )
      }
    },
    onError: (error) => {
      console.error("Error", error)
    },
  })
  const intl = useIntl()

  if (!surprises.length) {
    return null
  }

  const surprise = surprises[selectedSurprise]

  function showSurprise(newDirection: number) {
    setSelectedSurprise(([currentIndex]) => [
      currentIndex + newDirection,
      newDirection,
    ])
  }

  async function viewRewards() {
    const updates = surprises
      .map((surprise) => {
        const coupons = surprise.coupons
          ?.map((coupon) => {
            if (coupon?.couponCode) {
              return {
                rewardId: surprise.id,
                couponCode: coupon.couponCode,
              }
            }
          })
          .filter(
            (coupon): coupon is { rewardId: string; couponCode: string } =>
              !!coupon
          )

        return coupons
      })
      .flat()
      .filter(
        (coupon): coupon is { rewardId: string; couponCode: string } => !!coupon
      )

    unwrap.mutate(updates)
  }

  const earliestExpirationDate = surprise.coupons?.reduce(
    (earliestDate, coupon) => {
      const expiresAt = dt(coupon.expiresAt)
      return earliestDate.isBefore(expiresAt) ? earliestDate : expiresAt
    },
    dt()
  )

  return (
    <ModalOverlay
      className={styles.overlay}
      isOpen={open}
      onOpenChange={setOpen}
      isKeyboardDismissDisabled
    >
      <Modal className={styles.modal}>
        <Dialog aria-label="Surprises" className={styles.dialog}>
          {({ close }) => {
            return (
              <>
                <div className={styles.top}>
                  {surprises.length > 1 && showSurprises && (
                    <Caption type="label" uppercase>
                      {intl.formatMessage(
                        { id: "{amount} out of {total}" },
                        {
                          amount: selectedSurprise + 1,
                          total: surprises.length,
                        }
                      )}
                    </Caption>
                  )}
                  <button
                    onClick={() => {
                      viewRewards()
                      close()
                    }}
                    type="button"
                    className={styles.close}
                  >
                    <CloseLargeIcon />
                  </button>
                </div>
                {showSurprises ? (
                  <>
                    <AnimatePresence
                      mode="popLayout"
                      initial={false}
                      custom={direction}
                    >
                      <motion.div
                        key={selectedSurprise}
                        custom={direction}
                        variants={variants}
                        initial="enter"
                        animate="center"
                        exit="exit"
                        transition={{
                          x: { type: "ease", duration: 0.5 },
                          opacity: { duration: 0.2 },
                        }}
                      >
                        <Surprise title={surprise.label}>
                          <Body textAlign="center">{surprise.description}</Body>
                          <div className={styles.badge}>
                            <Caption>
                              {intl.formatMessage(
                                { id: "Expires at the earliest" },
                                {
                                  date: dt(earliestExpirationDate)
                                    .locale(lang)
                                    .format("D MMM YYYY"),
                                }
                              )}
                            </Caption>
                            <Caption>
                              {intl.formatMessage({
                                id: "Membership ID",
                              })}{" "}
                              {membershipNumber}
                            </Caption>
                          </div>
                        </Surprise>
                      </motion.div>
                    </AnimatePresence>
                    {surprises.length > 1 && (
                      <>
                        <nav className={styles.nav}>
                          <Button
                            variant="icon"
                            intent="tertiary"
                            disabled={selectedSurprise === 0}
                            onPress={() => showSurprise(-1)}
                            size="small"
                          >
                            <ChevronRightSmallIcon
                              className={styles.chevron}
                              width={20}
                              height={20}
                            />
                            {intl.formatMessage({ id: "Previous" })}
                          </Button>
                          <Button
                            variant="icon"
                            intent="tertiary"
                            disabled={selectedSurprise === surprises.length - 1}
                            onPress={() => showSurprise(1)}
                            size="small"
                          >
                            {intl.formatMessage({ id: "Next" })}
                            <ChevronRightSmallIcon width={20} height={20} />
                          </Button>
                        </nav>
                      </>
                    )}
                  </>
                ) : (
                  <Surprise title={intl.formatMessage({ id: "Surprise!" })}>
                    <Body textAlign="center">
                      {surprises.length > 1 ? (
                        <>
                          {intl.formatMessage<React.ReactNode>(
                            {
                              id: "You have <b>#</b> gifts waiting for you!",
                            },
                            {
                              amount: surprises.length,
                              b: (str) => <b>{str}</b>,
                            }
                          )}
                          <br />
                          {intl.formatMessage({
                            id: "Hurry up and use them before they expire!",
                          })}
                        </>
                      ) : (
                        intl.formatMessage({
                          id: "We have a special gift waiting for you!",
                        })
                      )}
                    </Body>
                    <Caption>
                      {intl.formatMessage({
                        id: "You'll find all your gifts in 'My benefits'",
                      })}
                    </Caption>

                    <Button
                      intent="primary"
                      onPress={() => {
                        setShowSurprises(true)
                      }}
                      size="medium"
                      theme="base"
                      fullWidth
                      autoFocus
                    >
                      {intl.formatMessage(
                        {
                          id: "Open gift(s)",
                        },
                        { amount: surprises.length }
                      )}
                    </Button>
                  </Surprise>
                )}
              </>
            )
          }}
        </Dialog>
      </Modal>
    </ModalOverlay>
  )
}

function Surprise({
  title,
  children,
}: {
  title?: string
  children?: React.ReactNode
}) {
  return (
    <div className={styles.content}>
      <Image
        src="/_static/img/loyalty-award.png"
        width={113}
        height={125}
        alt="Gift"
      />
      <header>
        <Title textAlign="center" level="h4">
          {title}
        </Title>
      </header>

      {children}
    </div>
  )
}
