"use client";

import Image from "next/image";
import { useRouter } from "next/navigation";
import type { ReactNode } from "react";
import { useCallback, useState } from "react";
import { localizePath } from "@/translations/config";
import { useI18n } from "@/translations/provider";
import { useQuestionAnswers } from "./question-answer-storage";
import QuestionProgressTracker, {
  useQuestionProgress,
} from "./question-progress-tracker";
import QuestionSnapList from "./question-snap-list";
import type { QuestionField } from "@/lib/schema-adapter";
import ErrorToast from "./error-toast";
import NoticeBox from "./notice-box";
import AnswerPaceSheet from "@/app/questions-list/[slug]/answer-pace-sheet";
import { FixToTheEnd } from "./fix-to-the-end";
import Button from "./button";
import { markFirstEntryCompleted } from "@/lib/first-entry-helper";
import DevTapInstrumentation from "./dev-tap-instrumentation";

type QuestionSectionFlowProps = {
  children: ReactNode;
  continueLabel: string;
  exitHref: string;
  onExit?: () => void;
  total: number;
  optionalQuestionIndexes: readonly number[];
  questions?: readonly QuestionField[];
};

function SectionFlowContent({
  children,
  continueLabel,
  exitHref,
  onExit,
  optionalQuestionIndexes,
  questions,
}: {
  children: ReactNode;
  continueLabel: string;
  exitHref: string;
  onExit?: () => void;
  optionalQuestionIndexes: readonly number[];
  questions?: readonly QuestionField[];
}) {
  const router = useRouter();
  const { dictionary: t, locale } = useI18n();
  const { flushAnswers, isUploadingMedia } = useQuestionAnswers();
  const { markQuestionPassed, isCompleted } = useQuestionProgress();
  const [activeQuestionIndex, setActiveQuestionIndex] = useState(0);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);

  const handleQuestionExit = useCallback(() => {
    void flushAnswers({ force: true });
  }, [flushAnswers]);

  const handleSubmit = useCallback(async () => {
    if (isSubmitting) {
      return;
    }
    setIsSubmitting(true);
    setErrorMessage(null);

    const MAX_RETRIES = 3;
    let success = false;
    let lastError: any = null;

    for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
      try {
        await flushAnswers({ force: true });
        success = true;
        break;
      } catch (err: any) {
        lastError = err;
        console.warn(
          `[CONTINUE] flushAnswers attempt ${attempt}/${MAX_RETRIES} failed:`,
          err,
        );
        // On 400 Bad Request / Validation error, do not retry silently
        const statusCode = err?.response?.status || err?.status;
        if (statusCode === 400) {
          break;
        }
        if (attempt < MAX_RETRIES) {
          // Silent delay between retries while maintaining loading spinner
          await new Promise((resolve) => setTimeout(resolve, 800));
        }
      }
    }

    if (success) {
      markFirstEntryCompleted();
      if (onExit) {
        onExit();
      } else {
        const target = localizePath(exitHref || "/questions-list", locale);
        router.replace(target);
      }
    } else {
      setIsSubmitting(false);
      const statusCode = lastError?.response?.status || lastError?.status;
      const data = lastError?.response?.data;

      let msg = "";

      // 1. Detailed field validation errors from backend
      if (data?.errors && typeof data.errors === "object") {
        const errorEntries = Object.entries(data.errors);
        if (errorEntries.length > 0) {
          const fieldNames: string[] = [];
          for (const [key] of errorEntries) {
            const matchingQuestion = questions?.find(
              (q) =>
                q.id === key ||
                q.id.endsWith(`.${key}`) ||
                key.endsWith(`.${q.id}`) ||
                q.id.split(".").pop() === key.split(".").pop(),
            );
            if (matchingQuestion?.title) {
              fieldNames.push(`«${matchingQuestion.title}»`);
            } else {
              fieldNames.push(`«${key}»`);
            }
          }

          if (fieldNames.length > 0) {
            const uniqueFieldNames = Array.from(new Set(fieldNames));
            const template =
              t["Please complete the required fields: {fields}"] ||
              "Please complete the required fields: {fields}";
            msg = template.replace("{fields}", uniqueFieldNames.join("، "));
          }
        }
      }

      // 2. Direct message / detail / error from backend
      if (!msg) {
        const directMessage = data?.detail || data?.message || data?.error;
        if (typeof directMessage === "string" && directMessage.trim()) {
          msg = directMessage;
        }
      }

      // 3. Fallback for 400 Bad Request
      if (!msg && statusCode === 400) {
        msg =
          t["Some required fields are missing or invalid. Please check your answers."] ||
          "Some required fields are missing or invalid. Please check your answers.";
      }

      // 4. Fallback for 401 Unauthorized
      if (!msg && statusCode === 401) {
        msg =
          t["Session expired. Please log in again."] ||
          "Session expired. Please log in again.";
      }

      // 5. Fallback for Network / Server Error
      if (!msg) {
        msg =
          t["Internet connection error. Answers could not be synced with server. Please check your connection and tap Continue again."] ||
          "Internet connection error. Answers could not be synced with server. Please check your connection and tap Continue again.";
      }

      setErrorMessage(msg);
    }
  }, [exitHref, onExit, flushAnswers, locale, router, isSubmitting, t, questions]);

  const markOptionalQuestionsPassed = useCallback(
    (currentIndex: number, nextIndex: number) => {
      [currentIndex, nextIndex].forEach((questionIndex) => {
        if (optionalQuestionIndexes.includes(questionIndex)) {
          markQuestionPassed(questionIndex);
        }
      });
    },
    [markQuestionPassed, optionalQuestionIndexes],
  );

  const activeQuestion = questions?.[activeQuestionIndex];
  const showNotice = activeQuestion?.showGuardianNotice;
  const isUnder27 = activeQuestion?.required ?? false;

  return (
    <>
      <AnswerPaceSheet
        activeQuestionIndex={activeQuestionIndex}
        title={t["Answer at Your Own Pace"]}
        description={
          t[
            "You can pause the survey anytime and resume later. Your progress is saved automatically."
          ]
        }
        continueLabel={continueLabel || t["Submit"]}
      />
      {showNotice && (
        <div className="w-full px-[17px] mb-6 shrink-0">
          <NoticeBox>
            {isUnder27
              ? t[
                  "To preserve your peace of mind, security, and dignity, the acquaintance process on our platform follows authentic and respectful family traditions. Having a trusted person (preferably a father or mother) as a representative, in addition to reflecting your noble family background, encourages the other party to step forward with full seriousness, respect, and confidence."
                ]
              : t[
                  "Our goal is to establish lasting bonds based on mutual trust. Although registering a representative is not mandatory for you, introducing a trusted person (such as a father, mother, or family elder) demonstrates your transparency and serious intent for marriage. Profiles that feature a trusted representative command significantly higher credibility and provide greater peace of mind to the other party's family."
                ]}
          </NoticeBox>
        </div>
      )}
      <QuestionSnapList
        alignTop={showNotice}
        firstQuestionHint={
          <Image
            src="/assets/images/Frame 1597880476.svg"
            alt=""
            aria-hidden="true"
            width={31}
            height={31}
          />
        }
        onQuestionExit={handleQuestionExit}
        onQuestionTransition={markOptionalQuestionsPassed}
        onActiveIndexChange={setActiveQuestionIndex}
      >
        {children}
      </QuestionSnapList>

      {process.env.NODE_ENV === "development" ? (
        <DevTapInstrumentation />
      ) : null}
      {errorMessage && (
        <ErrorToast
          message={errorMessage}
          onClose={() => setErrorMessage(null)}
          duration={5000}
          variant="error"
        />
      )}
      <FixToTheEnd>
        <Button
          disabled={!isCompleted || isSubmitting || isUploadingMedia}
          isLoading={isSubmitting || isUploadingMedia}
          onClick={handleSubmit}
        >
          {continueLabel || t["Submit"]}
        </Button>
      </FixToTheEnd>
    </>
  );
}

export function QuestionSectionFlow({
  children,
  continueLabel,
  exitHref,
  onExit,
  total,
  optionalQuestionIndexes,
  questions,
}: QuestionSectionFlowProps) {
  return (
    <QuestionProgressTracker total={total}>
      <SectionFlowContent
        continueLabel={continueLabel}
        exitHref={exitHref}
        onExit={onExit}
        optionalQuestionIndexes={optionalQuestionIndexes}
        questions={questions}
      >
        {children}
      </SectionFlowContent>
    </QuestionProgressTracker>
  );
}

export default QuestionSectionFlow;
