"use client";

import { useRouter } from "next/navigation";
import type { TouchEvent } from "react";
import { useEffect, useState } from "react";
import { useUpdateMarriageProfileBasicMutation } from "@/hooks/marriage/use-profile-basic";
import { localizePath } from "@/translations/config";
import { useI18n } from "@/translations/provider";
import Button from "./button";
import NavigationButton from "./navigation-button";
import type { GenderAnswer, RegistrationAnswer } from "./slider-slide";
import { SliderSlideFive } from "./slider-slide-five";
import { SliderSlideFour } from "./slider-slide-four";
import { SliderSlideOne, SliderSlideOneActions } from "./slider-slide-one";
import { SliderSlideThree } from "./slider-slide-three";
import { SliderSlideTwo } from "./slider-slide-two";

const FINAL_SLIDE_COUNT = 5;
const SWIPE_THRESHOLD = 40;
const SLIDER_ANSWERS_STORAGE_KEY = "marriage-slider-answers";

export default function SliderPage() {
  const router = useRouter();
  const { locale } = useI18n();
  const [activeSlide, setActiveSlide] = useState(0);
  const [selectedGender, setSelectedGender] = useState<GenderAnswer>("woman");
  const [selectedRegistration, setSelectedRegistration] =
    useState<RegistrationAnswer>("self");
  const [hasReadRules, setHasReadRules] = useState(false);
  const [touchStartX, setTouchStartX] = useState<number | null>(null);
  const updateProfileBasicMutation = useUpdateMarriageProfileBasicMutation();
  const hasFinalNotice = true;
  const maxSlideIndex = FINAL_SLIDE_COUNT - 1;
  const displaySlideCount = FINAL_SLIDE_COUNT;
  const navDotCount = displaySlideCount;

  useEffect(() => {
    // Clear any previous slider answers on mount so abandoned onboarding starts clean
    if (typeof window !== "undefined") {
      window.localStorage.removeItem(SLIDER_ANSWERS_STORAGE_KEY);
    }
  }, []);

  const goToSlide = (index: number) => {
    setActiveSlide(Math.max(0, Math.min(index, maxSlideIndex)));
  };

  const goToPreviousSlide = () => {
    goToSlide(activeSlide - 1);
  };

  const goToNextSlide = () => {
    goToSlide(activeSlide + 1);
  };

  const completeSlider = async () => {
    const navigateAway = () => {
      if (typeof window !== "undefined") {
        window.localStorage.removeItem(SLIDER_ANSWERS_STORAGE_KEY);
        // Use hard navigation instead of router.push() to ensure the
        // destination page loads with a fresh auth state.  SPA (soft)
        // navigation sometimes leaves stale query-cache / token state
        // that causes the profile query to return 401 and the page to
        // stay stuck on the loading spinner.
        window.location.href = localizePath(
          "/questions-list/personal_info",
          locale,
        );
        return;
      }
      router.push(localizePath("/questions-list/personal_info", locale));
    };

    // Safety timeout — navigate after 5 seconds even if the request hangs
    const timeout = setTimeout(navigateAway, 5000);

    try {
      await updateProfileBasicMutation.mutateAsync({
        gender: selectedGender === "man" ? "male" : "female",
        is_registering_for_self: selectedRegistration === "self",
      });
    } catch (error) {
      console.warn("Failed to update profile basic details:", error);
    } finally {
      clearTimeout(timeout);
      navigateAway();
    }
  };

  const handleTouchStart = (event: TouchEvent<HTMLDivElement>) => {
    setTouchStartX(event.touches[0]?.clientX ?? null);
  };

  const handleTouchEnd = (event: TouchEvent<HTMLDivElement>) => {
    if (touchStartX === null) {
      return;
    }

    const touchEndX = event.changedTouches[0]?.clientX ?? touchStartX;
    const deltaX = touchStartX - touchEndX;

    if (Math.abs(deltaX) >= SWIPE_THRESHOLD) {
      if (deltaX > 0) {
        goToNextSlide();
      } else {
        goToPreviousSlide();
      }
    }

    setTouchStartX(null);
  };

  return (
    <div className="relative flex h-[100dvh] max-h-[100dvh] flex-col overflow-hidden">
      <header className="relative -mx-[17px] rounded-b-[32px] px-[17px] pt-[max(16px,calc(var(--safe-top)+8px))] pb-3.5">
        <div className="relative flex items-center justify-between">
          <NavigationButton
            icon="back"
            iconLabel="Close slider"
            onClick={() => router.back()}
          />
          <nav
            aria-label={`Slide ${activeSlide + 1} of ${displaySlideCount}`}
            className="absolute left-1/2 flex -translate-x-1/2 items-center gap-2"
          >
            {Array.from({ length: navDotCount }, (_, index) => {
              const isActive = index === activeSlide;

              return (
                <button
                  key={`slide-${index + 1}`}
                  type="button"
                  aria-label={`Go to slide ${index + 1}`}
                  aria-pressed={isActive}
                  className={[
                    "h-2.5 rounded-full border-1 border-[#F14B46] transition-all duration-300 ease-out",
                    isActive ? "w-6 bg-[#F14B46]" : "w-2.5 bg-white/80",
                  ].join(" ")}
                  onClick={() => goToSlide(index)}
                />
              );
            })}
          </nav>
        </div>
      </header>

      <main
        className="flex min-h-0 flex-1 touch-pan-y overflow-hidden pt-6"
        onTouchEnd={handleTouchEnd}
        onTouchStart={handleTouchStart}
      >
        <div
          className="flex h-full w-full transition-transform duration-300 ease-out"
          style={{ transform: `translateX(-${activeSlide * 100}%)` }}
        >
          <SliderSlideOne
            index={0}
            onScrollToEnd={() => setHasReadRules(true)}
          />
          <SliderSlideTwo index={1} />
          <SliderSlideThree
            index={2}
            selectedGender={selectedGender}
            onGenderChange={setSelectedGender}
          />
          <SliderSlideFour
            index={3}
            selectedRegistration={selectedRegistration}
            onRegistrationChange={setSelectedRegistration}
          />
          {hasFinalNotice ? <SliderSlideFive index={4} /> : null}
        </div>
      </main>

      <div className="pointer-events-none fixed bottom-0 left-1/2 z-20 w-full sm:max-w-[375px] -translate-x-1/2 bg-[#F5F5F5]">
        <div
          style={{ paddingBottom: `calc(1rem + var(--safe-bottom))` }}
          className="mx-auto w-full sm:max-w-[375px] px-[17px] pt-4"
        >
          <div className="pointer-events-auto">
            {activeSlide === 0 ? (
              <SliderSlideOneActions
                onAccept={goToNextSlide}
                disabled={!hasReadRules}
              />
            ) : activeSlide === maxSlideIndex ? (
              <SliderFinalActions
                onBack={goToPreviousSlide}
                isFinishing={updateProfileBasicMutation.isPending}
                onFinish={completeSlider}
              />
            ) : (
              <SliderStepActions
                onBack={goToPreviousSlide}
                onNext={goToNextSlide}
              />
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

type SliderStepActionsProps = {
  onBack: () => void;
  onNext: () => void;
};

function SliderStepActions({ onBack, onNext }: SliderStepActionsProps) {
  return (
    <div className="flex items-center gap-3 [&>button]:flex-1">
      <Button variant="outlined" arrowDirection="left" onClick={onBack}>
        Back
      </Button>
      <Button arrowDirection="right" onClick={onNext}>
        Next
      </Button>
    </div>
  );
}

type SliderFinalActionsProps = {
  isFinishing?: boolean;
  onBack: () => void;
  onFinish: () => void | Promise<void>;
};

function SliderFinalActions({
  isFinishing = false,
  onBack,
  onFinish,
}: SliderFinalActionsProps) {
  return (
    <div className="flex items-center gap-3 [&>button]:flex-1">
      <Button
        variant="outlined"
        arrowDirection="left"
        disabled={isFinishing}
        onClick={onBack}
      >
        Back
      </Button>
      <Button disabled={isFinishing} isLoading={isFinishing} onClick={onFinish}>
        Finish
      </Button>
    </div>
  );
}
