import { useEffect, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { toast } from 'react-toastify'

import { useAuth } from '#components/Auth/useAuth'
import { useMyProfile } from '#components/Map/hooks/useMyProfile'
import { MapOverlayPage } from '#components/Templates/MapOverlayPage'

import type { FullItemsApi } from '#types/FullItemsApi'
import type { InviteApi } from '#types/InviteApi'
import type { Item } from '#types/Item'

interface Props {
  inviteApi: InviteApi
  itemsApi: FullItemsApi<Item>
}

/**
 * @category Onboarding
 */
export function InvitePage({ inviteApi, itemsApi }: Props) {
  const { isAuthenticated, isInitialized: isAuthenticationInitialized } = useAuth()
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()

  const { myProfile, isMyProfileLoaded } = useMyProfile()

  if (!id) throw new Error('Invite ID is required')

  const [invitingProfile, setInvitingProfile] = useState<Item | null>(null)

  useEffect(() => {
    async function redeemInvite() {
      if (!id) throw new Error('Invite ID is required')

      if (!isMyProfileLoaded) return

      if (!myProfile) {
        toast.error('Could not find your profile to redeem the invite.')
        return
      }

      const invitingProfileId = await inviteApi.redeemInvite(id, myProfile.id)

      if (invitingProfileId) {
        toast.success('Invite redeemed successfully!')
        navigate(`/item/${invitingProfileId}`)
      } else {
        toast.error('Failed to redeem invite')
        navigate('/')
      }
    }

    async function validateInvite() {
      if (!id) throw new Error('Invite ID is required')

      const invitingProfileId = await inviteApi.validateInvite(id)

      if (!invitingProfileId) {
        toast.error('Invalid invite code')
        navigate('/')
        return
      }

      const invitingProfile = await itemsApi.getItem(invitingProfileId)

      if (!invitingProfile) {
        toast.error('Inviting profile not found')
        navigate('/')
        return
      }

      setInvitingProfile(invitingProfile)
    }

    if (!isAuthenticationInitialized) return

    if (isAuthenticated) {
      void redeemInvite()
    } else {
      // Save invite code in local storage
      localStorage.setItem('inviteCode', id)

      void validateInvite()
    }
  }, [
    id,
    isAuthenticated,
    inviteApi,
    navigate,
    isAuthenticationInitialized,
    myProfile,
    isMyProfileLoaded,
    itemsApi,
  ])

  const goToSignup = () => {
    navigate('/signup')
  }

  const goToLogin = () => {
    navigate('/login')
  }

  return (
    <MapOverlayPage backdrop className='tw:max-w-xs tw:h-fit'>
      <h2 className='tw:text-2xl tw:font-semibold tw:mb-2 tw:text-center'>Invitation</h2>
      {invitingProfile ? (
        <div className='tw-text-center tw-mb-4'>
          <p className='tw-text-lg tw-font-semibold'>Welcome to Utopia!</p>
          <p className='tw-text-sm tw-text-gray-600'>
            You have been invited by: <strong>{invitingProfile.name}</strong> to join the Utopia
            community.
          </p>
          <div className='tw-flex tw:justify-center tw:mt-4'>
            <button
              className='tw-btn tw-btn-primary'
              onClick={isAuthenticated ? () => navigate('/') : goToSignup}
            >
              {isAuthenticated ? 'Go to Dashboard' : 'Sign Up'}
            </button>
            {!isAuthenticated && (
              <button className='tw-btn tw-btn-secondary' onClick={goToLogin}>
                Login
              </button>
            )}
          </div>
        </div>
      ) : (
        <p className='tw-text-center'>Validating invite...</p>
      )}
    </MapOverlayPage>
  )
}
