// ============================================================
// Cacyli — Villa showcase
// Desktop: scroll-driven card deck
// Mobile : Tinder-style swipe cards
// ============================================================

// ---- Mobile swipe component -------------------------------------------- //

const VillaSwipeMobile = () => {
  const villas = window.VILLAS;
  const [idx, setIdx] = React.useState(0);
  const [drag, setDrag] = React.useState({ x: 0, y: 0 });
  const [exitDir, setExitDir] = React.useState(null);
  const startRef = React.useRef(null);
  const activeRef = React.useRef(false);
  const THRESHOLD = 75;

  const v = villas[idx];
  const vNext = villas[(idx + 1) % villas.length];

  const advance = (dir) => {
    activeRef.current = false;
    setDrag({ x: 0, y: 0 });
    setExitDir(dir);
    setTimeout(() => {
      setIdx(i => (i + 1) % villas.length);
      setExitDir(null);
    }, 380);
  };

  const onTouchStart = (e) => {
    if (exitDir) return;
    activeRef.current = true;
    const t = e.touches[0];
    startRef.current = { x: t.clientX, y: t.clientY };
  };

  const onTouchMove = (e) => {
    if (!activeRef.current || !startRef.current) return;
    const t = e.touches[0];
    setDrag({
      x: t.clientX - startRef.current.x,
      y: t.clientY - startRef.current.y,
    });
  };

  const onTouchEnd = () => {
    if (!activeRef.current) return;
    activeRef.current = false;
    const { x, y } = drag;
    if (Math.abs(x) >= THRESHOLD) {
      advance(x > 0 ? 'right' : 'left');
    } else if (y >= THRESHOLD) {
      advance('down');
    } else {
      setDrag({ x: 0, y: 0 });
      startRef.current = null;
    }
  };

  const topStyle = () => {
    if (exitDir === 'right') return { transform: 'translate3d(160vw,-10%,0) rotate(30deg)', transition: 'transform 0.38s cubic-bezier(0.25,1,0.5,1)' };
    if (exitDir === 'left')  return { transform: 'translate3d(-160vw,-10%,0) rotate(-30deg)', transition: 'transform 0.38s cubic-bezier(0.25,1,0.5,1)' };
    if (exitDir === 'down')  return { transform: 'translate3d(0,135%,0) rotate(8deg)', transition: 'transform 0.38s cubic-bezier(0.25,1,0.5,1)' };
    if (drag.x !== 0 || drag.y !== 0) {
      const rot = (drag.x / window.innerWidth) * 18;
      return { transform: `translate3d(${drag.x}px,${drag.y}px,0) rotate(${rot}deg)`, transition: 'none' };
    }
    return { transform: 'translate3d(0,0,0)', transition: 'transform 0.3s cubic-bezier(0.25,1,0.5,1)' };
  };

  const dragMag = Math.max(Math.abs(drag.x), Math.abs(drag.y));
  const progress = Math.min(1, dragMag / THRESHOLD);
  const underScale = (0.93 + 0.07 * progress).toFixed(3);
  const underTY = (4 - 4 * progress).toFixed(1);
  const tilt = drag.x > 40 ? 'right' : drag.x < -40 ? 'left' : null;
  const isDragging = drag.x !== 0 || drag.y !== 0;

  return (
    <section className="villa-swipe" id="villas" aria-labelledby="villas-swipe-title">
      <h2 id="villas-swipe-title" className="sr-only">Nos villas</h2>

      <div className="swipe-header">
        <span className="eyebrow" style={{ fontSize: '0.7rem' }}>Nos villas</span>
        <span className="swipe-counter">
          {String(idx + 1).padStart(2, '0')} / {String(villas.length).padStart(2, '0')}
        </span>
      </div>

      <div className="swipe-stage">
        {/* Card underneath */}
        <div
          className="swipe-card swipe-card-under"
          style={{
            backgroundImage: `url(${vNext.img})`,
            transform: `scale(${underScale}) translateY(${underTY}%)`,
            transition: isDragging ? 'none' : 'transform 0.38s cubic-bezier(0.25,1,0.5,1)',
          }}
          aria-hidden="true"
        />

        {/* Top card */}
        <div
          className="swipe-card swipe-card-top"
          style={{ backgroundImage: `url(${v.img})`, ...topStyle() }}
          onTouchStart={onTouchStart}
          onTouchMove={onTouchMove}
          onTouchEnd={onTouchEnd}
          onTouchCancel={onTouchEnd}
        >
          {tilt === 'right' && <span className="swipe-badge swipe-badge-like">❤</span>}
          {tilt === 'left'  && <span className="swipe-badge swipe-badge-nope">✕</span>}

          <div className="swipe-info">
            <span className="swipe-tag">{v.tag}</span>
            <h3 className="swipe-name">{v.name}</h3>
            <p className="swipe-loc"><Icon name="pin" size={13} /> {v.location}</p>
            <p className="swipe-desc">{v.desc}</p>
            <div className="swipe-chips">
              {v.specs.slice(0, 3).map((s, k) => (
                <span key={k} className="swipe-chip">
                  <Icon name={s.icon} size={13} /> {s.val}
                </span>
              ))}
            </div>
            <a
              href={v.airbnb}
              className="btn btn-primary swipe-cta"
              target="_blank"
              rel="noopener noreferrer"
              onClick={e => e.stopPropagation()}
            >
              <Icon name="link" size={15} /> Voir sur Airbnb
            </a>
          </div>
        </div>
      </div>

      <div className="swipe-dots" aria-hidden="true">
        {villas.map((_, i) => (
          <span key={i} className={`swipe-dot${i === idx ? ' is-active' : ''}`} />
        ))}
      </div>

      {idx === 0 && !isDragging && !exitDir && (
        <p className="swipe-hint" aria-hidden="true">
          <Icon name="arrow-right" size={13} /> Glisser pour explorer
        </p>
      )}
    </section>
  );
};

// ---- Desktop scroll-driven deck ---------------------------------------- //

const VillaShowcaseDesktop = () => {
  const sectionRef = React.useRef(null);
  const photoRefs = React.useRef([]);
  const [activeIdx, setActiveIdx] = React.useState(0);
  const [pagerVisible, setPagerVisible] = React.useState(false);
  const villas = window.VILLAS;

  const SCROLL_PER_VILLA = 1;

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

    const onScroll = () => {
      const sec = sectionRef.current;
      if (!sec) return;
      const rect = sec.getBoundingClientRect();
      const vh = window.innerHeight;
      const perStep = vh * SCROLL_PER_VILLA;
      const total = villas.length * perStep;

      const scrolled = Math.min(Math.max(-rect.top, 0), total);
      const progress = scrolled / perStep;
      const idx = Math.min(villas.length - 1, Math.floor(progress + 0.5));
      setActiveIdx(idx);

      const visible = rect.top <= 80 && rect.bottom > vh * 0.5;
      setPagerVisible(visible);

      photoRefs.current.forEach((el, i) => {
        if (!el) return;
        const localP = progress - i;
        let transform, opacity = 1, zIndex;

        if (reduced) {
          el.style.transform = 'translate3d(0,0,0)';
          el.style.opacity = i === idx ? '1' : '0';
          el.style.zIndex = String(villas.length - Math.abs(i - idx));
          return;
        }

        if (localP >= 1) {
          transform = `translate3d(-130%, -8%, 0) rotate(-22deg)`;
          opacity = 0;
          zIndex = 0;
        } else if (localP >= 0) {
          const e = localP;
          const ease = e < 0.5 ? 2 * e * e : 1 - Math.pow(-2 * e + 2, 2) / 2;
          const tx = -ease * 130;
          const ty = -ease * 8;
          const rot = -ease * 22;
          const scale = 1 - ease * 0.05;
          opacity = 1 - Math.max(0, (e - 0.6) / 0.4);
          transform = `translate3d(${tx}%, ${ty}%, 0) rotate(${rot}deg) scale(${scale})`;
          zIndex = villas.length + 10;
        } else {
          const depth = -localP;
          if (depth > 3) {
            transform = `translate3d(0, 14%, 0) scale(0.82)`;
            opacity = 0;
            zIndex = 0;
          } else {
            const ty = depth * 4.2;
            const scale = 1 - depth * 0.05;
            const rot = depth * 1.2;
            const tx = depth * 2.2;
            opacity = depth > 2.5 ? Math.max(0, 1 - (depth - 2.5) / 0.5) : 1;
            transform = `translate3d(${tx}%, ${ty}%, 0) rotate(${rot}deg) scale(${scale})`;
            zIndex = villas.length - Math.ceil(depth);
          }
        }

        el.style.transform = transform;
        el.style.opacity = String(opacity);
        el.style.zIndex = String(zIndex);
      });
    };

    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
    };
  }, [villas.length]);

  const goTo = (i) => {
    const sec = sectionRef.current;
    if (!sec) return;
    const top = sec.offsetTop + i * window.innerHeight * SCROLL_PER_VILLA;
    window.scrollTo({ top, behavior: 'smooth' });
  };

  const totalHeight = `${villas.length * 100 * SCROLL_PER_VILLA + 50}vh`;
  const v = villas[activeIdx];

  return (
    <section
      className="villas villas-deck"
      id="villas"
      ref={sectionRef}
      aria-labelledby="villas-title"
      style={{ height: totalHeight, padding: 0 }}
    >
      <h2 id="villas-title" className="sr-only">Nos villas</h2>

      <div className="villa-frame">
        <div className="villas-heading">
          <span className="eyebrow eyebrow-pill">
            Nos villas — {String(activeIdx + 1).padStart(2, '0')} / {String(villas.length).padStart(2, '0')}
          </span>
        </div>

        <div className="vd-layout">
          {/* LEFT — Photo deck (animated) */}
          <div className="vd-photo-stage" aria-hidden="true">
            {villas.map((vv, i) => (
              <div
                key={vv.id}
                ref={(el) => (photoRefs.current[i] = el)}
                className="vd-photo"
                style={{ backgroundImage: `url(${vv.img})`, backgroundSize: 'cover', backgroundPosition: 'center' }}
                data-label={vv.name}
              >
                <span className="villa-img-tag">{vv.tag}</span>
                <span className="villa-img-counter">
                  {String(i + 1).padStart(2, '0')} / {String(villas.length).padStart(2, '0')}
                </span>
              </div>
            ))}
          </div>

          {/* RIGHT — Info panel */}
          <div className="vd-info-stage" aria-live="polite">
            <article key={v.id} className="vd-info vd-info-fade">
              <span className="eyebrow">Bien {String(activeIdx + 1).padStart(2, '0')}</span>
              <h3>{v.name}</h3>
              <p className="location">
                <Icon name="pin" size={16} /> {v.location}
              </p>
              <p className="desc">{v.desc}</p>

              <div className="villa-specs">
                {v.specs.map((s, k) => (
                  <div key={k} className="villa-spec">
                    <span className="villa-spec-icon"><Icon name={s.icon} size={18} /></span>
                    <span className="villa-spec-text">
                      <span className="lab">{s.lab}</span>
                      <span className="val">{s.val}</span>
                    </span>
                  </div>
                ))}
              </div>

              {v.price !== '—' && (
                <div className="villa-finance glass-deep">
                  <div className="villa-finance-cell">
                    <span className="lab">Valeur du bien</span>
                    <span className="val">{v.price}</span>
                  </div>
                  <div className="villa-finance-cell accent">
                    <span className="lab">Rendement brut</span>
                    <span className="val">{v.yield}</span>
                  </div>
                  <div className="villa-finance-cell">
                    <span className="lab">Revenus / an</span>
                    <span className="val">{v.revenue}</span>
                  </div>
                </div>
              )}

              <div className="villa-actions">
                <a
                  href={v.airbnb}
                  className="btn btn-primary"
                  target="_blank"
                  rel="noopener noreferrer"
                  style={{ padding: '14px 24px', fontSize: '0.95rem' }}
                  aria-label={`Voir ${v.name} sur Airbnb (s'ouvre dans un nouvel onglet)`}
                >
                  <Icon name="link" size={16} />
                  Voir sur Airbnb
                </a>
              </div>
            </article>
          </div>
        </div>

        {activeIdx === 0 && (
          <div className="deck-hint" aria-hidden="true">
            <span>Scroller pour défiler les cartes</span>
            <Icon name="arrow-down" size={16} />
          </div>
        )}
      </div>

      <nav
        className={`villa-pager ${pagerVisible ? 'is-visible' : ''}`}
        aria-label="Navigation entre les villas"
      >
        {villas.map((vv, i) => (
          <button
            key={vv.id}
            type="button"
            className={i === activeIdx ? 'is-active' : ''}
            onClick={() => goTo(i)}
            aria-label={`Aller à la villa ${vv.name}`}
            aria-current={i === activeIdx ? 'true' : undefined}
          >
            <span className="label">{vv.name}</span>
          </button>
        ))}
      </nav>
    </section>
  );
};

// ---- Wrapper ------------------------------------------------------------ //

const VillaShowcase = () => {
  const [isMobile, setIsMobile] = React.useState(window.innerWidth < 768);

  React.useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < 768);
    window.addEventListener('resize', check);
    return () => window.removeEventListener('resize', check);
  }, []);

  return isMobile ? <VillaSwipeMobile /> : <VillaShowcaseDesktop />;
};

window.VillaShowcase = VillaShowcase;
