import { useState, useEffect, useRef, useMemo } from "react";
import { useNavigate, useParams } from "react-router-dom";
import {
  Stack,
  Title,
  Group,
  Text,
  Paper,
  Badge,
  SimpleGrid,
  Divider,
  Button,
  ActionIcon,
  Alert,
  Loader,
  Center,
  Modal,
  Table,
  Select,
  NumberInput,
  TextInput,
  ThemeIcon,
  Box,
  rem,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { useTranslation } from "react-i18next";
import {
  IconArrowLeft,
  IconPrinter,
  IconPlus,
  IconInfoCircle,
  IconCertificate,
  IconCalendar,
  IconMapPin,
  IconClock,
  IconScoreboard,
  IconUser,
  IconCheck,
  IconX,
  IconDetails
} from "@tabler/icons-react";
import { notify, useErrorHandler } from "@ema-platform/ui";
import {
  useGetExamQuery,
  useUpdateExamMutation,
  useAssignQuestionsMutation,
} from "../api/exam-api";
import { useGetQuestionsQuery } from "../../question/api/question-api";
import { useGetCertificationsQuery } from "../../certification/api/certification-api";
import { QuestionAssigner } from "../components/QuestionAssigner";
import { RecordResultModal } from "../../result/components/RecordResultModal";
import type { ExamStatus, QuestionBrief, actionTypes } from "../types/exam";

const STATUS_COLOR: Record<string, string> = {
  PENDING: "gray",
  ACTIVE: "blue",
  COMPLETED: "teal",
  CANCELLED: "red",
  POSTPONED: "orange",
  PUBLISHED: "green",
};

const FORM_LABEL: Record<string, string> = { ESSAY: "Essay", CHOICE: "Choice" };
const TYPE_LABEL: Record<string, string> = { WRITTEN: "Written", ORAL: "Oral" };
const ADMIN_LABEL: Record<string, string> = {
  OFFLINE: "Offline",
  ONLINE: "Online",
};
const EVAL_LABEL: Record<string, string> = {
  SUM: "Sum",
  AVERAGE: "Average",
  PERCENTAGE: "Percentage",
};

function InfoRow({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>
        {label}
      </Text>
      <Text fz="sm" fw={500}>
        {value || "—"}
      </Text>
    </div>
  );
}

export function ExamDetailPage() {
  const { t, i18n } = useTranslation();
  const locale = i18n.language as "en" | "am";
  const { handleError } = useErrorHandler();
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const printRef = useRef<HTMLDivElement>(null);
  const [recordOpened, { open: openRecord, close: closeRecord }] =
    useDisclosure(false);
  const [assignOpened, { open: openAssign, close: closeAssign }] =
    useDisclosure(false);
  const [draftQuestions, setDraftQuestions] = useState<QuestionBrief[]>([]);
  const [randomCount, setRandomCount] = useState(5);
  const [updateExam] = useUpdateExamMutation();
  const [assignQuestions, { isLoading: isAssigning }] =
    useAssignQuestionsMutation();
  const {
    data: exam,
    isLoading,
    isError,
  } = useGetExamQuery(id ?? "", { skip: !id });
  const { data: qRes } = useGetQuestionsQuery();
  const { data: certRes } = useGetCertificationsQuery();
  const allQuestions = qRes?.items ?? [];
  const certifications = certRes?.items ?? [];
  const [whatAction, setWhatAction] = useState<actionTypes>();
  const eligibleQuestions = useMemo(() => {
    if (!exam) return [];
    return allQuestions
      .filter(
        (q) =>
          q.certificationId === exam.certificationId && q.form === exam.form,
      )
      .map((q) => ({
        id: q.id,
        title: q.title,
        form: q.form,
        points: q.points,
      }));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [allQuestions, exam?.certificationId, exam?.form]);

  if (isLoading)
    return (
      <Center py="xl">
        <Loader />
      </Center>
    );
  if (isError || !exam) {
    return (
      <Stack gap="md">
        <Button
          variant="subtle"
          leftSection={<IconArrowLeft size={15} />}
          w="fit-content"
          onClick={() => navigate("/exams")}
        >
          {t("exam.backToExams")}
        </Button>
        <Alert color="red" icon={<IconInfoCircle size={17} />}>
          {t("exam.notFound")}
        </Alert>
      </Stack>
    );
  }

  const openAssignModal = () => {
    setDraftQuestions(exam.questions ?? []);
    setRandomCount(5);
    openAssign();
  };

  const handleRandomSelect = () => {
    const assignedIds = new Set(draftQuestions.map((q) => q.id));
    const currentTotal = draftQuestions.reduce(
      (s, q) => s + Number(q.points),
      0,
    );
    const cuttingPoint = Number(exam.cuttingPoint);
    const eligible = eligibleQuestions.filter((q) => !assignedIds.has(q.id));

    if (eligible.length === 0) {
      notify.error("No eligible questions available for random selection");
      return;
    }

    const maxPossible =
      currentTotal + eligible.reduce((s, q) => s + Number(q.points), 0);
    if (maxPossible < cuttingPoint) {
      notify.error(
        `Even all eligible questions combined (${maxPossible} pts) cannot reach the passing mark (${cuttingPoint} pts). Adjust the cutting point or add more questions.`,
      );
      return;
    }

    const shuffled = [...eligible].sort(() => Math.random() - 0.5);
    const targetCount = Math.min(randomCount, shuffled.length);
    const picked = shuffled.slice(0, targetCount);
    let pickedTotal = picked.reduce((s, q) => s + Number(q.points), 0);

    if (currentTotal + pickedTotal < cuttingPoint) {
      const remaining = shuffled.slice(targetCount);
      for (const q of remaining) {
        if (currentTotal + pickedTotal >= cuttingPoint) break;
        picked.push(q);
        pickedTotal += q.points;
      }
    }

    const msg =
      picked.length > targetCount
        ? `Selected ${picked.length} questions (${picked.length - targetCount} extra added to meet the ${cuttingPoint} pts passing mark)`
        : `Randomly selected ${picked.length} questions`;

    setDraftQuestions([...draftQuestions, ...picked]);
    notify.info(msg);
  };

  const handleAssign = async () => {
    try {
      const questionIds = draftQuestions.map((q) => q.id);
      if (whatAction === "add") {
        await assignQuestions({
          examId: exam.id,
          questionIds,
          remark: undefined,
        }).unwrap();
        notify.success("Questions assigned");
        closeAssign();
      } else if (whatAction === "remove") {
        // await removeQuestions({
        //   examId: exam.id,
        //   questionIds,
        //   remark: undefined,
        // });
        // notify.success("Questions removed");
        // closeAssign();
        notify.warning("no action yet");
      }
    } catch (e) {
      handleError(e);
    }
  };
  const handlePrint = async () => {
    const total = (exam.questions ?? []).reduce(
      (s, q) => s + Number(q.points),
      0,
    );
    if (total < Number(exam.cuttingPoint)) {
      notify.error(
        `Total question marks (${total}) is less than the passing mark (${exam.cuttingPoint}). Add more questions or adjust the cutting point before printing.`,
      );
      return;
    }

    const printWindow = window.open("", "_blank");
    if (!printWindow) return;

    let logoBase64 = "";
    try {
      const resp = await fetch("/ema-logo.png");
      const blob = await resp.blob();
      logoBase64 = await new Promise<string>((resolve) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result as string);
        reader.readAsDataURL(blob);
      });
    } catch {
      /* logo not available */
    }

    const qMap = new Map(allQuestions.map((qq) => [qq.id, qq]));
    const qHtml = (exam.questions ?? [])
      .map((q, i) => {
        const full = qMap.get(q.id);
        const titleStr = q.title[locale] || q.title.en;
        const descStr =
          full?.description?.[locale] || full?.description?.en || "";
        return `
      <div style="margin-bottom: 24px; page-break-inside: avoid;">
        <p style="font-weight: 700; margin-bottom: 4px; font-size: 13px;">Question ${i + 1} (${q.points} pts — ${FORM_LABEL[q.form] ?? q.form})</p>
        <p style="margin: 0 0 4px 0; font-size: 14px; line-height: 1.5;">${titleStr}</p>
        ${descStr ? `<p style="margin: 0 0 8px 0; font-size: 12px; color: #555; line-height: 1.4;">${descStr}</p>` : ""}
        ${q.form === "ESSAY" ? '<div style="border-bottom: 1px dashed #ccc; height: 80px; margin-bottom: 12px;"></div>'.repeat(3) : ""}
        ${q.form === "CHOICE" ? ["A. ______", "B. ______", "C. ______", "D. ______"].map((l) => `<p style="margin: 4px 0; font-size: 13px;">${l}</p>`).join("") : ""}
      </div>`;
      })
      .join("");

    printWindow.document.write(`
      <html><head><title>${exam.title[locale] || exam.title.en}</title>
      <style>
        body { font-family: sans-serif; padding: 40px; max-width: 800px; margin: auto; }
        .header { text-align: center; margin-bottom: 32px; border-bottom: 2px solid #333; padding-bottom: 16px; }
        .header-logo { max-width: 80px; margin-bottom: 8px; }
        .header h1 { font-size: 20px; margin: 0 0 4px; }
        .header p { margin: 2px 0; font-size: 13px; color: #555; }
        .directions { background: #f5f5f5; padding: 12px 16px; border-radius: 4px; margin-bottom: 24px; font-size: 13px; }
        .directions strong { display: block; margin-bottom: 4px; }
        @media print { @page { margin: 20mm; } body { -webkit-print-color-adjust: exact; } }
      </style></head><body>
      <div class="header">
        ${logoBase64 ? `<img src="${logoBase64}" alt="Logo" class="header-logo" />` : ""}
        <h1>${exam.title[locale] || exam.title.en}</h1>
        <p>Date: ${exam.date} | Venue: ${exam.venue}</p>
        <p>Form: ${FORM_LABEL[exam.form]} | Type: ${TYPE_LABEL[exam.type]} | Time Allowed: ${exam.givenTime ? `${exam.givenTime.days}d ${exam.givenTime.hours}h ${exam.givenTime.minutes}m` : "N/A"}</p>
        <p>Pass Mark: ${exam.cuttingPoint} | Total Questions: ${(exam.questions ?? []).length}</p>
      </div>
      ${exam.direction?.[locale] ? `<div class="directions"><strong>Directions:</strong> ${exam.direction[locale]}</div>` : ""}
      ${qHtml}
      <div style="margin-top: 40px; border-top: 1px solid #ccc; padding-top: 12px; font-size: 12px; color: #888; text-align: center;">
        Generated by EMA — Ethiopian Maritime Authority
      </div>
      </body></html>
    `);
    printWindow.document.close();
    printWindow.focus();
    setTimeout(() => printWindow.print(), 500);
  };

  const totalPoints = (exam.questions ?? []).reduce(
    (s, q) => s + Number(q.points),
    0,
  );
  const certName =
    exam.certification?.name?.[locale] ??
    certifications.find((c) => c.id === exam.certificationId)?.name?.[locale] ??
    "—";

  return (
    <Stack gap="md" ref={printRef}>
      {/* Header */}
      <Group justify="space-between">
        <Group gap="sm">
          <ActionIcon
            variant="subtle"
            size="lg"
            onClick={() => navigate("/exams")}
          >
            <IconArrowLeft size={18} />
          </ActionIcon>
          <div>
            <Title order={3}>{exam.title[locale]}</Title>
          </div>
        </Group>
        <Group gap="sm">
          <Button
            variant="light"
            leftSection={<IconPrinter size={15} />}
            onClick={handlePrint}
            size="sm"
          >
            {t("exam.print")}
          </Button>
          <Button
            leftSection={<IconPlus size={15} />}
            onClick={openRecord}
            size="sm"
          >
            {t("exam.recordResult")}
          </Button>
        </Group>
      </Group>

      {/* Status badge */}
      <Badge
        size="lg"
        variant="light"
        color={STATUS_COLOR[exam.status]}
        style={{ width: "fit-content" }}
      >
        {t(`exam.status.${exam.status}`)}
      </Badge>

      {/* Exam Info */}
      <Paper withBorder radius="lg" p="lg">
        <Title order={5} mb="md">
          {t("exam.detail.title")}
        </Title>
        <SimpleGrid cols={{ base: 2, sm: 4 }} spacing="md">
          <InfoRow label={t("exam.detail.certification")} value={certName} />
          <InfoRow
            label={t("exam.detail.type")}
            value={t(`exam.type.${exam.type}`)}
          />
          <InfoRow
            label={t("exam.detail.form")}
            value={t(`exam.formType.${exam.form}`)}
          />
          <InfoRow label={t("exam.detail.venue")} value={exam.venue} />
          <InfoRow label={t("exam.detail.date")} value={exam.date} />
          <InfoRow
            label={t("exam.detail.administration")}
            value={t(`exam.admin.${exam.administrationMethod}`)}
          />
          <InfoRow
            label={t("exam.detail.evaluation")}
            value={t(`exam.eval.${exam.evaluationMethod}`)}
          />
          <InfoRow
            label={t("exam.detail.selection")}
            value={t(`exam.selection.${exam.selectionMethod}`)}
          />
          <InfoRow
            label={t("exam.detail.timeAllowed")}
            value={
              exam.givenTime
                ? `${exam.givenTime.days}d ${exam.givenTime.hours}h ${exam.givenTime.minutes}m`
                : "—"
            }
          />
          <InfoRow
            label={t("exam.detail.passMark")}
            value={String(exam.cuttingPoint)}
          />
          <InfoRow
            label={t("exam.detail.totalPoints")}
            value={String(totalPoints)}
          />
          <InfoRow
            label={t("exam.detail.questions")}
            value={String((exam.questions ?? []).length)}
          />
        </SimpleGrid>
        {(exam.direction?.en || exam.direction?.am) && (
          <>
            <Divider my="md" />
            <InfoRow
              label={t("exam.detail.directions")}
              value={[exam.direction?.en, exam.direction?.am]
                .filter(Boolean)
                .join(" / ")}
            />
          </>
        )}
      </Paper>

      {/* Questions */}
      <Paper withBorder radius="lg" p="lg">
        <Group justify="space-between" mb="md">
          <Title order={5}>
            {t("exam.detail.questionsSection", { pts: totalPoints })}
          </Title>
          <Button
            variant="light"
            size="xs"
            leftSection={<IconPlus size={14} />}
            onClick={openAssignModal}
          >
            {t("exam.manageQuestions")}
          </Button>
        </Group>
        {(exam.questions ?? []).length === 0 ? (
          <Alert color="gray" icon={<IconInfoCircle size={16} />}>
            {t("exam.noQuestionsAssigned")}
          </Alert>
        ) : (
          <Stack gap="md">
            {(exam.questions ?? []).map((q, i) => (
              <Paper key={q.id} withBorder p="md" radius="md">
                <Group justify="space-between" mb="xs">
                  <Text fz="sm" fw={700}>
                    {t("exam.detail.questionLabel")} {i + 1}
                  </Text>
                  <Group gap={4}>
                    <Badge
                      size="xs"
                      variant="light"
                      color={q.form === "ESSAY" ? "blue" : "violet"}
                    >
                      {t(`exam.formType.${q.form}`)}
                    </Badge>
                    <Badge size="xs" variant="light" color="gray">
                      {q.points} pts
                    </Badge>
                  </Group>
                </Group>
                <Text fz="sm">{q.title[locale]}</Text>
              </Paper>
            ))}
          </Stack>
        )}
      </Paper>

      <RecordResultModal
        exam={exam}
        opened={recordOpened}
        onClose={closeRecord}
      />

      {/* Question assignment modal */}
      <Modal
        opened={assignOpened}
        onClose={closeAssign}
        title={`${t("exam.manageQuestions")} — ${exam.title[locale]}`}
        size="xl"
        radius="lg"
      >
        <Stack gap="md">
          {exam.selectionMethod === "MANUAL" ? (
            <>
              <QuestionAssigner
                available={eligibleQuestions}
                assigned={draftQuestions}
                onChange={setDraftQuestions}
                mode="manual"
                actions={setWhatAction}
              />
              <Group justify="flex-end">
                <Button variant="default" onClick={closeAssign} size="sm">
                  {t("exam.cancel")}
                </Button>
                <Button onClick={handleAssign} size="sm" loading={isAssigning}>
                  {t("exam.saveAssignments")}
                </Button>
              </Group>
            </>
          ) : (
            <>
              <Text fz="sm" c="dimmed">
                {t("exam.assigner.randomHint", {
                  total: eligibleQuestions.length,
                  pts: exam.cuttingPoint,
                })}
              </Text>
              <Group gap="sm">
                <NumberInput
                  placeholder={t("exam.assigner.selectCount")}
                  value={randomCount}
                  onChange={(v) => setRandomCount(Number(v))}
                  min={1}
                  max={eligibleQuestions.length}
                  size="xs"
                  style={{ width: 80 }}
                />
                <Button size="xs" variant="light" onClick={handleRandomSelect}>
                  {t("exam.randomSelect")}
                </Button>
              </Group>
              <QuestionAssigner
                available={eligibleQuestions}
                assigned={draftQuestions}
                onChange={setDraftQuestions}
                mode="random"
              />
              <Group justify="flex-end">
                <Button variant="default" onClick={closeAssign} size="sm">
                  {t("exam.cancel")}
                </Button>
                <Button onClick={handleAssign} size="sm" loading={isAssigning}>
                  {t("exam.saveAssignments")}
                </Button>
              </Group>
            </>
          )}
        </Stack>
      </Modal>
    </Stack>
  );
}
