"use client";

import { useLayoutEffect, useRef, useState } from "react";
import type { QuestionField } from "@/data/question-data";
import { useQuestionAnswers } from "./question-answer-storage";
import QuestionTitle from "./question-title";

type QuestionSliderProps = {
  question: QuestionField;
  questionIndex: number;
  disabled?: boolean;
};

export function QuestionSlider({
  question,
  questionIndex,
  disabled,
}: QuestionSliderProps) {
  const [min, max] = question.extras.range;
  const initialValue = Math.round((min + max) / 2);
  const { getAnswerValue, setAnswerValue } = useQuestionAnswers();
  const storedValue = getAnswerValue(question, questionIndex);
  const value = typeof storedValue === "number" ? storedValue : initialValue;
  const progress = max === min ? 0 : ((value - min) / (max - min)) * 100;
  const sliderWrapperRef = useRef<HTMLDivElement>(null);
  const sliderRef = useRef<HTMLInputElement>(null);
  const thumbWidth = 18;
  const bubbleHalfWidth = 20;
  const [bubblePosition, setBubblePosition] = useState(bubbleHalfWidth);
  const steps = Array.from(
    { length: max - min + 1 },
    (_, index) => min + index,
  );

  useLayoutEffect(() => {
    const wrapper = sliderWrapperRef.current;
    const slider = sliderRef.current;

    if (!wrapper || !slider) {
      return;
    }

    const updateBubblePosition = () => {
      const wrapperRect = wrapper.getBoundingClientRect();
      const sliderRect = slider.getBoundingClientRect();
      const sliderLeft = sliderRect.left - wrapperRect.left;
      const thumbCenter =
        sliderLeft +
        thumbWidth / 2 +
        (progress / 100) * (sliderRect.width - thumbWidth);

      setBubblePosition(
        Math.min(
          Math.max(thumbCenter, bubbleHalfWidth),
          wrapperRect.width - bubbleHalfWidth,
        ),
      );
    };

    updateBubblePosition();

    const resizeObserver = new ResizeObserver(updateBubblePosition);
    resizeObserver.observe(wrapper);
    resizeObserver.observe(slider);

    return () => resizeObserver.disconnect();
  }, [progress]);

  return (
    <div
      className={[
        "flex w-full flex-col gap-6 transition-opacity duration-200",
        disabled ? "pointer-events-none opacity-30" : "",
      ].join(" ")}
    >
      <QuestionTitle question={question} />
      <div className="pt-9">
        <div ref={sliderWrapperRef} className="relative">
          <div
            className="-translate-x-1/2 absolute -top-6.5 z-10 flex items-center justify-center rounded-[7px] bg-[#F43F5E] px-2.5 group-12 font-semibold text-white shadow-sm after:absolute after:-bottom-[4px] after:left-1/2 after:h-[9px] after:w-2.5 after:-translate-x-1/2 after:rotate-45 after:rounded-[2px] after:bg-[#F43F5E] after:content-['']"
            style={{ left: `${bubblePosition}px` }}
          >
            {value}
          </div>
          <input
            ref={sliderRef}
            type="range"
            min={min}
            max={max}
            step={1}
            value={value}
            onChange={(event) =>
              setAnswerValue(
                question,
                questionIndex,
                Number(event.target.value),
              )
            }
            disabled={disabled}
            className="question-slider-range w-full"
            style={{
              background: `linear-gradient(to right, #F43F5E 0%, #F43F5E ${progress}%, #FAD1D8 ${progress}%, #FAD1D8 100%)`,
            }}
          />
        </div>
        <div className="mt-2 grid grid-flow-col auto-cols-fr text-center group-10 text-[#B7B7B7]">
          {steps.map((step) => (
            <span key={step}>{step}</span>
          ))}
        </div>
      </div>
    </div>
  );
}

export default QuestionSlider;
