import { useState } from "react";
import { useNavigate } from "react-router-dom";
import {
  Stack,
  Group,
  Button,
  Modal,
  Text,
  TextInput,
  Textarea,
  Card,
  Select,
  NumberInput,
  Tabs,
  SimpleGrid,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { useTranslation } from "react-i18next";
import {
  IconPlus,
  IconInfoCircle,
  IconClipboardList,
} from "@tabler/icons-react";
import { notify, useErrorHandler, AdvancedTable, useServerTable, ModalFooter, AmharicDatePicker } from "@ema-platform/ui";
import { LICENSE_PERMISSIONS, RequirePermission } from "@ema-platform/auth";
import { useGetCertificationsQuery } from "../../../certification/api/certification-api";
import { RANK_KEY_OPTIONS } from "../../../certification/types/certification";
import {
  useGetExamsQuery,
  useCreateExamMutation,
  useUpdateExamMutation,
  useDeleteExamMutation,
} from "../../api/exam-api";
import type { Exam } from "../../types/exam";
import { examColumns } from "./columns";
import { examActionsColumn } from "./actions";
import { ErrorState, PageHeader } from '@ema-platform/ui';

function ExamForm({
  editing,
  certOptions,
  isSubmitting,
  onSubmit,
  onCancel,
}: {
  editing: Exam | null;
  certOptions: { value: string; label: string }[];
  isSubmitting: boolean;
  onSubmit: (values: any, isEdit: boolean) => void;
  onCancel: () => void;
}) {
  const { t } = useTranslation();
  const [certificationId, setCertificationId] = useState<string | null>(
    editing?.certificationId ?? null,
  );
  const [titleEn, setTitleEn] = useState(editing?.title?.en ?? "");
  const [titleAm, setTitleAm] = useState(editing?.title?.am ?? "");
  const [directionEn, setDirectionEn] = useState(editing?.direction?.en ?? "");
  const [directionAm, setDirectionAm] = useState(editing?.direction?.am ?? "");
  const [date, setDate] = useState(editing?.date ?? "");
  const [days, setDays] = useState(editing?.givenTime?.days ?? 0);
  const [hours, setHours] = useState(editing?.givenTime?.hours ?? 0);
  const [minutes, setMinutes] = useState(editing?.givenTime?.minutes ?? 0);
  const [type, setType] = useState<string | null>(editing?.type ?? null);
  const [form, setForm] = useState<string | null>(editing?.form ?? null);
  const [venue, setVenue] = useState(editing?.venue ?? "");
  const [adminMethod, setAdminMethod] = useState<string | null>(
    editing?.administrationMethod ?? null,
  );
  const [evalMethod, setEvalMethod] = useState<string | null>(
    editing?.evaluationMethod ?? null,
  );
  const [selMethod, setSelMethod] = useState<string | null>(
    editing?.selectionMethod ?? null,
  );
  const [cuttingPoint, setCuttingPoint] = useState<number>(
    editing?.cuttingPoint ?? 0,
  );
  const [status, setStatus] = useState<string | null>(editing?.status ?? null);
  const [activeTab, setActiveTab] = useState<string | null>("basic");

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!certificationId || !titleEn || !titleAm || !date || !venue) {
      setActiveTab("basic");
      notify.error(t("exam.form.fillRequiredBasic"));
      return;
    }
    if ((directionEn || directionAm) && !(directionEn && directionAm)) {
      setActiveTab("basic");
      notify.error(t("exam.form.directionBothLanguages"));
      return;
    }
    if (!type || !form || !adminMethod || !evalMethod || !cuttingPoint) {
      setActiveTab("settings");
      notify.error(t("exam.form.fillRequiredSettings"));
      return;
    }
    onSubmit(
      {
        certificationId,
        titleEn,
        titleAm,
        directionEn,
        directionAm,
        date,
        days,
        hours,
        minutes,
        type,
        form,
        venue,
        adminMethod,
        evalMethod,
        selMethod,
        cuttingPoint,
        status,
      },
      !!editing,
    );
  };

  return (
    <Modal opened onClose={onCancel} title={editing ? t("exam.update") : t("exam.add")} size="xl">
      <form onSubmit={handleSubmit}>
        <Tabs value={activeTab} onChange={setActiveTab} variant="outline" radius="md">
          <Tabs.List mb="md">
            <Tabs.Tab value="basic" leftSection={<IconInfoCircle size={15} />}>
              {t("exam.form.basicInfo")}
            </Tabs.Tab>
            <Tabs.Tab
              value="settings"
              leftSection={<IconClipboardList size={15} />}
            >
              {t("exam.form.settings")}
            </Tabs.Tab>
          </Tabs.List>

          <Tabs.Panel value="basic">
            <Stack gap="sm">
              <Select
                label={t("exam.form.certification")}
                placeholder={t("exam.form.selectCertification")}
                data={certOptions}
                value={certificationId}
                onChange={setCertificationId}
                size="sm"
                searchable
                required
              />
              <TextInput
                label={t("exam.form.titleEn")}
                placeholder={t("exam.form.titleEnPlaceholder")}
                value={titleEn}
                onChange={(e) => setTitleEn(e.currentTarget.value)}
                size="sm"
                required
              />
              <TextInput
                label={t("exam.form.titleAm")}
                placeholder={t("exam.form.titleAmPlaceholder")}
                value={titleAm}
                onChange={(e) => setTitleAm(e.currentTarget.value)}
                size="sm"
                required
              />
              <Textarea
                label={t("exam.form.directionEn")}
                placeholder={t("exam.form.directionEnPlaceholder")}
                value={directionEn}
                onChange={(e) => setDirectionEn(e.currentTarget.value)}
                size="sm"
                autosize
                minRows={2}
              />
              <Textarea
                label={t("exam.form.directionAm")}
                placeholder={t("exam.form.directionAmPlaceholder")}
                value={directionAm}
                onChange={(e) => setDirectionAm(e.currentTarget.value)}
                size="sm"
                autosize
                minRows={2}
              />
              <AmharicDatePicker
                label={t("exam.form.examDate")}
                value={date}
                onChange={setDate}
                dateFormat="date"
                size="sm"
                required
              />
              <TextInput
                label={t("exam.form.venue")}
                placeholder={t("exam.form.venuePlaceholder")}
                value={venue}
                onChange={(e) => setVenue(e.currentTarget.value)}
                size="sm"
                required
              />

              <Text fz="sm" fw={500}>
                {t("exam.form.timeAllowed")}
              </Text>
              <Group gap="sm" grow>
                <NumberInput
                  label={t("exam.form.days")}
                  value={days}
                  onChange={(v) => setDays(Number(v))}
                  min={0}
                  size="sm"
                />
                <NumberInput
                  label={t("exam.form.hours")}
                  value={hours}
                  onChange={(v) => setHours(Number(v))}
                  min={0}
                  size="sm"
                />
                <NumberInput
                  label={t("exam.form.minutes")}
                  value={minutes}
                  onChange={(v) => setMinutes(Number(v))}
                  min={0}
                  size="sm"
                />
              </Group>
            </Stack>
          </Tabs.Panel>

          <Tabs.Panel value="settings">
            <Stack gap="sm">
              <SimpleGrid cols={2} spacing="sm">
                <Select
                  label={t("exam.columns.type")}
                  placeholder="Written or Oral"
                  data={[
                    { value: "WRITTEN", label: t("exam.form.written") },
                    { value: "ORAL", label: t("exam.form.oral") },
                  ]}
                  value={type}
                  onChange={setType}
                  size="sm"
                  required
                />
                <Select
                  label={t("exam.columns.form")}
                  placeholder="Essay or Choice"
                  data={[
                    { value: "ESSAY", label: t("exam.form.essay") },
                    { value: "CHOICE", label: t("exam.form.choice") },
                    { value: "BOTH", label: t("exam.form.both") },
                  ]}
                  value={form}
                  onChange={setForm}
                  size="sm"
                  required
                  disabled={adminMethod === "ONLINE"}
                  description={
                    adminMethod === "ONLINE"
                      ? t("exam.form.onlineChoiceOnlyHint")
                      : undefined
                  }
                />
                <Select
                  label={t("exam.detail.administration")}
                  placeholder="Offline or Online"
                  data={[
                    { value: "OFFLINE", label: t("exam.form.offline") },
                    { value: "ONLINE", label: t("exam.form.online") },
                  ]}
                  value={adminMethod}
                  onChange={(value) => {
                    setAdminMethod(value);
                    // Online exams are graded automatically, and that only
                    // has an answer model for CHOICE — matches the backend
                    // rule (online_exam_requires_choice_form), not just a
                    // UI nicety.
                    if (value === "ONLINE") setForm("CHOICE");
                  }}
                  size="sm"
                  required
                />
                <Select
                  label={t("exam.detail.evaluation")}
                  placeholder="How to compute score"
                  data={[
                    { value: "SUM", label: t("exam.form.sum") },
                    { value: "AVERAGE", label: t("exam.form.average") },
                    { value: "PERCENTAGE", label: t("exam.form.percentage") },
                  ]}
                  value={evalMethod}
                  onChange={setEvalMethod}
                  size="sm"
                  required
                />
                <Select
                  label={t("exam.detail.selection")}
                  placeholder="Manual or Random"
                  data={[
                    { value: "MANUAL", label: t("exam.form.manual") },
                    { value: "RANDOM", label: t("exam.form.random") },
                  ]}
                  value={selMethod}
                  onChange={setSelMethod}
                  size="sm"
                />
                <NumberInput
                  label={t("exam.form.cuttingPoint")}
                  placeholder={
                    evalMethod === "PERCENTAGE"
                      ? t("exam.form.cuttingPointPercentagePlaceholder")
                      : t("exam.form.cuttingPointPlaceholder")
                  }
                  value={cuttingPoint}
                  onChange={(v) => setCuttingPoint(Number(v))}
                  min={0}
                  max={evalMethod === "PERCENTAGE" ? 100 : undefined}
                  size="sm"
                  withAsterisk
                  description={
                    evalMethod === "PERCENTAGE"
                      ? t("exam.form.cuttingPointPercentageHint")
                      : undefined
                  }
                />
              </SimpleGrid>
              {editing && (
                <Select
                  label={t("exam.form.status")}
                  placeholder={t("exam.form.statusPlaceholder")}
                  data={[
                    { value: "PENDING", label: t("exam.form.pending") },
                    { value: "ACTIVE", label: t("exam.form.active") },
                    { value: "COMPLETED", label: t("exam.form.completed") },
                    { value: "CANCELLED", label: t("exam.form.cancelled") },
                    { value: "POSTPONED", label: t("exam.form.postponed") },
                    { value: "PUBLISHED", label: t("exam.form.published") },
                  ]}
                  value={status}
                  onChange={setStatus}
                  size="sm"
                />
              )}
            </Stack>
          </Tabs.Panel>
        </Tabs>

        <ModalFooter mt="md">
          <Button variant="default" onClick={onCancel} size="sm">
            {t("exam.cancel")}
          </Button>
          <Button type="submit" size="sm" loading={isSubmitting}>
            {editing ? t("exam.update") : t("exam.create")}
          </Button>
        </ModalFooter>
      </form>
    </Modal>
  );
}

export function ExamPage() {
  const navigate = useNavigate();
  const { t, i18n } = useTranslation();
  const { handleError } = useErrorHandler();
  const locale = i18n.language as "en" | "am";
  const { data: certRes } = useGetCertificationsQuery();
  const { data, isFetching, isError, refetch } = useGetExamsQuery();
  const { setPageIndex, pageSize, setPageSize, paginate } = useServerTable();
  const [createExam, { isLoading: isCreating }] = useCreateExamMutation();
  const [updateExam, { isLoading: isUpdating }] = useUpdateExamMutation();
  const [deleteExam] = useDeleteExamMutation();

  const certifications = certRes?.items ?? [];
  const exams = data?.items ?? [];

  const [editing, setEditing] = useState<Exam | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Exam | null>(null);
  const [deleteOpened, { open: openDelete, close: closeDelete }] =
    useDisclosure(false);
  const [changingStatusId, setChangingStatusId] = useState<string | null>(null);
  const [statusTarget, setStatusTarget] = useState<Exam | null>(null);
  const [pendingStatus, setPendingStatus] = useState<Exam["status"] | null>(null);
  const [statusOpened, { open: openStatus, close: closeStatus }] =
    useDisclosure(false);

  // Rank in the label: an exam inherits its STCW rank from the certification
  // it is created under (Certification.rankKey), so the officer sees which
  // rank a sitting will serve at the moment they pick the subject.
  const certOptions = certifications
    .filter((c) => c.isActive)
    .map((c) => {
      const rank = RANK_KEY_OPTIONS.find((r) => r.value === c.rankKey)?.label;
      return {
        value: c.id,
        label: rank ? `${c.name[locale]} — ${rank}` : c.name[locale],
      };
    });
  const getCertName = (id: string) =>
    certifications.find((c) => c.id === id)?.name?.[locale] ?? "-";

  const resetForm = () => {
    setEditing(null);
    setShowForm(false);
  };

  const handleSubmit = async (values: any, isEdit: boolean) => {
    const payload: any = {
      certificationId: values.certificationId,
      title: { en: values.titleEn, am: values.titleAm },
      direction:
        values.directionEn || values.directionAm
          ? { en: values.directionEn, am: values.directionAm }
          : undefined,
      date: values.date,
      givenTime: {
        days: values.days,
        hours: values.hours,
        minutes: values.minutes,
      },
      type: values.type,
      form: values.form,
      venue: values.venue,
      administrationMethod: values.adminMethod,
      evaluationMethod: values.evalMethod,
      selectionMethod: values.selMethod || "MANUAL",
      cuttingPoint: values.cuttingPoint,
    };
    if (isEdit) payload.status = values.status;

    try {
      if (isEdit && editing) {
        await updateExam({ id: editing.id, ...payload }).unwrap();
        notify.success(t("exam.updated"));
      } else {
        await createExam(payload).unwrap();
        notify.success(t("exam.created"));
      }
      resetForm();
    } catch (e) {
      handleError(e);
    }
  };

  const handleChangeStatus = async () => {
    if (!statusTarget || !pendingStatus) return;
    setChangingStatusId(statusTarget.id);
    try {
      await updateExam({ id: statusTarget.id, status: pendingStatus }).unwrap();
      notify.success(t("exam.updated"));
      closeStatus();
      setStatusTarget(null);
    } catch (e) {
      handleError(e);
    } finally {
      setChangingStatusId(null);
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      await deleteExam(deleteTarget.id).unwrap();
      notify.success(t("exam.deleted"));
      closeDelete();
      setDeleteTarget(null);
    } catch (e) {
      handleError(e);
    }
  };

  if (isError)
    return <ErrorState title={t("exam.loadError")} onRetry={refetch} />;

  const columns = [
    ...examColumns(t, locale, getCertName, (exam) => navigate(`/exams/${exam.id}`)),
    examActionsColumn(t, {
      onEdit: (exam) => {
        setEditing(exam);
        setShowForm(true);
      },
      onDelete: (exam) => {
        setDeleteTarget(exam);
        openDelete();
      },
      onDetails: (exam) => navigate(`/exams/${exam.id}`),
      onOpenStatusChange: (exam) => {
        setStatusTarget(exam);
        setPendingStatus(exam.status);
        openStatus();
      },
      changingStatusId,
    }),
  ];

  const page = paginate(exams);

  return (
    <Stack gap="lg">
      <PageHeader
        title={t("exam.title")}
        subtitle={t("exam.subtitle")}
        noMargin
        action={
          !showForm && (
            <RequirePermission anyOf={[LICENSE_PERMISSIONS.MANAGE_EXAMS]} hideOnly>
              <Button
                variant="light"
                leftSection={<IconPlus size={16} />}
                onClick={() => setShowForm(true)}
                size="sm"
              >
                {t("exam.add")}
              </Button>
            </RequirePermission>
          )
        }
      />

      {showForm && (
        <ExamForm
          editing={editing}
          certOptions={certOptions}
          isSubmitting={isCreating || isUpdating}
          onSubmit={handleSubmit}
          onCancel={resetForm}
        />
      )}

      <Card withBorder padding={0}>
        <AdvancedTable
          columns={columns}
          data={page.rows}
          tableName={t("exam.title")}
          itemCount={page.itemCount}
          pageIndex={page.pageIndex}
          onPageChange={setPageIndex}
          pageSize={pageSize}
          onPageSizeChange={setPageSize}
          refresh={refetch}
          isLoading={isFetching}
          emptyText={t("exam.noItems")}
        />
      </Card>

      {/* Delete confirmation */}
      <Modal
        opened={deleteOpened}
        onClose={closeDelete}
        title={t("exam.confirmDelete")}
        size="sm"
      >
        <Text mb="md">
          {t("exam.deleteConfirmText", {
            name: deleteTarget?.title?.[locale] ?? "",
          })}
        </Text>
        <ModalFooter>
          <Button variant="default" onClick={closeDelete} size="sm">
            {t("exam.cancel")}
          </Button>
          <Button color="red" onClick={handleDelete} size="sm">
            {t("exam.delete")}
          </Button>
        </ModalFooter>
      </Modal>

      {/* Quick status change — not the full edit form */}
      <Modal
        opened={statusOpened}
        onClose={closeStatus}
        title={t("exam.form.status")}
        size="sm"
      >
        <Stack gap="md">
          <Text fz="sm" c="dimmed">
            {statusTarget?.title?.[locale]}
          </Text>
          <Select
            label={t("exam.form.status")}
            data={[
              { value: "PENDING", label: t("exam.form.pending") },
              { value: "ACTIVE", label: t("exam.form.active") },
              { value: "COMPLETED", label: t("exam.form.completed") },
              { value: "CANCELLED", label: t("exam.form.cancelled") },
              { value: "POSTPONED", label: t("exam.form.postponed") },
              { value: "PUBLISHED", label: t("exam.form.published") },
            ]}
            value={pendingStatus}
            onChange={(value) => setPendingStatus(value as Exam["status"])}
            size="sm"
          />
          <ModalFooter>
            <Button variant="default" onClick={closeStatus} size="sm">
              {t("exam.cancel")}
            </Button>
            <Button
              onClick={handleChangeStatus}
              size="sm"
              loading={changingStatusId === statusTarget?.id}
              disabled={pendingStatus === statusTarget?.status}
            >
              {t("exam.update")}
            </Button>
          </ModalFooter>
        </Stack>
      </Modal>
    </Stack>
  );
}
