import toast from "react-hot-toast";
import { useEffect, useState } from "react";
import { Difficulty, IExam } from "@/types";
import { useNavigate } from "react-router-dom";
import { useDebounce } from "@/hooks/useDebounce";
import { API_Instance } from "@/api/axios.instance";
import API_Constants from "@/constants/api.constants";
import ROUTE_CONSTANTS from "@/constants/route.constants";
import { Accordion, AccordionRow } from "../shared/Accordion";
import { CheckCircle, ClipboardClock, Search, Share2 } from "lucide-react";
import { difficultyColor, getAxiosErrorMessage } from "@/utils/index.utils";
import { Button, Empty, Input, Popconfirm, Spin, Switch, Pagination, Tooltip } from "antd";
import { ChevronDown, ChevronRight, ClipboardList, Info, Pencil, Trash2 } from "lucide-react";

const initialPagination = {
  page: 1,
  limit: 10,
  total: 0,
  totalPages: 0,
};

const filterInitial = {
  testSearch: "",
  questionSearch: "",
};

export const MockTestTreeCard = ({
  exam,
  isOpen,
  onToggle,
}: {
  exam: IExam;
  isOpen?: boolean;
  onToggle?: () => void;
}) => {
  const [openTestId, setOpenTestId] = useState<string | null>(null);
  const [openQuestionId, setOpenQuestionId] = useState<string | null>(null);
  const [tests, setTests] = useState<any[]>([]);
  const [questions, setQuestions] = useState<any[]>([]);
  const [testPagination, setTestPagination] = useState(initialPagination);
  const [questionPagination, setQuestionPagination] = useState(initialPagination);
  const [loading, setLoading] = useState(false);
  const [topicLoading, setTopicLoading] = useState(false);
  const [filterValues, setFilterValues] = useState(filterInitial);

  const debouncedTestSearch = useDebounce(filterValues.testSearch, 600);
  const navigate = useNavigate();

  const toggleTest = (testId: string) => {
    const isSame = openTestId === testId;

    if (isSame) {
      setOpenTestId(null);
      setOpenQuestionId(null);
      setQuestions([]);
      return;
    }

    setOpenTestId(testId);
    setQuestions([]);
    setFilterValues((prev) => ({ ...prev, questionSearch: "" }));
    setQuestionPagination(initialPagination);
    getQuestions(testId);
  };

  const toggleQuestion = (id: string) => {
    const isSame = openQuestionId === id;
    setOpenQuestionId(isSame ? null : id);
  };

  const getTests = async (
    page: number = initialPagination.page,
    limit: number = initialPagination.limit,
    search: string = debouncedTestSearch,
  ) => {
    setTopicLoading(true);
    try {
      const response = await API_Instance.get(
        `${API_Constants.mockTests}?page=${page}&limit=${limit}&examId=${exam.id}&search=${search}`,
      );
      const data = await response.data;
      setTests(data.data || []);
      setTestPagination(data.meta || initialPagination);
    } catch (error) {
      toast.error(getAxiosErrorMessage(error));
    } finally {
      setTopicLoading(false);
    }
  };

  const getQuestions = async (testId: string) => {
    if (!testId) return;
    setLoading(true);
    try {
      const response = await API_Instance.get(`${API_Constants.mockTests}/${testId}`);
      const data = response.data.data;
      setQuestions(data.questions || []);
    } catch (error) {
      toast.error(getAxiosErrorMessage(error));
    } finally {
      setLoading(false);
    }
  };

  const handlePublishToggle = async (id: string, publish: boolean) => {
    try {
      await API_Instance.put(`${API_Constants.mockTests}/${id}`, { publish });
      toast.success(`Mock Test ${publish ? "published" : "un-published"} successfully`);
      getTests(testPagination.page, testPagination.limit, debouncedTestSearch);
    } catch (error: any) {
      toast.error(getAxiosErrorMessage(error));
    }
  };

  const handleDeleteTest = async (id: string) => {
    try {
      await API_Instance.delete(`${API_Constants.mockTests}/${id}`);
      toast.success("Mock Test deleted successfully");
      getTests(testPagination.page, testPagination.limit, debouncedTestSearch);
    } catch (error: any) {
      toast.error(getAxiosErrorMessage(error));
    }
  };

  useEffect(() => {
    if (isOpen) {
      getTests(1, testPagination.limit, debouncedTestSearch);
    }
  }, [debouncedTestSearch, isOpen]);

  return (
    <Accordion
      defaultExpanded={false}
      leftIcon={<ClipboardClock size={24} />}
      title={
        <div>
          <h2 className="text-md font-semibold text-slate-900">
            {exam.examName}
          </h2>
          <p className="text-xs text-slate-500 mt-0.5 flex items-center gap-2">
            <span>{exam.mockTestCount || 0} Mock Tests</span>
          </p>
        </div>
      }
      rightActions={
        <div
          className="flex items-center gap-1 pl-2 border-slate-200 ml-2"
          onClick={(e) => e.stopPropagation()}
        >
          <Button
            type="primary"
            ghost
            onClick={() =>
              navigate(ROUTE_CONSTANTS.MockTestCreate, {
                state: { examId: exam.id, examName: exam.examName },
              })
            }
          >
            Add Mock Test
          </Button>
        </div>
      }
      isOpen={isOpen}
      onToggle={() => {
        if (onToggle) onToggle();
        setOpenTestId(null);
        setOpenQuestionId(null);
        setQuestions([]);
        setFilterValues(filterInitial);
      }}
      content={
        <>
          <div className="mt-2 flex gap-3 items-end w-[18rem]">
            <Input
              placeholder={"Search Mock Tests"}
              prefix={<Search size={16} />}
              autoComplete="off"
              allowClear
              value={filterValues.testSearch}
              onChange={(e) => {
                setFilterValues({
                  ...filterValues,
                  testSearch: e.target.value,
                });
              }}
            />
          </div>

          <Spin spinning={topicLoading}>
            {tests.length === 0 && !topicLoading ? (
              <div className="min-h-[100px] flex items-center justify-center">
                <Empty
                  description={
                    debouncedTestSearch
                      ? "No mock tests found for your search"
                      : "No mock tests available"
                  }
                />
              </div>
            ) : (
              <div className="pt-4 pl-2 border-l-2 border-slate-200 ml-6 space-y-1">
                {tests.length > 0 &&
                  tests.map((test) => (
                    <AccordionRow
                      key={test.id}
                      title={
                        <div className="w-full flex items-center justify-between gap-3">
                            <div className="flex items-center gap-2">
                              <h2 className="text-md font-semibold text-slate-900">
                                {test.title}
                              </h2>
                              <p className="text-xs text-slate-500 flex items-center gap-2">
                                <span>{test._count?.questions || test.questionCount || 0} Questions</span>
                                <span className="text-slate-300">•</span>
                                <span>{test.totalMarks || 0} Total Marks</span>
                                {(test.totalMarks > 0 && (test._count?.questions || test.questionCount) > 0) ? (
                                  <>
                                    <span className="text-slate-300">•</span>
                                    <span>{test.totalMarks / (test._count?.questions || test.questionCount)} Marks per Question</span>
                                  </>
                                ) : null}
                              </p>
                              {test.referenceInstitution && test.referenceInstitution.user?.institutionName && (
                                <div className="flex items-center gap-1.5 px-2 py-0.5 bg-blue-50 border border-blue-100 rounded-md">
                                  <Share2 size={12} className="text-blue-500" />
                                  <span className="text-[11px] font-medium text-blue-600">
                                    {/* Shared by {test.referenceInstitution?.user?.institutionName || test.referenceInstitution?.user?.firstName || "Institution"} */}
                                    Shared by Exam Infra
                                  </span>
                                </div>
                              )}
                            </div>

                          {/* Action Buttons */}
                          <div
                            className="flex items-center gap-1 pl-2 border-l border-slate-200 ml-2"
                            onClick={(e) => e.stopPropagation()}
                          >
                            <Switch
                              checkedChildren="Published"
                              unCheckedChildren="Yet to publish"
                              checked={test.publish}
                              onChange={(val) =>
                                handlePublishToggle(test.id, val)
                              }
                            />
                            <Tooltip title={test.referenceSourceId ? "Shared mock test cannot be edited" : "Edit Test"}>
                              <div>
                                <button
                                  className={`p-1.5 rounded-xl transition-colors ${test.referenceSourceId ? 'text-slate-300 cursor-not-allowed' : 'text-slate-400 hover:text-blue-600 hover:bg-blue-50'}`}
                                  disabled={!!test.referenceSourceId}
                                  onClick={() => {
                                    if (!test.referenceSourceId) {
                                      navigate(ROUTE_CONSTANTS.MockTestEdit, {
                                        state: {
                                          ...test,
                                          examId: exam.id,
                                          examName: exam.examName,
                                        },
                                      });
                                    }
                                  }}
                                >
                                  <Pencil size={15} />
                                </button>
                              </div>
                            </Tooltip>
                            <Tooltip title={test.referenceSourceId ? "Shared mock test cannot be deleted" : "Delete Test"}>
                              <div>
                                <Popconfirm
                                  title="Delete the Test"
                                  description="Are you sure you want to delete this test?"
                                  onConfirm={() => {
                                    if (!test.referenceSourceId) {
                                      handleDeleteTest(test.id);
                                    }
                                  }}
                                  okText="Yes"
                                  cancelText="No"
                                  disabled={!!test.referenceSourceId}
                                >
                                  <button
                                    className={`p-1.5 rounded-xl transition-colors ${test.referenceSourceId ? 'text-slate-300 cursor-not-allowed' : 'text-slate-400 hover:text-red-600 hover:bg-red-50'}`}
                                    disabled={!!test.referenceSourceId}
                                  >
                                    <Trash2 size={15} />
                                  </button>
                                </Popconfirm>
                              </div>
                            </Tooltip>
                          </div>
                        </div>
                      }
                      isOpen={openTestId === test.id}
                      onToggle={() => {
                        toggleTest(test.id);
                      }}
                      disabled={test.questionCount === 0}
                      content={
                        <>
                          <Spin spinning={loading}>
                            {questions.length === 0 && !loading ? (
                              <div className="min-h-[100px] flex items-center justify-center">
                                <Empty description="No questions available" />
                              </div>
                            ) : (
                              <>
                                {questions?.length > 0 &&
                                  questions?.map((q) => {
                                    const isQuestionOpen = openQuestionId === q.mockTestQuestionId;
                                    return (
                                      <AccordionRow
                                        key={q.mockTestQuestionId}
                                        hideIcon
                                        className="bg-white shadow-sm border border-slate-100 overflow-hidden my-2"
                                        title={
                                          <div
                                            className={`
                                  flex items-center gap-4 p-0 cursor-pointer transition-colors duration-200
                                `}
                                          >
                                            <div className="text-slate-400 transition-transform duration-200">
                                              {isQuestionOpen ? (
                                                <ChevronDown size={14} />
                                              ) : (
                                                <ChevronRight size={14} />
                                              )}
                                            </div>

                                            <div className="flex-1 grid grid-cols-1 xl:grid-cols-12 gap-4 items-center">
                                              <div className="xl:col-span-4 flex items-center gap-3">
                                                <div className="hidden sm:flex items-center justify-center p-1 rounded bg-slate-100 text-brand-blue shrink-0">
                                                  <ClipboardList size={20} />
                                                </div>
                                                <h3
                                                  className={`text-sm font-medium text-left leading-relaxed line-clamp-1 ${isQuestionOpen
                                                    ? "text-brand-blue"
                                                    : "text-slate-700"
                                                    }`}
                                                >
                                                  {q.questionText}
                                                </h3>
                                              </div>

                                              <div className="xl:col-span-8 flex flex-wrap xl:justify-end items-center gap-x-3 gap-y-2 mt-2 xl:mt-0">
                                                {q.subject && (
                                                  <span className="text-[11px] px-2 py-0.5 rounded bg-purple-50 text-purple-600 border border-purple-100">
                                                    {q.subject}
                                                  </span>
                                                )}
                                                {q.topic && (
                                                  <span className="text-[11px] px-2 py-0.5 rounded bg-blue-50 text-blue-600 border border-blue-100">
                                                    {q.topic}
                                                  </span>
                                                )}
                                                {q.language && (
                                                  <span className="text-[11px] px-2 py-0.5 rounded bg-amber-50 text-amber-600 border border-amber-100">
                                                    {q.language}
                                                  </span>
                                                )}
                                                <span
                                                  className={`text-[10px] px-2.5 py-0.5 rounded-full font-semibold border min-w-[60px] text-center ${difficultyColor(
                                                    q.difficulty === "Easy"
                                                      ? Difficulty.Easy
                                                      : q.difficulty === "Medium"
                                                        ? Difficulty.Medium
                                                        : Difficulty.Hard,
                                                  )}`}
                                                >
                                                  {q.difficulty}
                                                </span>
                                              </div>
                                            </div>
                                          </div>
                                        }
                                        isOpen={openQuestionId === q.mockTestQuestionId}
                                        onToggle={() => toggleQuestion(q.mockTestQuestionId)}
                                        content={
                                          <div className="pt-2 pb-6 px-4 sm:px-8 bg-slate-50 border-t border-slate-100">
                                            <div className="mb-4 flex flex-col items-start gap-2">
                                              <div className="text-sm font-medium text-left leading-relaxed text-slate-700 text-wrap">
                                                {q.questionText}
                                              </div>
                                              {q.questionImage && (
                                                <img
                                                  src={q.questionImage}
                                                  alt="Question Image"
                                                  className="h-[5rem] object-contain rounded-md mt-2"
                                                />
                                              )}
                                            </div>
                                            <div className="space-y-3">
                                              {q.options.map((option: any, idx: number) => {
                                                const isCorrect = idx === q.correctAnswer;
                                                let optionClass =
                                                  "w-full text-left p-3 rounded-xl border text-sm font-medium flex justify-between items-center transition-all duration-200 cursor-default ";

                                                if (isCorrect) {
                                                  optionClass +=
                                                    "bg-green-50 border-green-500 text-green-800 shadow-sm ring-1 ring-green-500/20";
                                                } else {
                                                  optionClass +=
                                                    "bg-white border-slate-200 text-slate-500 opacity-80";
                                                }

                                                return (
                                                  <div key={idx} className={optionClass}>
                                                    <div className="flex items-center gap-3">
                                                      <span
                                                        className={`flex items-center justify-center w-6 h-6 rounded-full text-xs font-bold border ${isCorrect
                                                          ? "border-green-600 bg-green-100 text-green-700"
                                                          : "border-slate-300 bg-slate-50 text-slate-500"
                                                          }`}
                                                      >
                                                        {String.fromCharCode(65 + idx)}
                                                      </span>
                                                      {option.option !== "" && <span>{option.option}</span>}
                                                      {option.optionImage && (
                                                        <img
                                                          src={option.optionImage}
                                                          alt="Option Image"
                                                          className="h-[5rem] w-auto object-contain rounded-xl ml-5"
                                                        />
                                                      )}
                                                    </div>
                                                    {isCorrect && (
                                                      <CheckCircle className="text-green-600" size={18} />
                                                    )}
                                                  </div>
                                                );
                                              })}
                                            </div>
                                            <div className="mt-6 space-y-4">
                                              <div className="p-4 rounded-xl border bg-blue-50 border-blue-100">
                                                <h4 className="text-xs font-bold uppercase tracking-wider mb-2 flex items-center gap-2 text-blue-700">
                                                  <Info size={14} />
                                                  Explanation
                                                </h4>
                                                <p className="text-sm text-slate-700 leading-relaxed font-medium whitespace-pre-line">
                                                  {q.explanation}
                                                </p>
                                                {q.explanationImage && (
                                                  <img
                                                    src={q.explanationImage}
                                                    alt="Explanation Image"
                                                    className="h-[5rem] w-auto object-contain rounded-xl ml-5"
                                                  />
                                                )}
                                              </div>
                                            </div>
                                          </div>
                                        }
                                      />
                                    );
                                  })}
                              </>
                            )}
                          </Spin>
                        </>
                      }
                    />
                  ))}
                <div className="flex justify-end pb-2">
                  <Pagination
                    current={testPagination.page}
                    total={testPagination.total}
                    pageSize={testPagination.limit}
                    onChange={(p, pageSize) => {
                      setTestPagination({ ...testPagination, page: p, limit: pageSize });
                      getTests(p, pageSize);
                    }}
                    showSizeChanger
                  />
                </div>
              </div>
            )}
          </Spin>
        </>
      }
    />
  );
};

export default MockTestTreeCard;