"use client"

import { motion } from "framer-motion"
import { useState } from "react"
import {
  Dialog,
  DialogTrigger,
  Modal,
  ModalOverlay,
} from "react-aria-components"
import { useIntl } from "react-intl"

import { CloseLargeIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"

import Campaign from "./Flows/Campaign"
import Tier from "./Flows/Tier"
import { RedeemContext } from "./useRedeemFlow"

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

import type {
  RedeemModalState,
  RedeemProps,
  RedeemStep,
} from "@/types/components/myPages/myPage/accountPage"
import type { RewardWithRedeem } from "@/server/routers/contentstack/reward/output"

const MotionOverlay = motion(ModalOverlay)
const MotionModal = motion(Modal)

export default function Redeem({ reward, membershipNumber }: RedeemProps) {
  const [animation, setAnimation] = useState<RedeemModalState>("unmounted")
  const intl = useIntl()
  const [redeemStep, setRedeemStep] = useState<RedeemStep>("initial")

  function modalStateHandler(newAnimationState: RedeemModalState) {
    setAnimation((currentAnimationState) =>
      newAnimationState === "hidden" && currentAnimationState === "hidden"
        ? "unmounted"
        : currentAnimationState
    )
    if (newAnimationState === "unmounted") {
      setRedeemStep("initial")
    }
  }

  return (
    <RedeemContext.Provider value={{ redeemStep, setRedeemStep }}>
      <DialogTrigger
        onOpenChange={(isOpen) => setAnimation(isOpen ? "visible" : "hidden")}
      >
        <Button intent="primary" fullWidth>
          {reward.redeemLocation === "Non-redeemable"
            ? intl.formatMessage({ id: "How to use" })
            : intl.formatMessage({ id: "Open" })}
        </Button>
        <MotionOverlay
          className={styles.overlay}
          isExiting={animation === "hidden"}
          onAnimationComplete={modalStateHandler}
          variants={variants.fade}
          initial="hidden"
          animate={animation}
        >
          <MotionModal
            className={styles.modal}
            variants={variants.slideInOut}
            initial="hidden"
            animate={animation}
          >
            <Dialog className={styles.dialog} aria-label={reward.label}>
              {({ close }) => (
                <>
                  <header className={styles.modalHeader}>
                    <button
                      onClick={close}
                      type="button"
                      className={styles.modalClose}
                    >
                      <CloseLargeIcon />
                    </button>
                  </header>

                  {getRedeemFlow(reward, membershipNumber || "")}
                </>
              )}
            </Dialog>
          </MotionModal>
        </MotionOverlay>
      </DialogTrigger>
    </RedeemContext.Provider>
  )
}

const variants = {
  fade: {
    hidden: {
      opacity: 0,
      transition: { duration: 0.4, ease: "easeInOut" },
    },
    visible: {
      opacity: 1,
      transition: { duration: 0.4, ease: "easeInOut" },
    },
  },

  slideInOut: {
    hidden: {
      opacity: 0,
      y: 32,
      transition: { duration: 0.4, ease: "easeInOut" },
    },
    visible: {
      opacity: 1,
      y: 0,
      transition: { duration: 0.4, ease: "easeInOut" },
    },
  },
}

function getRedeemFlow(reward: RewardWithRedeem, membershipNumber: string) {
  switch (reward.rewardType) {
    case "Campaign":
      return <Campaign reward={reward} />
    case "Surprise":
    case "Tier":
      return <Tier reward={reward} membershipNumber={membershipNumber} />
    default:
      console.warn("Unsupported reward type for redeem:", reward.rewardType)
      return null
  }
}
