"use client";

import { useEffect, useMemo, useRef, useState, type CSSProperties } from 'react';
import { Flame } from 'lucide-react';
import type { ZoneData } from '@/data/zones';
import { zoneInPhrase } from '@/lib/zoneGeo';
import { getHeatTimelineMarkers } from '@/components/climateScrollProjection';

type ClimateScrollBlockProps = {
  zoneData: ZoneData;
};

const frDec = (value: number) => value.toFixed(1).replace('.', ',');

const clamp01 = (value: number) => Math.max(0, Math.min(1, value));
const TIMELINE_STEP_REM = 25.5;
const SCROLL_PROGRESS_COMPLETE = 0.9;

type ClimateStyle = CSSProperties & {
  '--heat': string;
  '--timeline-shift': string;
};

type TimelineCopy = {
  chapter: string;
  sourceLine: string;
  situationText: string;
  teamImpact: string;
};

const TIMELINE_COPY: Record<number, TimelineCopy> = {
  2026: {
    chapter: 'Référence actuelle',
    sourceLine: 'Trajectoire médiane du GIEC appliquée à votre zone : l’été actuel sert de point de départ.',
    situationText: 'Les journées au-dessus de 30°C existent déjà dans le calendrier d’exploitation.',
    teamImpact: 'Sur les quais exposés, les fins de journée deviennent plus difficiles pour les équipes.',
  },
  2031: {
    chapter: 'Premières tensions',
    sourceLine: 'À court terme, quelques jours chauds en plus suffisent à changer l’organisation.',
    situationText: 'La chaleur ne reste plus cantonnée aux pics de canicule : elle s’installe plus souvent.',
    teamImpact: 'Les pauses chaleur se multiplient et les équipes ralentissent plus tôt l’après-midi.',
  },
  2036: {
    chapter: 'Alerte chaleur',
    sourceLine: 'À dix ans, la trajectoire climatique se confirme sur les bâtiments industriels.',
    situationText: 'Le nombre de jours critiques progresse, avec une température estivale moyenne plus haute.',
    teamImpact: 'La cadence baisse près des portes sectionnelles et sous les toitures bac acier.',
  },
  2041: {
    chapter: 'Risque critique',
    sourceLine: 'Le réchauffement sort du registre météo : il pèse sur l’exploitation et les équipements.',
    situationText: 'Les périodes chaudes deviennent assez longues pour fragiliser les process sensibles.',
    teamImpact: 'Les groupes froids tournent plus longtemps pour maintenir les stocks et les postes exposés.',
  },
  2046: {
    chapter: 'Adaptation obligatoire',
    sourceLine: 'À vingt ans, l’adaptation devient une décision de continuité pour les bâtiments non protégés.',
    situationText: 'La chaleur n’est plus un aléa ponctuel : elle structure les coûts et les contraintes d’été.',
    teamImpact: 'La toiture devient un levier de continuité d’exploitation, pas seulement un support technique.',
  },
};

function getZoneLabel(zone: ZoneData): string {
  return zoneInPhrase(zone);
}

function getActiveTimelineIndex(progress: number): number {
  if (progress < 0.125) return 0;
  if (progress < 0.375) return 1;
  if (progress < 0.625) return 2;
  if (progress < 0.875) return 3;
  return 4;
}

const ClimateScrollBlock = ({ zoneData }: ClimateScrollBlockProps) => {
  const trackRef = useRef<HTMLDivElement>(null);

  const [progress, setProgress] = useState(0);
  const [reducedMotion, setReducedMotion] = useState(false);

  const timeline = useMemo(() => getHeatTimelineMarkers(zoneData), [zoneData]);
  const finalProjection = timeline[timeline.length - 1]?.projection ?? timeline[0]?.projection;
  const activeIndex = reducedMotion ? timeline.length - 1 : getActiveTimelineIndex(progress);
  const heatProgress = reducedMotion ? 1 : progress;
  const timelineShift = heatProgress * (timeline.length - 1) * TIMELINE_STEP_REM;

  const sceneStyle: ClimateStyle = {
    '--heat': String(heatProgress),
    '--timeline-shift': `${timelineShift}rem`,
  };

  useEffect(() => {
    const motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');

    const syncMotion = () => {
      const shouldReduce = motionQuery.matches;
      setReducedMotion(shouldReduce);
      if (shouldReduce) {
        setProgress(1);
      }
    };

    syncMotion();
    motionQuery.addEventListener('change', syncMotion);

    return () => {
      motionQuery.removeEventListener('change', syncMotion);
    };
  }, []);

  useEffect(() => {
    if (reducedMotion) return undefined;

    const updateTarget = () => {
      const section = trackRef.current;
      if (!section) return;

      const rect = section.getBoundingClientRect();
      const scrollableDistance = Math.max(rect.height - window.innerHeight, 1);
      const rawProgress = clamp01(-rect.top / scrollableDistance);
      setProgress(clamp01(rawProgress / SCROLL_PROGRESS_COMPLETE));
    };

    window.addEventListener('scroll', updateTarget, { passive: true });
    window.addEventListener('resize', updateTarget);
    updateTarget();

    return () => {
      window.removeEventListener('scroll', updateTarget);
      window.removeEventListener('resize', updateTarget);
    };
  }, [reducedMotion]);

  const renderTimelineMarker = (
    marker: ReturnType<typeof getHeatTimelineMarkers>[number],
    index: number,
  ) => {
    const copy = TIMELINE_COPY[marker.year];
    const projection = marker.projection;
    const isActive = index === activeIndex;

    return (
      <li
        key={marker.year}
        className={[
          'relative min-h-[22.5rem] transition-all duration-700',
          isActive ? 'opacity-100' : 'opacity-[0.64]',
        ].join(' ')}
      >
        <div className="flex flex-wrap items-end gap-x-4 gap-y-1">
          <span className="font-satoshi text-5xl font-black leading-none text-white tabular-nums drop-shadow-[0_0_22px_rgba(255,255,255,0.16)] md:text-[4.7rem]">
            {marker.year}
          </span>
          <span className="font-satoshi text-2xl font-black leading-tight text-white/92 md:text-3xl">
            {copy.chapter}
          </span>
        </div>

        <div className="mt-4 min-w-0">
          <div className="grid max-w-2xl grid-cols-3 border-y border-white/12 py-3">
            <div className="pr-4">
              <p className="font-satoshi text-2xl font-black leading-none text-white tabular-nums md:text-3xl">
                {projection.days}
              </p>
              <p className="mt-1 text-[11px] font-bold uppercase leading-tight text-red-100/76">
                jours &gt; 30°C
              </p>
            </div>
            <div className="border-l border-white/12 px-4">
              <p className="font-satoshi text-2xl font-black leading-none text-white tabular-nums md:text-3xl">
                {projection.dayDelta > 0 ? `+${projection.dayDelta}` : '0'}
              </p>
              <p className="mt-1 text-[11px] font-bold uppercase leading-tight text-white/62">
                {projection.dayDelta > 0 ? 'jours vs 2026' : 'référence 2026'}
              </p>
            </div>
            <div className="border-l border-white/12 pl-4">
              <p className="font-satoshi text-2xl font-black leading-none text-white tabular-nums md:text-3xl">
                {frDec(projection.temp)}°C
              </p>
              <p className="mt-1 text-[11px] font-bold uppercase leading-tight text-teal-100/76">
                moyenne estivale
              </p>
            </div>
          </div>

          <p className="mt-5 max-w-2xl text-base leading-relaxed text-white/66 md:text-lg">
            {copy.sourceLine} {copy.situationText}
          </p>
          <p className="mt-3 max-w-2xl text-base font-semibold leading-relaxed text-white/90 md:text-lg">
            Impact équipes : {copy.teamImpact}
          </p>
        </div>
      </li>
    );
  };

  return (
    <section
      ref={trackRef}
      className="relative bg-[#05070b] pb-24 pt-14 text-white md:h-[360svh] md:py-0"
      aria-labelledby="climate-scroll-title"
    >
      <div
        className="relative overflow-hidden bg-[#05070b] text-white md:sticky md:top-0 md:h-[100svh] md:min-h-[640px]"
        style={sceneStyle}
      >
        <div
          className="absolute inset-0 pointer-events-none"
          style={{
            background:
              'linear-gradient(180deg, rgba(5,7,11,0.98), rgba(5,7,11,0.94))',
          }}
        />
        <div
          className="absolute inset-0 pointer-events-none"
          style={{
            opacity: 'calc(0.12 + var(--heat) * 0.46)',
            background:
              'linear-gradient(180deg, rgba(29,115,121,0.22) 0%, rgba(129,57,49,0.20) 58%, rgba(174,41,36,0.36) 100%)',
          }}
        />
        <div
          className="absolute inset-0 pointer-events-none"
          style={{
            opacity: 'calc(var(--heat) * 0.34)',
            background:
              'radial-gradient(circle at 72% 54%, rgba(229,61,48,0.42), rgba(114,38,35,0.18) 38%, transparent 72%)',
          }}
        />

        <div className="relative z-10 mx-auto grid max-w-7xl gap-8 px-4 md:h-full md:grid-cols-[minmax(280px,0.56fr)_minmax(560px,1fr)] md:items-center md:gap-8 md:px-8 md:pb-10 md:pt-24 lg:px-14">
          <div className="max-w-xl">
            <p className="text-[10px] font-semibold uppercase text-teal-200/75">
              Prévision chaleur
            </p>

            <h2
              id="climate-scroll-title"
              className="mt-3 font-satoshi text-[1.82rem] font-black leading-[1.04] text-white sm:text-[2.35rem] md:text-[2.35rem] lg:text-[2.85rem]"
            >
              Et cela va empirer dans les 20 prochaines années.
            </h2>

            <p className="mt-3 max-w-lg text-sm leading-relaxed text-white/72 md:mt-4 md:text-base">
              Projection climatique {getZoneLabel(zoneData)}, d'après les projections de Météo-France.
            </p>

            {finalProjection ? (
              <div className="mt-5 border-l border-red-300/70 pl-4 md:mt-8 md:pl-5">
                <p className="flex items-center gap-2 text-[10px] font-semibold uppercase text-red-100/90">
                  <Flame className="h-4 w-4" />
                  Impact chaleur à horizon 2046
                </p>
                <p className="mt-2 font-satoshi text-[3rem] font-black leading-none text-white tabular-nums drop-shadow-[0_0_26px_rgba(255,255,255,0.14)] sm:text-6xl md:text-[4.4rem]">
                  +{finalProjection.dayDelta}
                  <span className="ml-2 text-xl text-red-200 md:text-2xl">jours</span>
                </p>
                <p className="mt-1 text-sm font-semibold text-white/78">
                  de forte chaleur par été vs 2026 · {finalProjection.days} jours &gt; 30°C
                </p>
              </div>
            ) : null}

            <p className="mt-6 max-w-lg text-[11px] leading-relaxed text-white/45 md:mt-8">
              Source : Météo-France — portail DRIAS, jeu de données Explore2 (scénario GIEC&nbsp;RCP&nbsp;8.5).
              Estimation locale par maille (~8&nbsp;km), fourchette haute des modèles (ENSmax), horizon 2046.
            </p>

          </div>

          <div className="relative hidden h-[82vh] overflow-hidden md:block">
            <ol
              className="relative z-10 transition-transform duration-700 ease-out"
              style={{ transform: 'translateY(calc(30vh - var(--timeline-shift)))' }}
            >
              {timeline.map((marker, index) => renderTimelineMarker(marker, index))}
            </ol>
          </div>

          <div className="relative md:hidden">
            <div className="flex flex-col gap-5">
              {timeline.map((marker) => {
                const copy = TIMELINE_COPY[marker.year];
                const projection = marker.projection;

                return (
                  <div key={marker.year} className="relative">
                    <article className="min-w-0 rounded-lg border border-white/12 bg-white/[0.07] p-3.5 shadow-[0_0_28px_rgba(230,62,48,0.10)]">
                      <div className="flex flex-wrap items-end gap-x-2 gap-y-1">
                        <span className="font-satoshi text-[2.45rem] font-black leading-none tabular-nums">
                          {marker.year}
                        </span>
                        <span className="pb-1 font-satoshi text-base font-black text-white/92">
                          {copy.chapter}
                        </span>
                      </div>

                      <div className="mt-3 grid grid-cols-3 border-y border-white/12 py-3">
                        <div className="pr-2">
                          <p className="font-satoshi text-[1.65rem] font-black leading-none text-white tabular-nums">
                            {projection.days}
                          </p>
                          <p className="mt-1 text-[9px] font-bold uppercase leading-tight text-red-100/76">
                            jours chauds
                          </p>
                        </div>
                        <div className="border-l border-white/12 px-2">
                          <p className="font-satoshi text-[1.65rem] font-black leading-none text-white tabular-nums">
                            {projection.dayDelta > 0 ? `+${projection.dayDelta}` : '0'}
                          </p>
                          <p className="mt-1 text-[9px] font-bold uppercase leading-tight text-white/62">
                            {projection.dayDelta > 0 ? 'vs 2026' : 'référence'}
                          </p>
                        </div>
                        <div className="border-l border-white/12 pl-2">
                          <p className="font-satoshi text-[1.65rem] font-black leading-none text-white tabular-nums">
                            {frDec(projection.temp)}°
                          </p>
                          <p className="mt-1 text-[9px] font-bold uppercase leading-tight text-teal-100/76">
                            temp. été
                          </p>
                        </div>
                      </div>

                      <p className="mt-3 text-[13px] leading-relaxed text-white/72">
                        {copy.sourceLine} {copy.situationText}
                      </p>
                      <p className="mt-2 text-[13px] font-semibold leading-relaxed text-white/90">
                        Impact équipes : {copy.teamImpact}
                      </p>
                    </article>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};

export default ClimateScrollBlock;
