import { useEffect, useRef, useState } from 'react'
import { AnimatePresence, motion } from 'motion/react'
import { CookieConsentBanner } from './components/CookieConsentBanner'
import { Header } from './components/Header'
import { Hero } from './components/Hero'
import { StudioShowcase } from './components/StudioShowcase'
import { Footer } from './components/Footer'
import { ContactPage } from './components/ContactPage'
import { JobsPage } from './components/JobsPage'
import { CandidatePortalPage } from './components/CandidatePortalPage'
import { SupportPage } from './components/SupportPage'
import { SEO } from './components/SEO'
import {
  trackScrollToSection,
  useGoogleAnalytics,
} from './hooks/useGoogleAnalytics'
import {
  buildLocalizedUrl,
  buildPathWithLanguage,
  buildPathWithLanguageAndSearch,
  normalizeLanguage,
  syncLanguageInCurrentUrl,
} from './constants/site'
import { useTranslation } from 'react-i18next'
import {
  getAccessAnalyticsConsentStatus,
  recordAccessError,
  recordAccessPageView,
  setAccessAnalyticsConsentStatus,
  type AccessAnalyticsConsentStatus,
  type AccessAnalyticsPageContext,
} from './services/accessAnalytics'

type AppPage =
  | 'home'
  | 'contact'
  | 'jobs'
  | 'candidate'
  | 'support'

const pageMetadata: Record<AppPage, AccessAnalyticsPageContext> = {
  home: {
    path: '/',
    title: 'MWBR Tecnologia - Home',
  },
  contact: {
    path: '/contato',
    title: 'MWBR Tecnologia - Contato',
  },
  jobs: {
    path: '/trabalhe-conosco',
    title: 'MWBR Tecnologia - Trabalhe Conosco',
  },
  candidate: {
    path: '/area-candidato',
    title: 'MWBR Tecnologia - Área do Candidato',
  },
  support: {
    path: '/suporte',
    title: 'MWBR Tecnologia - Suporte Técnico',
  },
}

const pageAliases: Partial<Record<AppPage, string[]>> = {
  contact: ['/contact'],
  jobs: ['/jobs'],
  candidate: ['/candidate'],
  support: ['/support', '/suporte-tecnico'],
}

const normalizePathname = (pathname: string) => {
  const trimmedPathname = pathname.trim()

  if (!trimmedPathname || trimmedPathname === '/') {
    return '/'
  }

  const prefixedPathname = trimmedPathname.startsWith('/')
    ? trimmedPathname
    : `/${trimmedPathname}`

  return prefixedPathname.replace(/\/+$/, '') || '/'
}

const scrollToHomeSection = (target: string) => {
  if (target === 'home') {
    window.scrollTo({ top: 0, behavior: 'smooth' })
    return
  }

  const element = document.getElementById(target)
  if (!element) return

  const headerElement = document.querySelector('header')
  const measuredHeaderHeight = headerElement?.getBoundingClientRect().height ?? 0
  const fallbackHeaderHeight = window.innerWidth >= 1024 ? 88 : 76
  const headerOffset =
    measuredHeaderHeight > 0
      ? Math.min(measuredHeaderHeight, fallbackHeaderHeight)
      : fallbackHeaderHeight
  const targetTop =
    element.getBoundingClientRect().top + window.scrollY - headerOffset - 10

  window.scrollTo({
    top: Math.max(targetTop, 0),
    behavior: 'smooth',
  })
}

const normalizeHashRoute = (hash: string) => {
  return hash
    .replace(/^#/, '')
    .replace(/^!/, '')
    .replace(/^\//, '')
    .split('?')[0]
    .split('&')[0]
    .trim()
    .toLowerCase()
}

const resolvePageFromPathname = (pathname: string): AppPage | null => {
  const normalizedPathname = normalizePathname(pathname)

  if (normalizedPathname === pageMetadata.home.path) {
    return 'home'
  }

  const matchingPage = (Object.entries(pageMetadata) as [
    AppPage,
    AccessAnalyticsPageContext,
  ][]).find(([page, metadata]) => {
    return (
      normalizedPathname === metadata.path ||
      pageAliases[page]?.includes(normalizedPathname)
    )
  })

  return matchingPage?.[0] ?? null
}

const resolvePageFromHash = (hash: string): AppPage | null => {
  const hashRoute = normalizeHashRoute(hash)

  if (hashRoute === 'contact' || hashRoute === 'contato') return 'contact'
  if (hashRoute === 'jobs' || hashRoute === 'trabalhe-conosco') return 'jobs'
  if (hashRoute === 'candidate' || hashRoute === 'area-candidato') return 'candidate'
  if (
    hashRoute === 'support' ||
    hashRoute === 'suporte' ||
    hashRoute === 'suporte-tecnico'
  ) {
    return 'support'
  }

  return null
}

const resolveCurrentPageFromLocation = (): AppPage => {
  return (
    resolvePageFromPathname(window.location.pathname) ??
    resolvePageFromHash(window.location.hash) ??
    'home'
  )
}

const getCanonicalPathForLocation = () => {
  const pageFromPath = resolvePageFromPathname(window.location.pathname)
  const normalizedPathname = normalizePathname(window.location.pathname)

  if (pageFromPath && normalizedPathname !== pageMetadata[pageFromPath].path) {
    return pageMetadata[pageFromPath].path
  }

  const pageFromHash = resolvePageFromHash(window.location.hash)

  if (pageFromHash) {
    return pageMetadata[pageFromHash].path
  }

  return null
}

export default function App() {
  const { i18n } = useTranslation()
  const [currentPage, setCurrentPage] = useState<AppPage>(() =>
    resolveCurrentPageFromLocation(),
  )
  const [analyticsConsent, setAnalyticsConsent] =
    useState<AccessAnalyticsConsentStatus>(() => getAccessAnalyticsConsentStatus())
  const currentPageRef = useRef<AppPage>(currentPage)
  const analyticsEnabled = analyticsConsent === 'granted'
  const { trackPageView } = useGoogleAnalytics(analyticsEnabled)
  const currentLanguage = normalizeLanguage(i18n.resolvedLanguage ?? i18n.language)

  useEffect(() => {
    const handleLocationChange = () => {
      setCurrentPage(resolveCurrentPageFromLocation())
    }

    handleLocationChange()
    window.addEventListener('hashchange', handleLocationChange)
    window.addEventListener('popstate', handleLocationChange)
    return () => {
      window.removeEventListener('hashchange', handleLocationChange)
      window.removeEventListener('popstate', handleLocationChange)
    }
  }, [])

  useEffect(() => {
    currentPageRef.current = currentPage
  }, [currentPage])

  useEffect(() => {
    const canonicalPath = getCanonicalPathForLocation()

    if (!canonicalPath) {
      return
    }

    window.history.replaceState(
      null,
      '',
      buildPathWithLanguageAndSearch(
        canonicalPath,
        currentLanguage,
        window.location.search,
      ),
    )
    setCurrentPage(resolveCurrentPageFromLocation())
  }, [currentLanguage, currentPage])

  useEffect(() => {
    syncLanguageInCurrentUrl(currentLanguage)
  }, [currentLanguage])

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

    const currentPageMetadata = {
      ...pageMetadata[currentPage],
      url: window.location.href,
    }

    recordAccessPageView(currentPageMetadata)
    trackPageView(currentPageMetadata.path, currentPageMetadata.title)
  }, [analyticsEnabled, currentPage, trackPageView])

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

    const resolvePageContext = () => ({
      ...pageMetadata[currentPageRef.current],
      url: window.location.href,
    })

    const handleWindowError = (event: ErrorEvent) => {
      const message = event.message?.trim()
      const resourceTarget = event.target
      const resourceSource =
        resourceTarget instanceof HTMLImageElement
          ? resourceTarget.currentSrc || resourceTarget.src
          : resourceTarget instanceof HTMLScriptElement
            ? resourceTarget.src
            : resourceTarget instanceof HTMLLinkElement
              ? resourceTarget.href
              : ''
      const nextMessage =
        message ||
        (resourceSource
          ? `Falha ao carregar recurso: ${resourceSource}`
          : 'Erro de execução não identificado.')

      recordAccessError({
        pageContext: resolvePageContext(),
        source: 'window',
        message: nextMessage,
        stack: event.error instanceof Error ? event.error.stack : undefined,
      })
    }

    const handlePromiseRejection = (event: PromiseRejectionEvent) => {
      const reasonMessage =
        event.reason instanceof Error
          ? event.reason.message
          : typeof event.reason === 'string'
            ? event.reason
            : 'Promise rejeitada sem detalhe disponível.'

      recordAccessError({
        pageContext: resolvePageContext(),
        source: 'promise',
        message: reasonMessage,
        stack: event.reason instanceof Error ? event.reason.stack : undefined,
      })
    }

    window.addEventListener('error', handleWindowError, true)
    window.addEventListener('unhandledrejection', handlePromiseRejection)

    return () => {
      window.removeEventListener('error', handleWindowError, true)
      window.removeEventListener('unhandledrejection', handlePromiseRejection)
    }
  }, [analyticsEnabled])

  const navigateTo = (target: string) => {
    const normalizedTarget =
      target === 'trabalhe-conosco'
        ? 'jobs'
        : target === 'suporte' || target === 'suporte-tecnico'
          ? 'support'
          : target

    if (
      normalizedTarget === 'contact' ||
      normalizedTarget === 'jobs' ||
      normalizedTarget === 'candidate' ||
      normalizedTarget === 'support'
    ) {
      if (
        currentPage !== normalizedTarget ||
        normalizePathname(window.location.pathname) !==
          pageMetadata[normalizedTarget].path
      ) {
        window.history.pushState(
          null,
          '',
          buildPathWithLanguage(pageMetadata[normalizedTarget].path, currentLanguage),
        )
      }

      setCurrentPage(normalizedTarget)
      window.requestAnimationFrame(() => {
        window.scrollTo({ top: 0, behavior: 'smooth' })
      })
      return
    }

    if (
      currentPage !== 'home' ||
      normalizePathname(window.location.pathname) !== pageMetadata.home.path
    ) {
      window.history.pushState(
        null,
        '',
        buildPathWithLanguage(pageMetadata.home.path, currentLanguage),
      )
      setCurrentPage('home')

      window.setTimeout(() => {
        if (normalizedTarget === 'home') {
          window.scrollTo({ top: 0, behavior: 'smooth' })
          return
        }

        scrollToHomeSection(normalizedTarget)
        trackScrollToSection(normalizedTarget)
      }, 90)
      return
    }

    if (normalizedTarget === 'home') {
      window.scrollTo({ top: 0, behavior: 'smooth' })
      return
    }

    scrollToHomeSection(normalizedTarget)
    trackScrollToSection(normalizedTarget)
  }

  const handleAcceptAnalytics = () => {
    setAnalyticsConsent(setAccessAnalyticsConsentStatus('granted'))
  }

  const handleDeclineAnalytics = () => {
    setAnalyticsConsent(setAccessAnalyticsConsentStatus('denied'))
  }

  return (
    <div className='page-shell flex min-h-screen flex-col text-slate-950'>
      <SEO
        page={currentPage}
        url={buildLocalizedUrl(pageMetadata[currentPage].path, currentLanguage)}
        noIndex={currentPage === 'candidate'}
      />
      <Header currentPage={currentPage} navigateTo={navigateTo} />

      <main className='relative z-10 flex-1 w-full overflow-x-hidden pt-0'>
        <AnimatePresence mode='wait'>
          {currentPage === 'home' && (
            <motion.div
              key='home'
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              transition={{ duration: 0.35, ease: 'easeOut' }}
            >
              <Hero />
              <StudioShowcase onContactClick={() => navigateTo('contact')} />
            </motion.div>
          )}

          {currentPage === 'contact' && (
            <motion.div
              key='contact'
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              transition={{ duration: 0.3, ease: 'easeOut' }}
            >
              <ContactPage />
            </motion.div>
          )}

          {currentPage === 'jobs' && (
            <motion.div
              key='jobs'
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              transition={{ duration: 0.3, ease: 'easeOut' }}
            >
              <JobsPage navigateTo={navigateTo} />
            </motion.div>
          )}

          {currentPage === 'candidate' && (
            <motion.div
              key='candidate'
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              transition={{ duration: 0.3, ease: 'easeOut' }}
            >
              <CandidatePortalPage navigateTo={navigateTo} />
            </motion.div>
          )}

          {currentPage === 'support' && (
            <motion.div
              key='support'
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -20 }}
              transition={{ duration: 0.3, ease: 'easeOut' }}
            >
              <SupportPage />
            </motion.div>
          )}
        </AnimatePresence>
      </main>

      <Footer navigateTo={navigateTo} />

      {analyticsConsent === 'pending' && (
        <CookieConsentBanner
          onAccept={handleAcceptAnalytics}
          onDecline={handleDeclineAnalytics}
        />
      )}
    </div>
  )
}
