'use client'

import Cookies from 'js-cookie'
import { useEffect } from 'react'
import { useAnalyticsConsent } from '@/app/components/base/analytics-consent/consent-store'
import { useSearchParams } from '@/next/navigation'
import { rememberCreateAppExternalAttribution } from '@/utils/create-app-tracking'

const UTM_INFO_COOKIE = 'utm_info'
const UTM_INFO_COOKIE_EXPIRES_DAYS = 1
const UTM_INFO_QUERY_KEYS = [
  'utm_source',
  'utm_medium',
  'utm_campaign',
  'utm_content',
  'utm_term',
  'slug',
] as const

type SearchParamReader = {
  get: (name: string) => string | null
}

const normalizeString = (value?: string | null) => {
  const trimmed = value?.trim()
  return trimmed || undefined
}

const getSearchParamValue = (searchParams: SearchParamReader, key: string) =>
  normalizeString(searchParams.get(key))

const parseRedirectUrlSearchParams = (redirectUrl: string) => {
  const baseUrl = window.location.origin

  try {
    const url = new URL(redirectUrl, baseUrl)
    if (url.origin !== baseUrl) return null

    return url.searchParams
  } catch {
    return null
  }
}

const resolveAttributionSearchParams = (
  searchParams: SearchParamReader,
): SearchParamReader | null => {
  if (getSearchParamValue(searchParams, 'utm_source')) return searchParams

  const redirectUrl = getSearchParamValue(searchParams, 'redirect_url')
  if (!redirectUrl) return null

  return parseRedirectUrlSearchParams(redirectUrl)
}

/**
 * Captures external-campaign params (utm_* + blog `slug`) from the landing URL.
 *
 * Blog links point straight at cloud.dify.ai (e.g. `/apps?utm_source=dify_blog&slug=…`),
 * bypassing the marketing site that normally seeds the `utm_info` cookie. A new visitor
 * is bounced to sign-up, and the URL params are lost on that redirect — so we persist
 * them here, on the landing render, before the redirect happens:
 *
 * - `utm_info` cookie → read by the registration trackers, so slug is reported on
 *   registration even when the user registers before creating an app.
 * - create_app sessionStorage → read by `trackCreateApp`, so slug is reported on
 *   create_app.
 *
 * slug is intentionally NOT attached to page-view events; only these conversion events.
 */
const ExternalAttributionRecorder = () => {
  const analyticsConsent = useAnalyticsConsent()
  const searchParams = useSearchParams()

  useEffect(() => {
    if (analyticsConsent !== 'granted') return

    const attributionSearchParams = resolveAttributionSearchParams(searchParams)
    if (!attributionSearchParams) return

    const utmSource = getSearchParamValue(attributionSearchParams, 'utm_source')
    if (!utmSource) return

    // create_app conversion attribution (utm_source + slug).
    rememberCreateAppExternalAttribution({ searchParams: attributionSearchParams })

    // Seed the utm_info cookie the registration trackers read. A campaign click always
    // overwrites any previous value, so the most recent blog link wins (last-touch) and
    // a stale cookie from an earlier, un-converted visit can't shadow the new slug. This
    // mirrors the create_app attribution refreshed just above.
    const utmInfo: Record<string, string> = {}
    UTM_INFO_QUERY_KEYS.forEach((key) => {
      const value = getSearchParamValue(attributionSearchParams, key)
      if (value) utmInfo[key] = value
    })

    Cookies.set(UTM_INFO_COOKIE, JSON.stringify(utmInfo), {
      expires: UTM_INFO_COOKIE_EXPIRES_DAYS,
      path: '/',
    })
  }, [analyticsConsent, searchParams])

  return null
}

export default ExternalAttributionRecorder
