import { createLazyFileRoute } from "@tanstack/react-router";
import {
  Card,
  Flex,
  Pagination,
  Stack,
  Radio,
  Text,
  Textarea,
  Loader,
  ActionIcon,
  CloseButton,
  Group,
} from "@mantine/core";
import { useQuery, useMutation } from "@tanstack/react-query";
import {
  submitOptionMutationOptions,
  getAverageScoreSubAspectQueryOptions,
  getAverageScoreQueryOptions,
  fetchAspects,
  getQuestionsAllQueryOptions,
  toggleFlagAnswer,
} from "@/modules/assessmentManagement/queries/assessmentQueries";
import { TbFlagFilled, TbUpload, TbChevronRight, TbChevronUp } from "react-icons/tb";
import FinishAssessmentModal from "@/modules/assessmentManagement/modals/ConfirmModal";
import { useState, useRef, useEffect } from "react";

const getQueryParam = (param: string) => {
  const urlParams = new URLSearchParams(window.location.search);
  return urlParams.get(param);
};

export const Route = createLazyFileRoute("/_dashboardLayout/assessment/")({
  component: AssessmentPage,
});

interface ToggleFlagResponse {
  message: string;
  answer: {
    id: string;
    createdAt: string | null;
    updatedAt: string | null;
    optionId: string | null;
    assessmentId: string | null;
    isFlagged: boolean | null;
    filename: string | null;
    validationInformation: string;
  };
}

export default function AssessmentPage() {
  const [page, setPage] = useState(1);
  const limit = 10;
  const questionRefs = useRef<{ [key: string]: HTMLDivElement | null }>({});
  const [files, setFiles] = useState<File[]>([]);
  const [dragActive, setDragActive] = useState(false);
  const [flaggedQuestions, setFlaggedQuestions] = useState<{
    [key: string]: boolean;
  }>({});
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [modalOpen, setModalOpen] = useState(false);
  const [selectedAspectId, setSelectedAspectId] = useState<string | null>(null);
  const [selectedSubAspectId, setSelectedSubAspectId] = useState<string | null>(null);
  const [assessmentId, setAssessmentId] = useState<string | null>(null);
  const [answers, setAnswers] = useState<{ [key: string]: string }>({});

  // Fetch aspects and sub-aspects
  const aspectsQuery = useQuery({
    queryKey: ["aspects"],
    queryFn: fetchAspects,
  });

  // Fetching questions data using useQuery
  const { data, isLoading, isError, error } = useQuery(
    getQuestionsAllQueryOptions(page, limit)
  );

  const handleFinishClick = () => {
    setModalOpen(true);
  };

  useEffect(() => {
    const id = getQueryParam("id");

    if (!id) {
      // Handle if no ID found
      setAssessmentId(null);
    } else {
      setAssessmentId(id);
    }

    // Check if aspectsQuery.data and aspectsQuery.data.data are defined
    if (aspectsQuery.data?.data && aspectsQuery.data.data.length > 0) {
      // If no sub-aspect is selected, find a suitable default
      if (selectedSubAspectId === null) {
        const firstMatchingSubAspect = aspectsQuery.data.data
          .flatMap(aspect => aspect.subAspects) // Get all sub-aspects
          .find(subAspect => data?.data.some(question => question.subAspectId === subAspect.id)); // Filter based on available questions

        if (firstMatchingSubAspect) {
          setSelectedSubAspectId(firstMatchingSubAspect.id);
          setSelectedAspectId(aspectsQuery.data.data.find(aspect =>
            aspect.subAspects.some(sub => sub.id === firstMatchingSubAspect.id)
          )?.id || null); // Set selectedAspectId based on the found sub-aspect
        }
      }
    }
  }, [aspectsQuery.data, selectedSubAspectId, data?.data])

  const handleConfirmFinish = () => {
    if (assessmentId) {
      // Menggunakan history.pushState untuk mengubah URL tanpa reload
      const newUrl = `/assessmentResult?id=${assessmentId}`;
      window.history.pushState({}, "", newUrl);
      // Setelah mengubah URL, Anda bisa menjalankan logika lain jika diperlukan
      console.log("Navigated to:", newUrl);
    }
  };

  // Tambahkan state untuk aspek yang terbuka
  const [openAspects, setOpenAspects] = useState<{ [key: string]: boolean }>({});

  const toggleAspect = (aspectId: string) => {
    setOpenAspects((prev) => ({
      ...prev,
      [aspectId]: !prev[aspectId], // Toggle state untuk aspek yang diklik
    }));
  };

  // Fetch average scores by aspect
  const averageScoreQuery = useQuery(getAverageScoreQueryOptions(assessmentId || ""));

  // Fetch average scores by sub-aspect
  const averageScoreSubAspectQuery = useQuery(getAverageScoreSubAspectQueryOptions(assessmentId || ""));

  // Filter average score aspect berdasarkan sub-aspect yang dipilih
  const filteredAverageScores = averageScoreQuery.data?.aspects?.filter(aspect =>
    aspect.subAspects.some(subAspect => subAspect.subAspectId === selectedSubAspectId)
  );

  // Filter average scores for the selected sub-aspect
  const averageScoresForSelectedSubAspect = averageScoreSubAspectQuery.data?.subAspects?.filter(
    (subAspect) =>
      subAspect.aspectId === selectedAspectId // Use the appropriate property for filtering
  );

  // Mutation function to toggle flag
  const toggleFlagMutation = useMutation<ToggleFlagResponse, Error, string>({
    mutationFn: toggleFlagAnswer,
    onSuccess: (response) => {
      if (response && response.answer) {
        const { answer } = response;
        setFlaggedQuestions((prevFlags) => ({
          ...prevFlags,
          [answer.id]: answer.isFlagged !== null ? answer.isFlagged : false,
        }));
      }
    },

    onError: (error) => {
      console.error("Error toggling flag:", error);
    },
  });

  // Mutation function to submit answer
  const submitOptionMutation = useMutation(submitOptionMutationOptions());

  useEffect(() => {
    const savedAnswers = localStorage.getItem("assessmentAnswers");
    if (savedAnswers) {
      setAnswers(JSON.parse(savedAnswers));
    }
  }, []);

  const handleAnswerChange = (questionId: string, optionId: string) => {
    const assessmentId = getQueryParam("id");

    if (!assessmentId) {
      console.error("Assessment ID tidak ditemukan");
      return;
    }

    // Simpan jawaban ke localStorage
    const updatedAnswers = { ...answers, [questionId]: optionId };
    localStorage.setItem("assessmentAnswers", JSON.stringify(updatedAnswers));

    // Update state
    setAnswers(updatedAnswers);

    submitOptionMutation.mutate({
      optionId,
      assessmentId,
      questionId,
      isFlagged: false,
      filename: undefined,
    });
  };

  // Drag and Drop handlers
  const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
    setDragActive(true);
  };

  const handleDragLeave = () => {
    setDragActive(false);
  };

  const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
    event.preventDefault();
    setDragActive(false);
    const droppedFiles = Array.from(event.dataTransfer.files);
    setFiles((prevFiles) => [...prevFiles, ...droppedFiles]);
  };

  const handleClick = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  };

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files) {
      const fileArray = Array.from(event.target.files); // Ubah ke array hanya jika files tidak null
      setFiles((prevFiles) => [...prevFiles, ...fileArray]);
    }
  };

  const handleRemoveFile = (fileIndex: number) => {
    setFiles((prevFiles) =>
      prevFiles.filter((_, index) => index !== fileIndex)
    );
  };

  // Function to scroll to the specific question
  const scrollToQuestion = (questionId: string) => {
    const questionElement = questionRefs.current[questionId];
    if (questionElement) {
      questionElement.scrollIntoView({ behavior: "smooth" });
    }
  };

  // Handle pagination
  const handlePageChange = (newPage: number) => {
    setPage(newPage);
  };

  // Render conditions
  if (isLoading) {
    return <Loader />;
  }

  if (isError) {
    return (
      <Text color="red">
        Error: {error?.message || "Terjadi kesalahan saat memuat pertanyaan."}
      </Text>
    );
  }

  const totalQuestions = data?.data?.length || 0;

  if (!assessmentId) {
    return (
      <Card shadow="sm" p="lg" radius="md" withBorder>
        <Text color="red" className="text-center">
          Error: Data Asesmen tidak ditemukan. Harap akses halaman melalui link yang valid.
        </Text>
      </Card>
    );
  }

  const startIndex = (page - 1) * limit;
  const endIndex = startIndex + limit;
  const paginatedQuestions = data?.data.slice(startIndex, endIndex) || [];

  const filteredQuestions = paginatedQuestions.filter((question) => {
    return question.subAspectId === selectedSubAspectId; // Misalnya, jika `question` memiliki `subAspectId`
  });

  return (
    <Card shadow="sm" p="lg" radius="md" withBorder>
      <Stack gap="md">
        <Flex justify="space-between" align="flex-start" mt="lg">

          {/* LEFT-SIDE */}
          {/* Aspek dan Sub-Aspek */}
          <Flex direction="column" gap="xs" className="mr-4 w-52">
            <div className="space-y-4">
              {aspectsQuery.data?.data
                .filter((aspect) =>
                  aspect.subAspects.some((subAspect) =>
                    data?.data.some((question) => question.subAspectId === subAspect.id)
                  )
                )
                .map((aspect) => (
                  <div
                    key={aspect.id}
                    className="p-4 bg-gray-50 rounded-lg shadow-md"
                  >
                    <div
                      className="flex justify-between cursor-pointer"
                      onClick={() => toggleAspect(aspect.id)}
                    >
                      <div className="text-lg text-gray-700">{aspect.name}</div>
                      <div>
                        {openAspects[aspect.id] ? (
                          <TbChevronUp size={25} />
                        ) : (
                          <TbChevronRight size={25} />
                        )}
                      </div>
                    </div>

                    {openAspects[aspect.id] && (
                      <div className="mt-2 space-y-2">
                        {aspect.subAspects
                          .filter((subAspect) =>
                            data?.data.some((question) => question.subAspectId === subAspect.id)
                          )
                          .map((subAspect) => (
                            <div
                              key={subAspect.id}
                              className={`flex justify-between text-gray-600 cursor-pointer ${selectedSubAspectId === subAspect.id ? 'font-bold' : ''}`}
                              onClick={() => setSelectedSubAspectId(subAspect.id)}
                            >
                              <div>{subAspect.name}</div>
                            </div>
                          ))}
                      </div>
                    )}
                  </div>
                ))}
            </div>
          </Flex>
          {/* Pertanyaan */}
          <Stack gap="sm" style={{ flex: 1 }}>
            <Text className="text-2xl font-bold">
              Harap menjawab semua pertanyaan yang tersedia
            </Text>
            <Text className="text-gray-400">Semua jawaban Anda akan ditinjau</Text>
            {filteredQuestions.length === 0 ? (
              <Text color="black" className="text-center p-3">
                Pertanyaan tidak ada untuk sub-aspek yang dipilih.
              </Text>
            ) : (
              filteredQuestions.map((question: any, index: number) => {
                const questionId = question.questionId;
                if (!questionId) return null;

                return (
                  <Card
                    key={questionId}
                    shadow="sm"
                    p="lg"
                    radius="md"
                    withBorder
                    ref={(el) => (questionRefs.current[questionId] = el)}
                    style={{ position: "relative" }}
                  >
                    <Stack gap="sm">
                      <Flex justify="space-between" align="flex-start" style={{ width: "100%" }}>
                        <Text
                          className="font-bold"
                          style={{
                            flexGrow: 1,
                            wordBreak: "break-word",
                            marginRight: "40px",
                          }}
                        >
                          {startIndex + index + 1}. {question.questionText}
                        </Text>

                        <ActionIcon
                          onClick={() => {
                            setFlaggedQuestions((prevFlags) => ({
                              ...prevFlags,
                              [questionId]: !prevFlags[questionId],
                            }));
                            toggleFlagMutation.mutate(questionId);
                          }}
                          title="Tandai"
                          color={flaggedQuestions[questionId] ? "red" : "white"}
                          style={{
                            border: "1px gray solid ",
                            borderRadius: "4px",
                            backgroundColor: flaggedQuestions[questionId] ? "red" : "white",
                          }}
                        >
                          <TbFlagFilled
                            size={20}
                            color={flaggedQuestions[questionId] ? "white" : "black"}
                            style={{
                              padding: "2px",
                            }}

                          />
                        </ActionIcon>
                      </Flex>

                      {question.options?.length > 0 ? (
                        <Radio.Group value={answers[question.questionId] || ""}>
                          <div className="flex flex-col gap-4">
                            {question.options.map((option: any) => (
                              <label
                                key={option.optionId}
                                className="bg-gray-200 border rounded-lg p-4 cursor-pointer transition-transform transform hover:scale-105 shadow-md hover:shadow-lg flex items-center"
                                onClick={() => document.getElementById(option.optionId)?.click()}
                              >
                                <Radio
                                  id={option.optionId}
                                  className="font-bold"
                                  value={option.optionId}
                                  label={option.optionText}
                                  size="md"
                                  radius="xl"
                                  style={{ pointerEvents: "none" }}
                                  checked={answers[question.questionId] === option.optionId} // Untuk menampilkan jawaban yang sudah dipilih
                                  onChange={() => handleAnswerChange(question.questionId, option.optionId)} // Memanggil handleAnswerChange dengan questionId dan optionId
                                />
                              </label>
                            ))}
                          </div>
                        </Radio.Group>
                      ) : (
                        <Text color="red">Tidak ada opsi untuk pertanyaan ini.</Text>
                      )}

                      <Textarea placeholder="Berikan keterangan terkait jawaban di atas" />

                      {/* File Upload */}
                      {question.needFile === true && (
                        <div
                          className={`pt-5 pb-5 pr-5 pl-2 border-2 border-dashed ${dragActive ? "bg-gray-100" : "bg-transparent"
                            } shadow-lg`}
                          onDragOver={handleDragOver}
                          onDragLeave={handleDragLeave}
                          onDrop={handleDrop}
                          onClick={handleClick}
                        >
                          <Flex align="center" justify="space-between" gap="sm">
                            <TbUpload
                              size={24}
                              style={{ marginLeft: "8px", marginRight: "8px" }}
                            />
                            <div className="flex-grow text-right">
                              <Text className="font-bold">
                                Klik untuk unggah atau geser file disini
                              </Text>
                              <Text className="text-sm text-gray-400">
                                PNG, JPG, PDF
                              </Text>
                            </div>
                          </Flex>
                          <input
                            type="file"
                            ref={fileInputRef}
                            onChange={handleFileChange}
                            style={{ display: "none" }}
                            accept="image/png, image/jpeg, application/pdf"
                          />
                        </div>
                      )}

                      {files.length > 0 && (
                        <Stack gap="sm" mt="sm">
                          <Text className="font-bold">File yang diunggah:</Text>
                          {files.map((file, fileIndex) => (
                            <Group key={fileIndex} align="center">
                              <Text>{file.name}</Text>
                              <CloseButton
                                title="Hapus file"
                                onClick={() => handleRemoveFile(fileIndex)}
                              />
                            </Group>
                          ))}
                        </Stack>
                      )}
                    </Stack>
                  </Card>
                );
              })
            )}
          </Stack>

          {/* Navigasi dan Pagination */}
          <Flex direction="column" gap="xs" className="ml-4">

            {/* Navigasi (Number of Questions) */}
            <div className="grid grid-cols-5 gap-2">
              {filteredQuestions.map((question, index) => {
                const questionId = question.questionId;
                if (!questionId) return null;

                // Menentukan nomor soal berdasarkan indeks pertanyaan yang difilter
                const questionNumber = index + 1; // Nomor pertanyaan dimulai dari 1

                return (
                  <div key={questionId} className="flex justify-center relative">
                    <button
                      className={`w-10 h-10 border rounded-lg flex items-center justify-center relative
                        ${flaggedQuestions[questionId] ? "text-black" : "bg-transparent text-black"}`}
                      onClick={() => scrollToQuestion(questionId)}
                    >
                      {questionNumber} {/* Menampilkan nomor pertanyaan yang sudah difilter */}
                    </button>

                    {flaggedQuestions[questionId] && (
                      <div className="absolute top-0 right-0 w-0 h-0 border-b-[20px] border-b-transparent border-r-[20px] border-r-black rounded-e-md" />
                    )}
                  </div>
                );
              })}
            </div>

            <div className="mt-4 flex justify-center">
              <Pagination
                value={page}
                total={Math.ceil(totalQuestions / limit)}
                onChange={handlePageChange}
              />
            </div>

            {/* Skor Aspek dan Sub-Aspek */}
            <div className="mt-4">
              <Card shadow="sm" p="md" radius="md" withBorder>
                <Stack>
                  {/* Skor Aspek */}
                  <div>
                    {filteredAverageScores && filteredAverageScores.length > 0 ? (
                      filteredAverageScores.map((aspect) => (
                        <div key={aspect.aspectId} className="flex justify-between items-center">
                          <Text className="text-xl text-gray-400">
                            {aspect.aspectName}
                          </Text>
                          <Text className="text-xl font-bold">
                            {parseFloat(aspect.averageScore).toFixed(2)}
                          </Text>
                        </div>
                      ))
                    ) : (
                      <Text className="text-lg text-gray-400">Data aspek kosong</Text>
                    )}
                  </div>

                  {/* Garis pembatas */}
                  <div>
                    <hr className="border-t-2 border-gray-300 w-full mx-auto" />
                  </div>

                  {/* Skor Sub-Aspek */}
                  <div>
                    {averageScoresForSelectedSubAspect?.length ? (
                      averageScoresForSelectedSubAspect.map((subAspect) => (
                        <div key={subAspect.aspectId} className="flex justify-between items-center">
                          <Text className="text-lg text-gray-400">
                            {subAspect.subAspectName}
                          </Text>
                          <Text className="text-lg font-bold">
                            {parseFloat(subAspect.averageScore).toFixed(2)}
                          </Text>
                        </div>
                      ))
                    ) : (
                      <Text className="text-lg text-gray-400">Data sub aspek kosong</Text>
                    )}
                  </div>
                </Stack>

                {/* Tombol Selesai */}
                <div className="mt-6">
                  <button onClick={handleFinishClick} className="bg-gray-200 text-black font-bold py-2 w-full">
                    Selesai
                  </button>
                </div>

                {/* Modal untuk konfirmasi selesai asesmen */}
                <FinishAssessmentModal
                  opened={modalOpen}
                  onClose={() => setModalOpen(false)}
                  onConfirm={handleConfirmFinish}
                  assessmentId={assessmentId}
                />
              </Card>
            </div>
          </Flex>
        </Flex>
      </Stack>
    </Card>
  );
}