'use client'

import { FC, useEffect, useMemo, useRef, useState } from 'react'

import {
  deriveSocialIcon,
  fetchHeaderFooterData,
  getExternalDomainLabel,
  selectLocaleData,
} from 'shared-utils/header-footer'
import type {
  IHeaderFooter,
  IHeaderMenuLink,
  IHeaderMenuSection,
  THeaderFooterApi,
  THeaderMenuLocale,
} from 'shared-types'
import { PktConsent, type IPktConsent } from '../consent/Consent'
import { PktIcon } from '../icon/Icon'

/** The payload marks the cookie-settings entry with this pseudo-URL. */
const CONSENT_TRIGGER_URL = '#cb-trigger'

export type TFooterConsentConfig = Pick<
  IPktConsent,
  | 'hotjarId'
  | 'googleAnalyticsId'
  | 'devMode'
  | 'cookieDomain'
  | 'cookieSecure'
  | 'cookieExpiryDays'
  | 'onToggleConsent'
>

interface IUseGlobalFooterDataOptions {
  data?: THeaderFooterApi<string>
  dataUrl?: string
  locale?: THeaderMenuLocale
  skipGlobal?: boolean
  onDataError?: (error: Error) => void
}

export function useGlobalFooterData({
  data,
  dataUrl,
  locale = 'nb-NO',
  skipGlobal = false,
  onDataError,
}: IUseGlobalFooterDataOptions): IHeaderFooter | undefined {
  const [fetchedData, setFetchedData] = useState<THeaderFooterApi<string>>()
  const onDataErrorRef = useRef(onDataError)
  onDataErrorRef.current = onDataError

  useEffect(() => {
    if (data || skipGlobal) return
    const controller = new AbortController()
    fetchHeaderFooterData<string>(dataUrl, controller.signal)
      .then((payload) => {
        if (!controller.signal.aborted) setFetchedData(payload)
      })
      .catch((error: Error) => {
        if (error.name === 'AbortError') return
        // eslint-disable-next-line no-console -- Error on fetching data
        console.warn('Failed to fetch header/footer data:', error)
        onDataErrorRef.current?.(error)
      })
    return () => controller.abort()
  }, [data, dataUrl, skipGlobal])

  const effectiveData = data ?? fetchedData
  return useMemo(() => {
    if (skipGlobal) return undefined
    return selectLocaleData(effectiveData, locale)?.footer
  }, [effectiveData, locale, skipGlobal])
}

interface ISectionLinkProps {
  link: IHeaderMenuLink
  includeConsent: boolean
  consent: TFooterConsentConfig
}

const SectionLink: FC<ISectionLinkProps> = ({ link, includeConsent, consent }) => {
  if (link.url === CONSENT_TRIGGER_URL) {
    // Punkt's own consent dialog replaces the CDN cookie-banner trigger.
    if (!includeConsent) return null
    return (
      <li>
        <PktConsent triggerType="footerlink" triggerText={link.text} {...consent} />
      </li>
    )
  }
  const domain = getExternalDomainLabel(link.url)
  return (
    <li>
      <a href={link.url}>
        {link.text}
        {domain && <span className="pkt-footer__link-domain"> ({domain})</span>}
      </a>
    </li>
  )
}

const Section: FC<{ section: IHeaderMenuSection } & Omit<ISectionLinkProps, 'link'>> = ({
  section,
  includeConsent,
  consent,
}) => (
  <section>
    <h2>{section.title}</h2>
    <ul className="pkt-footer__link-list">
      {section.links.map((link) => (
        <SectionLink key={`${link.url}|${link.text}`} link={link} includeConsent={includeConsent} consent={consent} />
      ))}
    </ul>
  </section>
)

const SomeLink: FC<{ entry: IHeaderMenuLink }> = ({ entry }) => {
  const icon = deriveSocialIcon(entry.url, entry.text)
  if (!icon) {
    return (
      <li>
        <a href={entry.url}>{entry.text}</a>
      </li>
    )
  }
  return (
    <li>
      <a className="pkt-footer__some-link" href={entry.url} aria-label={entry.text}>
        <PktIcon className="pkt-footer__some-icon" name={icon} />
      </a>
    </li>
  )
}

interface IFooterGlobalProps {
  footer: IHeaderFooter
  includeConsent?: boolean
  consent?: TFooterConsentConfig
}

/**
 * The global (blue) footer band, fed by the shared header/footer payload.
 * Internal — rendered by PktFooter / PktFooterSimple, not exported.
 */
export const FooterGlobal: FC<IFooterGlobalProps> = ({ footer, includeConsent = false, consent = {} }) => {
  const hasLinks = footer.links?.length > 0
  const hasSome = footer.some?.length > 0
  return (
    <div className="pkt-footer__band pkt-footer__band--global">
      <div className="pkt-footer__inner">
        <div className="pkt-footer__sections">
          {footer.sections.map((section) => (
            <Section key={section.title} section={section} includeConsent={includeConsent} consent={consent} />
          ))}
          {(hasLinks || hasSome) && (
            <div className="pkt-footer__bottom">
              {hasLinks && (
                <ul className="pkt-footer__bottom-links">
                  {footer.links.map((link) => (
                    <li key={`${link.url}|${link.text}`}>
                      <a href={link.url}>{link.text}</a>
                    </li>
                  ))}
                </ul>
              )}
              {hasSome && (
                <ul className="pkt-footer__some">
                  {footer.some.map((entry) => (
                    <SomeLink key={`${entry.url}|${entry.text}`} entry={entry} />
                  ))}
                </ul>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  )
}
