import { lazy, Suspense, useState, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useFadeInRef } from '../../hooks/useFadeIn';
import { useIsMobile } from '../../hooks/useIsMobile';
import HexCanvas from './HexCanvas';
import HomeFinalCta from './HomeFinalCta';
import BottomIllustration from './BottomIllustration';
import { TickerValue } from '../ui/TickerValue';
import { ChevronIcon, LogoIcon, PlayIcon } from '../ui/icons';
import { trackEvent } from '../../lib/analytics';
import { apiUrl } from '../../lib/api';

const BRAND_NAME = 'Perfect Postcode';
const BRAND_TEXT_CLASS = 'text-teal-600 dark:text-teal-400';
const HOME_SECTION_CONTAINER_CLASS = 'max-w-7xl mx-auto px-6 md:px-10';
const HOME_SECTION_HEADING_CLASS =
  'text-2xl md:text-3xl font-bold text-navy-950 dark:text-warm-100';
const HOME_BODY_CLASS = 'text-base leading-relaxed text-warm-600 dark:text-warm-400';
const HOME_PRIMARY_BUTTON_CLASS =
  'border border-[#d27a11] bg-[#f09a22] text-navy-950 rounded-lg font-semibold hover:bg-[#df8614] transition-colors text-base shadow-lg shadow-[#7a3905]/25 text-center';
const PRODUCT_DEMO_VIDEO_BY_LANGUAGE: Record<string, string> = {
  en: 'recording',
  de: 'recording-de',
  zh: 'recording-zh',
  hi: 'recording-hi',
};
const PRODUCT_DEMO_SECTION_ID = 'product-demo-video';
const ProductShowcase = lazy(() => import('./ProductShowcase'));

function ProductShowcaseFallback({ className = '' }: { className?: string }) {
  return (
    <div
      className={`min-h-[28rem] rounded-lg border border-white/10 bg-navy-950/35 dark:bg-navy-950/45 ${className}`}
      aria-hidden="true"
    />
  );
}

function getProductDemoSlug(language: string | undefined, isMobile: boolean): string {
  const code = language?.toLowerCase().split('-')[0] ?? 'en';
  const base = PRODUCT_DEMO_VIDEO_BY_LANGUAGE[code] ?? PRODUCT_DEMO_VIDEO_BY_LANGUAGE.en;
  // Mobile cuts (9:16, 540x960) are published as `<base>-mobile` alongside
  // the 16:9 desktop cuts. The recorder pipeline writes both every render —
  // see video/src/storyboard.ts.
  return isMobile ? `${base}-mobile` : base;
}

function highlightBrandText(text: string, className = BRAND_TEXT_CLASS) {
  const parts = text.split(BRAND_NAME);
  if (parts.length === 1) return text;

  return parts.flatMap((part, index) =>
    index === 0
      ? [part]
      : [
          <span key={`brand-${index}`} className={className}>
            {BRAND_NAME}
          </span>,
          part,
        ]
  );
}

function ProductDemoVideo() {
  const { t, i18n } = useTranslation();
  const isMobile = useIsMobile();
  const sectionRef = useRef<HTMLDivElement | null>(null);
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const currentVideoSrcRef = useRef<string | null>(null);
  const [shouldLoadVideo, setShouldLoadVideo] = useState(false);
  const [isVideoPlaying, setIsVideoPlaying] = useState(false);
  const productDemoSlug = getProductDemoSlug(i18n.language, isMobile);
  const productDemoVideoSrc = `/video/${productDemoSlug}.mp4`;
  const productDemoPosterSrc = `/video/${productDemoSlug}.jpg`;

  useEffect(() => {
    if (currentVideoSrcRef.current === productDemoVideoSrc) return;
    currentVideoSrcRef.current = productDemoVideoSrc;
    setIsVideoPlaying(false);

    const video = videoRef.current;
    if (!video || !shouldLoadVideo) return;
    video.pause();
    video.load();
  }, [productDemoVideoSrc, shouldLoadVideo]);

  useEffect(() => {
    const section = sectionRef.current;
    if (!section || shouldLoadVideo) return;

    if (!('IntersectionObserver' in window)) {
      setShouldLoadVideo(true);
      return;
    }

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (!entry.isIntersecting) return;
        setShouldLoadVideo(true);
        observer.disconnect();
      },
      { rootMargin: '600px 0px' }
    );

    observer.observe(section);
    return () => observer.disconnect();
  }, [shouldLoadVideo]);

  const playVideo = () => {
    const video = videoRef.current;
    setShouldLoadVideo(true);
    if (!video) return;

    if (video.getAttribute('src') !== productDemoVideoSrc) {
      video.src = productDemoVideoSrc;
      video.load();
    }

    void video.play().catch(() => {
      setIsVideoPlaying(false);
    });
  };

  return (
    <div
      id={PRODUCT_DEMO_SECTION_ID}
      ref={sectionRef}
      className={`${HOME_SECTION_CONTAINER_CLASS} pt-8 md:pt-12 pb-2`}
    >
      <div
        className={`relative overflow-hidden rounded-lg border border-warm-200 bg-navy-950 shadow-sm dark:border-warm-700 ${
          isMobile ? 'mx-auto max-w-sm' : ''
        }`}
      >
        <video
          ref={videoRef}
          src={shouldLoadVideo ? productDemoVideoSrc : undefined}
          poster={productDemoPosterSrc}
          controls
          playsInline
          preload={shouldLoadVideo ? 'metadata' : 'none'}
          className={`block w-full bg-navy-950 object-contain ${
            isMobile ? 'aspect-[9/16]' : 'aspect-video'
          }`}
          aria-label={t('home.productDemoLabel')}
          onPlay={() => setIsVideoPlaying(true)}
          onPause={() => setIsVideoPlaying(false)}
          onEnded={() => setIsVideoPlaying(false)}
        />
        {!isVideoPlaying && (
          <div className="pointer-events-none absolute inset-0 flex items-center justify-center bg-navy-950/15 transition-colors">
            <button
              type="button"
              onClick={playVideo}
              className="pointer-events-auto group flex h-20 w-20 items-center justify-center rounded-full bg-white/95 text-coral-500 shadow-2xl shadow-navy-950/40 ring-1 ring-white/60 transition-transform hover:scale-105 focus:outline-none focus-visible:scale-105 focus-visible:ring-4 focus-visible:ring-teal-300/75 md:h-24 md:w-24"
              aria-label={t('home.playProductDemo')}
            >
              <PlayIcon className="h-11 w-11 -translate-x-0.5 md:h-14 md:w-14" />
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

interface PriceStripTier {
  up_to: number | null;
  price_pence: number;
}

/**
 * Compact pricing teaser under the hero CTAs: surfaces the current lifetime
 * price and tier scarcity that otherwise hide behind the Pricing nav link.
 */
function PriceStrip({
  onOpenPricing,
  hidePricing,
}: {
  onOpenPricing: () => void;
  hidePricing?: boolean;
}) {
  const { t } = useTranslation();
  const [pricing, setPricing] = useState<{
    licensed_count: number;
    current_price_pence: number;
    tiers: PriceStripTier[];
  } | null>(null);

  useEffect(() => {
    if (hidePricing) return;
    const controller = new AbortController();
    fetch(apiUrl('pricing'), { signal: controller.signal })
      .then((res) => (res.ok ? res.json() : null))
      .then(setPricing)
      .catch(() => {});
    return () => controller.abort();
  }, [hidePricing]);

  if (hidePricing || !pricing) return null;

  const price = `£${pricing.current_price_pence / 100}`;
  const currentTier = pricing.tiers.find(
    (tier) => tier.up_to === null || pricing.licensed_count < tier.up_to
  );
  const spotsRemaining =
    currentTier?.up_to != null ? currentTier.up_to - pricing.licensed_count : 0;

  return (
    <p className="text-sm text-warm-300 mb-2">
      {pricing.current_price_pence === 0
        ? t('upgrade.freeForEarly')
        : t('home.priceStrip', { price })}{' '}
      {pricing.current_price_pence > 0 && spotsRemaining > 0 && (
        <span className="font-semibold text-teal-300">
          {spotsRemaining === 1
            ? t('home.priceStripSpots', { count: spotsRemaining })
            : t('home.priceStripSpotsPlural', { count: spotsRemaining })}
        </span>
      )}{' '}
      <button
        onClick={() => {
          trackEvent('CTA Click', { location: 'hero', label: 'price_strip' });
          onOpenPricing();
        }}
        className="underline decoration-dotted underline-offset-2 text-teal-300 hover:text-teal-200"
      >
        {t('home.priceStripCta')}
      </button>
    </p>
  );
}

export default function HomePage({
  onOpenDashboard,
  onOpenPricing,
  theme = 'light',
  hidePricing,
}: {
  onOpenDashboard: () => void;
  onOpenPricing: () => void;
  theme?: 'light' | 'dark';
  hidePricing?: boolean;
}) {
  const { t } = useTranslation();
  const [statsActive, setStatsActive] = useState(false);
  const homeScrollerRef = useRef<HTMLDivElement | null>(null);
  const homeSurfaceRef = useRef<HTMLDivElement | null>(null);
  useEffect(() => {
    const timer = setTimeout(() => setStatsActive(true), 300);
    return () => clearTimeout(timer);
  }, []);

  const whyRef = useFadeInRef();
  const ctaRef = useFadeInRef();

  useEffect(() => {
    const scroller = homeScrollerRef.current;
    if (!scroller) return;

    let frame = 0;
    const syncParallax = () => {
      frame = 0;
      scroller.style.setProperty('--home-scroll-y', `${scroller.scrollTop}px`);
    };
    const onScroll = () => {
      if (frame) return;
      frame = requestAnimationFrame(syncParallax);
    };

    syncParallax();
    scroller.addEventListener('scroll', onScroll, { passive: true });
    return () => {
      scroller.removeEventListener('scroll', onScroll);
      if (frame) cancelAnimationFrame(frame);
    };
  }, []);

  useEffect(() => {
    const surface = homeSurfaceRef.current;
    if (!surface) return;

    let frame = 0;
    let pointerX = 0;
    let pointerY = 0;

    const syncPointer = () => {
      frame = 0;
      surface.style.setProperty('--home-pointer-x', `${pointerX}px`);
      surface.style.setProperty('--home-pointer-y', `${pointerY}px`);
    };
    const queuePointerSync = (event: PointerEvent) => {
      const rect = surface.getBoundingClientRect();
      pointerX = event.clientX - rect.left;
      pointerY = event.clientY - rect.top;
      if (frame) return;
      frame = requestAnimationFrame(syncPointer);
    };
    const onPointerEnter = (event: PointerEvent) => {
      queuePointerSync(event);
      surface.style.setProperty('--home-pointer-active', '1');
    };
    const onPointerLeave = () => {
      surface.style.setProperty('--home-pointer-active', '0');
    };

    surface.style.setProperty('--home-pointer-active', '0');
    surface.addEventListener('pointerenter', onPointerEnter);
    surface.addEventListener('pointermove', queuePointerSync, { passive: true });
    surface.addEventListener('pointerleave', onPointerLeave);
    return () => {
      surface.removeEventListener('pointerenter', onPointerEnter);
      surface.removeEventListener('pointermove', queuePointerSync);
      surface.removeEventListener('pointerleave', onPointerLeave);
      if (frame) cancelAnimationFrame(frame);
    };
  }, []);

  // Scroll depth tracking
  const scrolledSections = useRef(new Set<string>());
  useEffect(() => {
    const ids = ['how-it-works'];
    const observers: IntersectionObserver[] = [];
    ids.forEach((id) => {
      const el = document.getElementById(id);
      if (!el) return;
      const observer = new IntersectionObserver(
        ([entry]) => {
          if (entry.isIntersecting && !scrolledSections.current.has(id)) {
            scrolledSections.current.add(id);
            trackEvent('Scroll Depth', { section: id });
          }
        },
        { threshold: 0.1 }
      );
      observer.observe(el);
      observers.push(observer);
    });
    return () => observers.forEach((o) => o.disconnect());
  }, []);

  // 30s time-on-page event
  useEffect(() => {
    const timer = setTimeout(() => trackEvent('Time on Page', { seconds: '30' }), 30000);
    return () => clearTimeout(timer);
  }, []);

  const scrollToProductDemoVideo = () => {
    const target = document.getElementById(PRODUCT_DEMO_SECTION_ID);
    if (!target) return;
    const scroller = target.closest('.overflow-y-auto') as HTMLElement | null;
    if (!scroller) return;
    const start = scroller.scrollTop;
    const end =
      start + target.getBoundingClientRect().top - scroller.getBoundingClientRect().top + 24;
    const distance = end - start;
    const duration = 1200;
    let startTime: number;
    const step = (time: number) => {
      if (!startTime) startTime = time;
      const p = Math.min((time - startTime) / duration, 1);
      const ease = p < 0.5 ? 4 * p * p * p : 1 - Math.pow(-2 * p + 2, 3) / 2;
      scroller.scrollTop = start + distance * ease;
      if (p < 1) requestAnimationFrame(step);
    };
    requestAnimationFrame(step);
  };

  return (
    <div
      ref={homeScrollerRef}
      className="home-page-scroll flex-1 overflow-y-auto overflow-x-hidden bg-warm-50 dark:bg-navy-950 relative"
    >
      <div className="relative" style={{ zIndex: 1 }}>
        {/* Hero */}
        <div className="relative overflow-hidden bg-gradient-to-b from-navy-950 via-navy-900 to-navy-900 dark:from-navy-950 dark:via-navy-900 dark:to-navy-950 min-h-[calc(100dvh-3rem)] flex flex-col">
          <HexCanvas
            isDark={theme === 'dark'}
            animated={false}
            className="home-hero-hex-parallax"
          />
          <div className="home-hero-container relative z-10 mx-auto flex w-full max-w-[104rem] flex-1 flex-col px-6 pb-8 pt-6 backdrop-blur-[2px] md:px-10 md:py-10">
            <div className="home-hero-layout hero-roomy-lift grid flex-1 items-center gap-x-8 gap-y-6">
              <div className="home-hero-copy min-w-0 max-w-4xl">
                <p className="text-sm font-semibold text-teal-300 mb-3">{t('home.heroEyebrow')}</p>
                <h1 className="text-3xl md:text-5xl font-extrabold text-white mb-4 leading-[1.1]">
                  {t('home.heroTitle1')}{' '}
                  <span className="text-teal-400">{t('home.heroTitle2')}</span>.
                  <br />
                  {t('home.heroTitle3')}
                </h1>
                <p className="text-base md:text-lg text-warm-100 mb-6 leading-relaxed max-w-xl">
                  {t('home.heroSubtitle')}
                </p>
                <p className="text-base md:text-lg text-warm-200 mb-8 max-w-xl">
                  {highlightBrandText(t('home.heroDescription'), 'font-semibold text-teal-300')}
                </p>
                <div className="flex flex-col sm:flex-row sm:items-center gap-3 sm:gap-4 mb-5">
                  <button
                    onClick={() => {
                      trackEvent('CTA Click', { location: 'hero', label: 'explore_map' });
                      onOpenDashboard();
                    }}
                    className={`px-7 py-3.5 ${HOME_PRIMARY_BUTTON_CLASS}`}
                  >
                    {t('home.exploreTheMap')}
                  </button>
                  <button
                    onClick={() => {
                      trackEvent('CTA Click', { location: 'hero', label: 'see_difference' });
                      scrollToProductDemoVideo();
                    }}
                    className="px-7 py-3 border-2 border-teal-400 text-teal-400 rounded-lg font-semibold hover:bg-teal-400/10 transition-colors text-base text-center"
                  >
                    {t('home.seeTheDifference')}
                  </button>
                </div>
                <PriceStrip onOpenPricing={onOpenPricing} hidePricing={hidePricing} />
                <p className="text-sm text-warm-400 mb-8">{t('home.coverageNote')}</p>
                <div className="home-hero-stats flex flex-wrap pt-3 border-t border-white/10">
                  <div className="home-hero-stat">
                    <div className="home-hero-stat-value">
                      <TickerValue text="13M" active={statsActive} />
                    </div>
                    <div className="home-hero-stat-label">{t('home.statProperties')}</div>
                  </div>
                  <div className="home-hero-stat">
                    <div className="home-hero-stat-value">
                      <TickerValue text="40+" active={statsActive} />
                    </div>
                    <div className="home-hero-stat-label">{t('home.statFilters')}</div>
                  </div>
                  <div className="home-hero-stat">
                    <div className="home-hero-stat-value">{t('home.statEvery')}</div>
                    <div className="home-hero-stat-label">{t('home.statPostcodeInEngland')}</div>
                  </div>
                </div>
              </div>
              <Suspense fallback={<ProductShowcaseFallback />}>
                <ProductShowcase />
              </Suspense>
            </div>
          </div>
          <button
            type="button"
            className="hero-scroll-chevron absolute bottom-4 left-1/2 z-20 -translate-x-1/2 items-center justify-center rounded-full text-white transition-colors hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/50"
            aria-label={t('home.scrollToProductDemo')}
            onClick={() => {
              trackEvent('CTA Click', { location: 'hero_chevron', label: 'scroll_down' });
              scrollToProductDemoVideo();
            }}
          >
            <ChevronIcon direction="down" className="h-14 w-14" />
          </button>
        </div>

        <div ref={homeSurfaceRef} className="home-content-surface relative overflow-hidden">
          <div className="relative z-10">
            <ProductDemoVideo />

            {/* Our philosophy */}
            <div className={`${HOME_SECTION_CONTAINER_CLASS} pt-12 md:pt-20 pb-4`}>
              <h2 className={`${HOME_SECTION_HEADING_CLASS} mb-6`}>{t('home.ourPhilosophy')}</h2>
              <div className="space-y-4 text-base md:text-lg leading-relaxed text-warm-700 dark:text-warm-300">
                <p>{t('home.philosophyP1')}</p>
                <p>{highlightBrandText(t('home.philosophyP2'))}</p>
              </div>
            </div>

            {/* Street-level detail */}
            <div className={`${HOME_SECTION_CONTAINER_CLASS} pt-10 md:pt-16 pb-2`}>
              <div className="grid gap-6 md:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)] md:items-start">
                <div>
                  <h2 className={`${HOME_SECTION_HEADING_CLASS} mb-4`}>{t('home.streetTitle')}</h2>
                  <p className={`${HOME_BODY_CLASS} max-w-2xl`}>{t('home.streetIntro')}</p>
                </div>
                <div className="grid gap-4 sm:grid-cols-2">
                  {[
                    {
                      title: t('home.streetCard1Title'),
                      body: t('home.streetCard1Body'),
                    },
                    {
                      title: t('home.streetCard2Title'),
                      body: t('home.streetCard2Body'),
                    },
                  ].map((item) => (
                    <div
                      key={item.title}
                      className="rounded-lg border border-warm-200 bg-white/90 p-5 shadow-sm dark:border-warm-700 dark:bg-warm-800/90"
                    >
                      <h3 className="text-base font-bold text-navy-950 dark:text-warm-100">
                        {item.title}
                      </h3>
                      <p className="mt-3 text-sm leading-relaxed text-warm-600 dark:text-warm-400">
                        {item.body}
                      </p>
                    </div>
                  ))}
                </div>
              </div>
            </div>

            {/* Comparison table */}
            <div
              id="how-it-works"
              className={`${HOME_SECTION_CONTAINER_CLASS} pt-10 md:pt-16 pb-2`}
            >
              <div ref={whyRef} className="fade-in-section">
                <div id="comparison">
                  <h2
                    className={`${HOME_SECTION_HEADING_CLASS} mb-6 flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-center md:mb-10 md:gap-x-3`}
                  >
                    <span>{t('home.othersVs')}</span>
                    <span className="inline-flex items-center gap-2 md:gap-3">
                      <span className={BRAND_TEXT_CLASS}>{t('header.appName')}</span>
                      <LogoIcon className="h-[1em] w-[1em] shrink-0 text-teal-600 dark:text-teal-400" />
                    </span>
                  </h2>
                  <div className="overflow-x-auto rounded-xl border border-warm-200 dark:border-warm-700 bg-white/95 dark:bg-warm-800/95 shadow-sm">
                    <table className="w-full text-left">
                      <thead>
                        <tr className="border-b border-warm-200 dark:border-warm-700 bg-warm-50 dark:bg-warm-800">
                          <th className="px-2 md:px-5 py-3 md:py-4 text-xs font-bold text-navy-950 dark:text-warm-100" />
                          <th className="px-1.5 md:px-3 py-3 md:py-4 text-xs font-bold text-navy-950 dark:text-warm-100 text-center">
                            {t('home.checkMyPostcode')}
                          </th>
                          <th className="px-1.5 md:px-3 py-3 md:py-4 text-xs font-bold text-navy-950 dark:text-warm-100 text-center">
                            {t('home.areaGuides')}
                          </th>
                          <th className="px-1.5 md:px-3 py-3 md:py-4 text-xs font-extrabold text-navy-950 dark:text-warm-100 text-center bg-teal-50 dark:bg-teal-900/30">
                            <span className={BRAND_TEXT_CLASS}>{t('header.appName')}</span>
                          </th>
                        </tr>
                      </thead>
                      <tbody>
                        {[
                          {
                            feature: t('home.compSearchWithout'),
                            subtitle: t('home.compSearchWithoutSub'),
                            postcode: false,
                            guides: false,
                          },
                          {
                            feature: t('home.compAreaData'),
                            subtitle: t('home.compAreaDataSub'),
                            postcode: true,
                            guides: true,
                          },
                          {
                            feature: t('home.compPropertyData'),
                            subtitle: t('home.compPropertyDataSub'),
                            postcode: false,
                            guides: true,
                          },
                          {
                            feature: t('home.compFilters'),
                            subtitle: t('home.compFiltersSub'),
                            postcode: false,
                            guides: false,
                          },
                        ].map((row, i, arr) => (
                          <tr
                            key={i}
                            className={
                              i < arr.length - 1
                                ? 'border-b border-warm-100 dark:border-warm-800'
                                : ''
                            }
                          >
                            <td className="px-2 md:px-5 py-2.5 md:py-3.5 text-sm text-warm-700 dark:text-warm-300">
                              {row.feature}
                              {row.subtitle && (
                                <div className="italic text-warm-500 dark:text-warm-400">
                                  {row.subtitle}
                                </div>
                              )}
                            </td>
                            {[row.postcode, row.guides].map((has, j) => {
                              const statusLabel = has ? t('common.yes') : t('common.no');
                              return (
                                <td
                                  key={j}
                                  aria-label={statusLabel}
                                  className={`px-1.5 md:px-3 py-2.5 md:py-3.5 text-center text-base ${has ? 'text-green-500' : 'text-red-500'}`}
                                >
                                  <span aria-hidden="true">{has ? '\u2713' : '\u2717'}</span>
                                  <span className="sr-only">{statusLabel}</span>
                                </td>
                              );
                            })}
                            <td
                              aria-label={t('common.yes')}
                              className="px-1.5 md:px-3 py-2.5 md:py-3.5 text-center text-base text-green-500 bg-teal-50 dark:bg-teal-900/30"
                            >
                              <span aria-hidden="true">&#x2713;</span>
                              <span className="sr-only">{t('common.yes')}</span>
                            </td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                </div>
              </div>
            </div>

            {/* The real cost CTA */}
            <div className={`${HOME_SECTION_CONTAINER_CLASS} pt-8 md:pt-14 pb-12`}>
              <div ref={ctaRef} className="fade-in-section">
                <HomeFinalCta onOpenDashboard={onOpenDashboard} />
              </div>
            </div>

            {/* Bottom illustration */}
            <BottomIllustration isDark={theme === 'dark'} />
          </div>
        </div>
      </div>
    </div>
  );
}
