import { useEffect, useMemo, useState } from "react";
import {
  Link,
  useNavigate,
  useParams,
  useSearchParams,
} from "react-router-dom";
import { ArrowLeft } from "lucide-react";
import { toast } from "sonner";
import { Button } from "../../components/ui/button";
import { Stepper } from "../../components/ui/stepper";
import successIcon from "../../assets/success.svg";
import type { PracticeParentKind } from "../../types/course.types";
import type { QuestionTypeDefinition } from "../../types/questionTypeDefinition.types";
import { getQuestionTypeDefinitions } from "../../api/questionTypeDefinitions.api";
import { emptyDynamicFieldValuesForDefinition } from "../../lib/learnEnglishDefinitionQuestion";
import {
  executeLearnEnglishPracticeCreation,
  learnEnglishPracticeApiErrorMessage,
  validateLearnEnglishQuestionsWithDefinitions,
} from "../../lib/learnEnglishPracticePublish";

import { ContextStep } from "./components/practice-steps/ContextStep";
import { ScenarioStep } from "./components/practice-steps/ScenarioStep";
import { PersonaStep } from "./components/practice-steps/PersonaStep";
import { QuestionsStep } from "./components/practice-steps/QuestionsStep";
import { ReviewStep } from "./components/practice-steps/ReviewStep";
import {
  personaFromId,
  personaIdNumber,
} from "./components/practice-steps/constants";
import { useActivePersonas } from "../../hooks/useActivePersonas";

const STEP_LABELS = ["Practice", "Persona", "Questions", "Review"] as const;

export function AddPracticeFlow() {
  const navigate = useNavigate();
  const {
    level,
    programType,
    courseId: routeCourseId,
    unitId: routeUnitId,
    moduleId: routeModuleId,
  } = useParams<{
    level?: string;
    programType?: string;
    courseId?: string;
    unitId?: string;
    moduleId?: string;
  }>();
  const [searchParams] = useSearchParams();
  const backToParam = searchParams.get("backTo");
  const lessonId = searchParams.get("lessonId");
  const lessonTitleRaw = searchParams.get("lessonTitle");

  const isExamPrep = Boolean(programType?.trim());

  const effectiveBackTo = useMemo(() => {
    if (backToParam?.trim()) return backToParam.trim();
    if (isExamPrep && routeModuleId) return "module";
    if (isExamPrep && routeCourseId) return "courses";
    return null;
  }, [backToParam, isExamPrep, routeModuleId, routeCourseId]);

  const courseId = isExamPrep
    ? routeCourseId ?? searchParams.get("courseId")
    : searchParams.get("courseId");
  const moduleId = isExamPrep
    ? routeModuleId ?? searchParams.get("moduleId")
    : searchParams.get("moduleId");
  const unitId = isExamPrep ? routeUnitId : null;

  const lessonTitleDisplay = (() => {
    const raw = lessonTitleRaw?.trim();
    if (!raw) return null;
    try {
      return decodeURIComponent(raw);
    } catch {
      return raw;
    }
  })();

  const isModuleContext = effectiveBackTo === "module";
  const isCourseContext =
    effectiveBackTo === "modules" || effectiveBackTo === "courses";
  const isLessonPractice = useMemo(() => {
    const lid = lessonId ? Number(lessonId) : NaN;
    return Number.isFinite(lid) && lid > 0;
  }, [lessonId]);
  /** Learn English lesson practices skip story fields; exam prep lessons use the full form. */
  const isLearnEnglishLessonPractice = isLessonPractice && !isExamPrep;

  const parentContext = useMemo((): {
    kind: PracticeParentKind;
    id: number;
  } | null => {
    const lid = lessonId ? Number(lessonId) : NaN;
    if (Number.isFinite(lid) && lid > 0) return { kind: "LESSON", id: lid };
    const mid = moduleId ? Number(moduleId) : NaN;
    if (isModuleContext && Number.isFinite(mid) && mid > 0)
      return { kind: "MODULE", id: mid };
    const cid = courseId ? Number(courseId) : NaN;
    if (isCourseContext && Number.isFinite(cid) && cid > 0)
      return { kind: "COURSE", id: cid };
    return null;
  }, [lessonId, moduleId, courseId, isModuleContext, isCourseContext]);

  const parentSummary = useMemo(() => {
    if (lessonId)
      return `Lesson #${lessonId}${lessonTitleDisplay ? ` — ${lessonTitleDisplay}` : ""}`;
    if (isModuleContext && moduleId) return `Module #${moduleId}`;
    if (isCourseContext && courseId) return `Course #${courseId}`;
    return null;
  }, [
    lessonId,
    lessonTitleDisplay,
    isModuleContext,
    isCourseContext,
    moduleId,
    courseId,
  ]);

  const programLabel = isExamPrep
    ? programType === "skill"
      ? "Skill-Based Courses"
      : "English Proficiency Exams"
    : level
      ? `Program ${level}`
      : null;

  const backLabel =
    effectiveBackTo === "module"
      ? "Back to Module"
      : effectiveBackTo === "modules"
        ? "Back to Modules"
        : effectiveBackTo === "courses"
          ? "Back to Course"
          : isExamPrep
            ? "Back to Program"
            : "Back to Courses";

  const backPath = useMemo(() => {
    if (isExamPrep) {
      if (
        effectiveBackTo === "module" &&
        programType &&
        courseId &&
        unitId &&
        moduleId
      ) {
        return `/new-content/courses/${programType}/${courseId}/${unitId}/${moduleId}`;
      }
      if (effectiveBackTo === "courses" && programType && courseId) {
        return `/new-content/courses/${programType}/${courseId}`;
      }
      if (programType) {
        return `/new-content/courses/${programType}`;
      }
      return "/new-content";
    }
    if (effectiveBackTo === "module" && level && courseId && moduleId) {
      return `/new-content/learn-english/${level}/courses/${courseId}/modules/${moduleId}`;
    }
    if (effectiveBackTo === "modules" && level && courseId) {
      return `/new-content/learn-english/${level}/courses/${courseId}`;
    }
    return `/new-content/learn-english/${level}/courses`;
  }, [
    isExamPrep,
    effectiveBackTo,
    programType,
    courseId,
    unitId,
    moduleId,
    level,
  ]);

  const [currentStep, setCurrentStep] = useState(1);
  const [isPublished, setIsPublished] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  const [selectedPersona, setSelectedPersona] = useState<string | null>(null);
  const {
    personas,
    loading: personasLoading,
    error: personasError,
    reload: reloadPersonas,
  } = useActivePersonas();

  const [formData, setFormData] = useState({
    title: "",
    description: "",
    storyImageUrl: "",
    shuffleQuestions: false,
    tips: "",
    questions: [
      {
        id: "q1",
        questionTypeDefinitionId: null as number | null,
        text: "",
        dynamicFieldValues: {} as Record<string, string>,
        mcqOptions: [
          { text: "", isCorrect: true },
          { text: "", isCorrect: false },
          { text: "", isCorrect: false },
          { text: "", isCorrect: false },
        ],
        trueFalseCorrect: true,
        shortAnswers: [""],
      },
    ],
  });

  const [typeDefinitions, setTypeDefinitions] = useState<QuestionTypeDefinition[]>(
    [],
  );
  const [definitionsLoading, setDefinitionsLoading] = useState(true);
  const [definitionsError, setDefinitionsError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      setDefinitionsLoading(true);
      setDefinitionsError(null);
      try {
        const { definitions: list } = await getQuestionTypeDefinitions({
          include_system: true,
          status: "ACTIVE",
        });
        if (!cancelled) setTypeDefinitions(list);
      } catch (e) {
        if (!cancelled) {
          setDefinitionsError(learnEnglishPracticeApiErrorMessage(e));
          setTypeDefinitions([]);
        }
      } finally {
        if (!cancelled) setDefinitionsLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (typeDefinitions.length === 0) return;
    setFormData((fd) => ({
      ...fd,
      questions: fd.questions.map((q) => {
        if (q.questionTypeDefinitionId != null) return q;
        const def = typeDefinitions[0];
        return {
          ...q,
          questionTypeDefinitionId: def.id,
          dynamicFieldValues: emptyDynamicFieldValuesForDefinition(def),
        };
      }),
    }));
  }, [typeDefinitions]);

  const submitPractice = async (status: "DRAFT" | "PUBLISHED") => {
    if (!parentContext) {
      toast.error("Missing practice parent", {
        description:
          "Open this screen from a course, module, or lesson so the API receives parent_kind and parent_id.",
      });
      return;
    }
    if (
      !isLearnEnglishLessonPractice &&
      (!formData.title.trim() || !formData.description.trim())
    ) {
      toast.error("Title and story description are required", {
        description: "Complete the first step before publishing.",
      });
      return;
    }
    if (!selectedPersona) {
      toast.error("Select a persona", {
        description: "Choose a character on the Persona step before publishing.",
      });
      return;
    }
    const personaId = personaIdNumber(selectedPersona);
    if (!personaId) {
      toast.error("Invalid persona", {
        description: "Re-select a persona from the list and try again.",
      });
      return;
    }
    const persona = personaFromId(selectedPersona, personas);
    const mappedQuestions = formData.questions.map((q) => ({
        questionText: String(q.text ?? "").trim(),
        questionTypeDefinitionId: Number(q.questionTypeDefinitionId),
        dynamicFieldValues: { ...(q.dynamicFieldValues ?? {}) },
        mcqOptions: (q.mcqOptions ?? []).map(
          (o: { text?: string; isCorrect?: boolean }) => ({
            option_text: String(o.text ?? ""),
            is_correct: Boolean(o.isCorrect),
          }),
        ),
        trueFalseAnswerIsTrue: q.trueFalseCorrect !== false,
        shortAnswers: (q.shortAnswers ?? []).map((s: string) => String(s)),
      }));

    const validationMsg = validateLearnEnglishQuestionsWithDefinitions(
      mappedQuestions,
      typeDefinitions,
    );
    if (validationMsg) {
      toast.error("Check your questions", { description: validationMsg });
      return;
    }

    const lessonDefaultTitle =
      lessonTitleDisplay?.trim() ||
      (lessonId ? `Lesson ${lessonId} practice` : "Lesson practice");

    const useExamPrepLessonApi =
      isExamPrep &&
      isLessonPractice &&
      parentContext.kind === "LESSON" &&
      Number.isFinite(parentContext.id);

    setSubmitting(true);
    try {
      await executeLearnEnglishPracticeCreation({
        parentKind: parentContext.kind,
        parentId: parentContext.id,
        examPrepLessonId: useExamPrepLessonApi ? parentContext.id : undefined,
        status,
        questionSetTitle: isLearnEnglishLessonPractice
          ? lessonDefaultTitle
          : formData.title.trim() || "Practice set",
        questionSetDescription: isLearnEnglishLessonPractice
          ? null
          : formData.description.trim() || null,
        shuffleQuestions: formData.shuffleQuestions,
        practiceTitle: isLearnEnglishLessonPractice
          ? lessonDefaultTitle
          : formData.title.trim() || "Untitled practice",
        storyDescription: isLearnEnglishLessonPractice
          ? ""
          : formData.description.trim(),
        storyImage: isLearnEnglishLessonPractice
          ? ""
          : formData.storyImageUrl.trim(),
        quickTips: formData.tips.trim(),
        personaName: persona?.name ?? null,
        personaId,
        questions: mappedQuestions,
        definitions: typeDefinitions,
      });
      toast.success(
        status === "PUBLISHED" ? "Practice published" : "Draft saved",
        {
          description:
            "Question set, questions, and parent-linked practice were created.",
        },
      );
      setIsPublished(true);
    } catch (e) {
      toast.error("Could not save practice", {
        description: learnEnglishPracticeApiErrorMessage(e),
      });
    } finally {
      setSubmitting(false);
    }
  };

  const nextStep = () =>
    setCurrentStep((prev) => Math.min(prev + 1, STEP_LABELS.length));
  const prevStep = () => setCurrentStep((prev) => Math.max(prev - 1, 1));

  if (isPublished) {
    return (
      <div className="flex flex-col items-center justify-center min-h-screen px-4 text-center pb-20 animate-in fade-in zoom-in duration-500">
        <div className="mb-10 relative">
          <div className="absolute inset-0 bg-brand-500/10 blur-3xl rounded-full" />
          <img
            src={successIcon}
            alt="Success"
            className="h-[128px] w-[128px] relative"
          />
        </div>
        <h1 className="text-[28px] font-bold text-grayScale-900 mb-2">
          Practice Published Successfully!
        </h1>
        <p className="text-grayScale-600 text-md mb-14 max-w-lg font-medium leading-relaxed">
          {lessonId
            ? "Your speaking practice is saved and linked to this lesson’s question set."
            : "Your speaking practice is saved for the linked course or module."}
        </p>
        <div className="flex flex-col gap-4 w-full max-w-[400px]">
          <Button
            onClick={() => navigate(backPath)}
            className="h-14 rounded-[6px] bg-[#9E2891] font-bold shadow-xl shadow-brand-500/20 text-[16px] text-white "
          >
            {backLabel}
          </Button>
          <Button
            onClick={() => {
              setIsPublished(false);
              setCurrentStep(1);
              setSelectedPersona(null);
              setFormData({
                title: "",
                description: "",
                storyImageUrl: "",
                shuffleQuestions: false,
                tips: "",
                questions: [
                  {
                    id: "q1",
                    questionTypeDefinitionId:
                      typeDefinitions[0]?.id ?? (null as number | null),
                    text: "",
                    dynamicFieldValues: typeDefinitions[0]
                      ? emptyDynamicFieldValuesForDefinition(typeDefinitions[0])
                      : {},
                    mcqOptions: [
                      { text: "", isCorrect: true },
                      { text: "", isCorrect: false },
                      { text: "", isCorrect: false },
                      { text: "", isCorrect: false },
                    ],
                    trueFalseCorrect: true,
                    shortAnswers: [""],
                  },
                ],
              });
            }}
            variant="outline"
            className="h-14 rounded-[6px] border-[#9E2891] text-[#9E2891] font-semibold text-[16px] bg-white "
          >
            Add Another Practice
          </Button>
        </div>
      </div>
    );
  }

  const renderStep = () => {
    if (isModuleContext) {
      switch (currentStep) {
        case 1:
          return (
            <ContextStep
              formData={formData}
              setFormData={setFormData}
              nextStep={nextStep}
              onCancel={() => navigate(backPath)}
              isLessonPractice={isLearnEnglishLessonPractice}
              lessonTitle={lessonTitleDisplay}
              parentSummary={parentSummary}
            />
          );
        case 2:
          return (
            <PersonaStep
              personas={personas}
              loading={personasLoading}
              error={personasError}
              onRetry={() => void reloadPersonas()}
              selectedPersona={selectedPersona}
              setSelectedPersona={setSelectedPersona}
              nextStep={nextStep}
              prevStep={prevStep}
            />
          );
        case 3:
          return (
            <QuestionsStep
              formData={formData}
              setFormData={setFormData}
              nextStep={nextStep}
              prevStep={prevStep}
              typeDefinitions={typeDefinitions}
              definitionsLoading={definitionsLoading}
              definitionsError={definitionsError}
            />
          );
        case 4:
          return (
            <ReviewStep
              formData={formData}
              selectedPersona={selectedPersona}
              personas={personas}
              isLessonPractice={isLearnEnglishLessonPractice}
              lessonTitle={lessonTitleDisplay}
              programLabel={programLabel}
              courseLabel={courseId ? `Course ${courseId}` : null}
              moduleLabel={moduleId ? `Module ${moduleId}` : null}
              prevStep={prevStep}
              onEditContext={() => setCurrentStep(1)}
              onEditQuestions={() => setCurrentStep(3)}
              parentSummary={parentSummary}
              typeDefinitions={typeDefinitions}
              canPublish={parentContext !== null}
              submitting={submitting}
              onSaveDraft={() => void submitPractice("DRAFT")}
              onPublish={() => void submitPractice("PUBLISHED")}
            />
          );
        default:
          return null;
      }
    }

    switch (currentStep) {
      case 1:
        return (
          <ScenarioStep
            formData={formData}
            setFormData={setFormData}
            nextStep={nextStep}
            cancelHref={backPath}
          />
        );
      case 2:
        return (
          <PersonaStep
            personas={personas}
            loading={personasLoading}
            error={personasError}
            onRetry={() => void reloadPersonas()}
            selectedPersona={selectedPersona}
            setSelectedPersona={setSelectedPersona}
            nextStep={nextStep}
            prevStep={prevStep}
          />
        );
      case 3:
        return (
          <QuestionsStep
            formData={formData}
            setFormData={setFormData}
            nextStep={nextStep}
            prevStep={prevStep}
            typeDefinitions={typeDefinitions}
            definitionsLoading={definitionsLoading}
            definitionsError={definitionsError}
          />
        );
      case 4:
        return (
          <ReviewStep
            formData={formData}
            selectedPersona={selectedPersona}
            personas={personas}
            isLessonPractice={isLearnEnglishLessonPractice}
            lessonTitle={lessonTitleDisplay}
            programLabel={programLabel}
            courseLabel={courseId ? `Course ${courseId}` : null}
            moduleLabel={moduleId ? `Module ${moduleId}` : null}
            prevStep={prevStep}
            onEditContext={() => setCurrentStep(1)}
            onEditQuestions={() => setCurrentStep(3)}
            parentSummary={parentSummary}
            typeDefinitions={typeDefinitions}
            canPublish={parentContext !== null}
            submitting={submitting}
            onSaveDraft={() => void submitPractice("DRAFT")}
            onPublish={() => void submitPractice("PUBLISHED")}
          />
        );
      default:
        return null;
    }
  };

  return (
    <div className="space-y-8 pb-32 px-6 pt-6 min-h-screen ">
      <div className="mx-auto max-w-7xl w-full">
        <div className="flex items-center justify-between mb-8">
          <Link
            to={backPath}
            className="flex items-center gap-2 text-[15px] font-medium text-grayScale-600 transition-colors hover:text-brand-500 decoration-none"
          >
            <ArrowLeft className="h-4 w-4" />
            {backLabel}
          </Link>
        </div>

        <div className=" mb-10">
          <div className="flex items-center justify-between">
            <h1 className="text-3xl font-bold text-[#0F172A]">
              Add New Practice
            </h1>
            <Button
              variant="outline"
              className="rounded-[8px] border-grayScale-200 text-grayScale-600 h-10 px-6 font-bold bg-white hover:bg-grayScale-50"
              onClick={() => navigate(backPath)}
            >
              Cancel
            </Button>
          </div>
          <p className="text-grayScale-400 text-base">
            Create a practice with story details, a persona, and questions from your question type library.
          </p>
          {lessonId ? (
            <div className="mt-4 rounded-xl border border-violet-200 bg-violet-50/80 px-4 py-3 text-sm text-violet-950">
              <p className="font-semibold text-violet-900">Lesson practice</p>
              <p className="mt-1 text-violet-800/90">
                Linked to lesson{" "}
                <span className="font-mono font-bold text-violet-950">
                  #{lessonId}
                </span>
                {lessonTitleDisplay ? (
                  <>
                    {" "}
                    — <span className="font-medium">{lessonTitleDisplay}</span>
                  </>
                ) : null}
                .
              </p>
            </div>
          ) : null}
        </div>

        <div className="mx-auto w-[70%] mb-12">
          <Stepper steps={[...STEP_LABELS]} currentStep={currentStep} />
        </div>

        <div
          className={`mx-auto ${currentStep === 3 || currentStep === 4 ? "max-w-6xl" : "max-w-4xl"}`}
        >
          {renderStep()}
        </div>
      </div>
    </div>
  );
}
