"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { motion, useReducedMotion } from "framer-motion";

const STEPS = [
  { id: "solicitud", label: "Solicitud", desc: "Publicas lo que necesitas" },
  { id: "cotizacion", label: "Cotizacion", desc: "Recibes precios y plazos" },
  { id: "firma", label: "Firma", desc: "Acuerdas por escrito" },
  { id: "pago", label: "Pago confirmado", desc: "Cierras con confianza" },
] as const;

const HOLD_MS = 1400;

export function HoldConnect({
  title = "Asi conecta Servicios PR",
  description = "Describe el trabajo, recibe cotizaciones y cierras con confianza.",
}: {
  title?: string;
  description?: string;
}) {
  const reduce = useReducedMotion();
  const zoneRef = useRef<HTMLDivElement>(null);
  const holdingRef = useRef(false);
  const holdStartRef = useRef<number | null>(null);
  const rafRef = useRef<number | null>(null);
  const skipTapRef = useRef(false);

  const [mounted, setMounted] = useState(false);
  const [progress, setProgress] = useState(0);
  const [activeStep, setActiveStep] = useState(-1);
  const [done, setDone] = useState(false);
  const [inView, setInView] = useState(false);

  const prefersReducedMotion = mounted && !!reduce;

  const revealed = done ? STEPS.length : Math.max(0, activeStep + 1);

  const tick = useCallback(() => {
    if (!holdingRef.current || !holdStartRef.current) return;
    const p = Math.min(1, (performance.now() - holdStartRef.current) / HOLD_MS);
    setProgress(p);
    if (p >= 1) {
      holdingRef.current = false;
      holdStartRef.current = null;
      skipTapRef.current = true;
      setDone(true);
      setActiveStep(STEPS.length - 1);
      setProgress(1);
      return;
    }
    rafRef.current = requestAnimationFrame(tick);
  }, []);

  const stopHold = useCallback(() => {
    holdingRef.current = false;
    holdStartRef.current = null;
    if (rafRef.current !== null) {
      cancelAnimationFrame(rafRef.current);
      rafRef.current = null;
    }
    if (!done) setProgress(0);
  }, [done]);

  const startHold = useCallback(
    (e: React.PointerEvent) => {
      if (done || prefersReducedMotion) return;
      e.preventDefault();
      (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
      holdingRef.current = true;
      holdStartRef.current = performance.now();
      setProgress(0.02);
      rafRef.current = requestAnimationFrame(tick);
    },
    [done, prefersReducedMotion, tick]
  );

  const advanceClick = useCallback(() => {
    if (done) {
      setDone(false);
      setActiveStep(-1);
      setProgress(0);
      return;
    }
    setActiveStep((s) => {
      const next = s + 1;
      if (next >= STEPS.length - 1) {
        setDone(true);
        setProgress(1);
        return STEPS.length - 1;
      }
      setProgress((next + 1) / STEPS.length);
      return next;
    });
  }, [done]);

  const onPointerUp = useCallback(() => {
    const started = holdStartRef.current;
    const elapsed = started ? performance.now() - started : 0;

    stopHold();

    if (skipTapRef.current) {
      skipTapRef.current = false;
      return;
    }

    if (elapsed > 0 && elapsed < 320) {
      advanceClick();
    }
  }, [stopHold, advanceClick]);

  useEffect(() => {
    setMounted(true);
  }, []);

  useEffect(() => {
    const el = zoneRef.current;
    if (!el) return;
    const io = new IntersectionObserver(
      ([entry]) => setInView(entry?.isIntersecting ?? false),
      { threshold: 0.35 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);

  useEffect(() => {
    if (!mounted || !prefersReducedMotion || !inView) return;
    const t = window.setTimeout(() => {
      setDone(true);
      setActiveStep(STEPS.length - 1);
      setProgress(1);
    }, 400);
    return () => clearTimeout(t);
  }, [mounted, prefersReducedMotion, inView]);

  useEffect(() => {
    return () => {
      if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
    };
  }, []);

  const ringDeg = progress * 360;
  const hint = done
    ? "Clic para reiniciar"
    : prefersReducedMotion
      ? "Flujo completo"
      : "Clic para avanzar · o mantén presionado el circulo";

  return (
    <div
      ref={zoneRef}
      className={`hold-connect${done ? " hold-connect--done" : ""}${inView ? " hold-connect--in" : ""}`}
      role="group"
      aria-label={title}
    >
      <div className="hold-connect__top">
        <button
          type="button"
          className="hold-connect__ring-btn"
          aria-label={done ? "Reiniciar flujo" : "Mantén presionado para completar el flujo"}
          onPointerDown={startHold}
          onPointerUp={onPointerUp}
          onPointerCancel={onPointerUp}
          onPointerLeave={onPointerUp}
          style={{ ["--ring-deg" as string]: `${ringDeg}deg` }}
        >
          <svg className="hold-connect__ring-svg" viewBox="0 0 120 120" aria-hidden="true">
            <circle
              className="hold-connect__ring-track"
              cx="60"
              cy="60"
              r="52"
              fill="none"
              strokeWidth="4"
            />
            <circle
              className="hold-connect__ring-fill"
              cx="60"
              cy="60"
              r="52"
              fill="none"
              strokeWidth="4"
              strokeDasharray={`${2 * Math.PI * 52}`}
              strokeDashoffset={`${2 * Math.PI * 52 * (1 - progress)}`}
              transform="rotate(-90 60 60)"
            />
          </svg>
          <span className="hold-connect__ring-icon" aria-hidden="true">
            {revealed > 0 ? revealed : "→"}
          </span>
        </button>

        <div className="hold-connect__copy">
          <h3 className="hold-connect__title">{title}</h3>
          <p className="hold-connect__desc">{description}</p>
          <p className="hold-connect__hint">{hint}</p>
          <button
            type="button"
            className="btn-ghost hold-connect__action mt-3"
            onClick={(e) => {
              e.stopPropagation();
              advanceClick();
            }}
          >
            {done ? "Reiniciar flujo" : "Siguiente paso"}
          </button>
        </div>
      </div>

      <ol className="hold-connect__steps" aria-label="Pasos del flujo">
        {STEPS.map((step, i) => {
          const isOn = done || i <= activeStep;
          return (
            <motion.li
              key={step.id}
              className={`hold-connect__step${isOn ? " is-on" : ""}`}
              initial={false}
              animate={
                isOn
                  ? { opacity: 1, y: 0, scale: 1 }
                  : { opacity: 0.35, y: 8, scale: 0.96 }
              }
              transition={{ duration: 0.35, ease: [0.22, 1, 0.36, 1] }}
            >
              <span className="hold-connect__step-n">{i + 1}</span>
              <span className="hold-connect__step-label">{step.label}</span>
              <span className="hold-connect__step-desc">{step.desc}</span>
            </motion.li>
          );
        })}
      </ol>
    </div>
  );
}
