import { useCallback, useState } from "react";
import {
  Alert,
  Button,
  Group,
  Modal,
  NumberInput,
  Select,
  Stack,
  Text,
  TextInput,
  Title,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { useDisclosure } from "@mantine/hooks";
import { IconInfoCircle, IconPlus } from "@tabler/icons-react";
import { useTranslation } from "react-i18next";
import {
  AdvancedTable,
  ModalFooter,
  notify,
  PageLoader,
  useErrorHandler,
  type AdvancedColumn,
} from "@ema-platform/ui";
import {
  useLocalized,
  useGetDepartmentsQuery,
  useCreateDepartmentMutation,
  useUpdateDepartmentMutation,
  useDeleteDepartmentMutation,
  useGetRanksQuery,
  useCreateRankMutation,
  useUpdateRankMutation,
  useDeleteRankMutation,
  type Department,
  type Rank,
  type RankCertificateCategory,
} from "@ema-platform/api";

const CATEGORY_OPTIONS: { value: RankCertificateCategory; label: string }[] = [
  { value: "COC", label: "CoC" },
  { value: "COP", label: "CoP" },
];

/**
 * Departments and their CoC/CoP rank ladders, as backoffice-editable config.
 *
 * Both used to be hardcoded (`ESeafarerDepartment` and the `COC_LADDERS`/
 * `COP_LADDERS` arrays) — this is the write side that config never had. A
 * rank's `ladderOrder` is the rung position `resolveNextRank` climbs, so
 * reordering here changes what an applicant is auto-advanced to next.
 */
export function RankDepartmentTab() {
  const { t } = useTranslation();
  const localized = useLocalized();

  const { data: deptRes, isLoading: deptLoading, isFetching: deptFetching, refetch: refetchDepts } =
    useGetDepartmentsQuery();
  const { data: rankRes, isLoading: rankLoading, isFetching: rankFetching, refetch: refetchRanks } =
    useGetRanksQuery();

  const departments = deptRes?.items ?? [];
  const ranks = rankRes?.items ?? [];

  const deptOptions = departments.map((d) => ({ value: d.id, label: localized(d.name) }));
  const deptName = useCallback(
    (id: string) => departments.find((d) => d.id === id)?.code ?? "-",
    [departments],
  );

  if (deptLoading || rankLoading) {
    return <PageLoader label={t("configuration.loadingRanks", "Loading departments and ranks…")} height={300} />;
  }

  return (
    <Stack gap="xl">
      <Alert variant="light" color="blue" icon={<IconInfoCircle size={16} />}>
        <Text size="sm">
          {t(
            "configuration.rankLadderNotice",
            "A rank's position is its rung on the ladder — an applicant is auto-advanced to the next position up from what they already hold.",
          )}
        </Text>
      </Alert>

      <DepartmentSection
        departments={departments}
        isFetching={deptFetching}
        refetch={refetchDepts}
        localized={localized}
      />

      <RankSection
        ranks={ranks}
        deptOptions={deptOptions}
        deptName={deptName}
        isFetching={rankFetching}
        refetch={refetchRanks}
        localized={localized}
      />
    </Stack>
  );
}

// ------------------------------------------------------------- departments

function DepartmentSection({
  departments,
  isFetching,
  refetch,
  localized,
}: {
  departments: Department[];
  isFetching: boolean;
  refetch: () => void;
  localized: (v: Department["name"]) => string;
}) {
  const { t } = useTranslation();
  const { handleError } = useErrorHandler();
  const [createDepartment, { isLoading: isCreating }] = useCreateDepartmentMutation();
  const [updateDepartment, { isLoading: isUpdating }] = useUpdateDepartmentMutation();
  const [deleteDepartment] = useDeleteDepartmentMutation();

  const [editing, setEditing] = useState<Department | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Department | null>(null);
  const [deleteOpened, { open: openDelete, close: closeDelete }] = useDisclosure(false);

  const resetForm = useCallback(() => {
    setEditing(null);
    setShowForm(false);
  }, []);

  const form = useForm({
    initialValues: { code: "", nameEn: "", nameAm: "", sortOrder: 0 },
    validate: {
      code: (v) => (!v ? t("configuration.validation.codeRequired", "Code is required") : null),
      nameEn: (v) => (!v ? t("configuration.validation.nameEnRequired") : null),
      nameAm: (v) => (!v ? t("configuration.validation.nameAmRequired") : null),
    },
  });

  const openEdit = useCallback(
    (dept: Department) => {
      setEditing(dept);
      form.setValues({
        code: dept.code,
        nameEn: dept.name.en ?? "",
        nameAm: dept.name.am ?? "",
        sortOrder: dept.sortOrder,
      });
      setShowForm(true);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [],
  );

  const handleSubmit = form.onSubmit(async (values) => {
    const name = { en: values.nameEn, am: values.nameAm };
    try {
      if (editing) {
        await updateDepartment({
          id: editing.id,
          code: values.code,
          name,
          sortOrder: values.sortOrder,
        }).unwrap();
        notify.success(t("configuration.updated"));
      } else {
        await createDepartment({ code: values.code, name, sortOrder: values.sortOrder }).unwrap();
        notify.success(t("configuration.created"));
      }
      resetForm();
      form.reset();
    } catch (e) {
      handleError(e);
    }
  });

  const confirmDelete = useCallback(async () => {
    if (!deleteTarget) return;
    try {
      await deleteDepartment(deleteTarget.id).unwrap();
      notify.success(t("configuration.deleted"));
      closeDelete();
      setDeleteTarget(null);
    } catch (e) {
      handleError(e);
    }
  }, [deleteTarget, deleteDepartment, closeDelete, handleError]);

  const columns: AdvancedColumn<Department>[] = [
    { header: t("configuration.code", "Code"), cell: ({ row }) => row.original.code },
    { header: t("configuration.name"), cell: ({ row }) => localized(row.original.name) },
    { header: t("configuration.sortOrder", "Order"), cell: ({ row }) => row.original.sortOrder },
    {
      header: "actions",
      size: 90,
      cell: ({ row }) => (
        <Group gap="xs">
          <Button variant="subtle" size="xs" onClick={() => openEdit(row.original)}>
            {t("configuration.edit", "Edit")}
          </Button>
          <Button
            variant="subtle"
            color="red"
            size="xs"
            onClick={() => {
              setDeleteTarget(row.original);
              openDelete();
            }}
          >
            {t("configuration.delete")}
          </Button>
        </Group>
      ),
    },
  ];

  return (
    <Stack gap="sm">
      <Group justify="space-between" align="flex-end">
        <Title order={4}>{t("configuration.departments", "Departments")}</Title>
        {!showForm && (
          <Button
            variant="light"
            size="sm"
            leftSection={<IconPlus size={16} />}
            onClick={() => {
              form.reset();
              setShowForm(true);
            }}
          >
            {t("configuration.addDepartment", "Add department")}
          </Button>
        )}
      </Group>

      <AdvancedTable
        columns={columns}
        data={[...departments].sort((a, b) => a.sortOrder - b.sortOrder)}
        tableName={t("configuration.departments", "Departments")}
        itemCount={departments.length}
        pageIndex={0}
        onPageChange={() => {}}
        pageSize={departments.length || 10}
        onPageSizeChange={() => {}}
        refresh={refetch}
        isLoading={isFetching}
      />

      <Modal
        opened={showForm}
        onClose={resetForm}
        title={editing ? t("configuration.update") : t("configuration.addDepartment", "Add department")}
        size="sm"
      >
        <form onSubmit={handleSubmit}>
          <Stack gap="sm">
            <TextInput
              label={t("configuration.code", "Code")}
              placeholder="DECK"
              {...form.getInputProps("code")}
              size="sm"
            />
            <TextInput label={t("configuration.nameEn")} {...form.getInputProps("nameEn")} size="sm" />
            <TextInput label={t("configuration.nameAm")} {...form.getInputProps("nameAm")} size="sm" />
            <NumberInput
              label={t("configuration.sortOrder", "Sort order")}
              {...form.getInputProps("sortOrder")}
              size="sm"
            />
            <ModalFooter>
              <Button variant="default" onClick={resetForm} size="sm">
                {t("configuration.cancel")}
              </Button>
              <Button type="submit" size="sm" loading={isCreating || isUpdating}>
                {editing ? t("configuration.update") : t("configuration.create")}
              </Button>
            </ModalFooter>
          </Stack>
        </form>
      </Modal>

      <Modal opened={deleteOpened} onClose={closeDelete} title={t("configuration.confirmDelete")} size="sm">
        <Text mb="md">
          {t("configuration.deleteConfirmText", { name: deleteTarget ? localized(deleteTarget.name) : "" })}
        </Text>
        <ModalFooter>
          <Button variant="default" onClick={closeDelete} size="sm">
            {t("configuration.cancel")}
          </Button>
          <Button color="red" onClick={confirmDelete} size="sm">
            {t("configuration.delete")}
          </Button>
        </ModalFooter>
      </Modal>
    </Stack>
  );
}

// ------------------------------------------------------------------ ranks

function RankSection({
  ranks,
  deptOptions,
  deptName,
  isFetching,
  refetch,
  localized,
}: {
  ranks: Rank[];
  deptOptions: { value: string; label: string }[];
  deptName: (id: string) => string;
  isFetching: boolean;
  refetch: () => void;
  localized: (v: Rank["name"]) => string;
}) {
  const { t } = useTranslation();
  const { handleError } = useErrorHandler();
  const [createRank, { isLoading: isCreating }] = useCreateRankMutation();
  const [updateRank, { isLoading: isUpdating }] = useUpdateRankMutation();
  const [deleteRank] = useDeleteRankMutation();

  const [editing, setEditing] = useState<Rank | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Rank | null>(null);
  const [deleteOpened, { open: openDelete, close: closeDelete }] = useDisclosure(false);

  const resetForm = useCallback(() => {
    setEditing(null);
    setShowForm(false);
  }, []);

  const form = useForm({
    initialValues: {
      departmentId: "",
      certificateCategory: "COC" as RankCertificateCategory,
      key: "",
      nameEn: "",
      nameAm: "",
      ladderOrder: 0,
    },
    validate: {
      departmentId: (v) => (!v ? t("configuration.validation.departmentRequired") : null),
      key: (v) => (!v ? t("configuration.validation.keyRequired", "Key is required") : null),
      nameEn: (v) => (!v ? t("configuration.validation.nameEnRequired") : null),
      nameAm: (v) => (!v ? t("configuration.validation.nameAmRequired") : null),
    },
  });

  const openEdit = useCallback(
    (rank: Rank) => {
      setEditing(rank);
      form.setValues({
        departmentId: rank.departmentId,
        certificateCategory: rank.certificateCategory,
        key: rank.key,
        nameEn: rank.name.en ?? "",
        nameAm: rank.name.am ?? "",
        ladderOrder: rank.ladderOrder,
      });
      setShowForm(true);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [],
  );

  const handleSubmit = form.onSubmit(async (values) => {
    const name = { en: values.nameEn, am: values.nameAm };
    try {
      if (editing) {
        await updateRank({
          id: editing.id,
          departmentId: values.departmentId,
          certificateCategory: values.certificateCategory,
          key: values.key,
          name,
          ladderOrder: values.ladderOrder,
        }).unwrap();
        notify.success(t("configuration.updated"));
      } else {
        await createRank({
          departmentId: values.departmentId,
          certificateCategory: values.certificateCategory,
          key: values.key,
          name,
          ladderOrder: values.ladderOrder,
        }).unwrap();
        notify.success(t("configuration.created"));
      }
      resetForm();
      form.reset();
    } catch (e) {
      handleError(e);
    }
  });

  const confirmDelete = useCallback(async () => {
    if (!deleteTarget) return;
    try {
      await deleteRank(deleteTarget.id).unwrap();
      notify.success(t("configuration.deleted"));
      closeDelete();
      setDeleteTarget(null);
    } catch (e) {
      handleError(e);
    }
  }, [deleteTarget, deleteRank, closeDelete, handleError]);

  const sortedRanks = [...ranks].sort(
    (a, b) =>
      a.departmentId.localeCompare(b.departmentId) ||
      a.certificateCategory.localeCompare(b.certificateCategory) ||
      a.ladderOrder - b.ladderOrder,
  );

  const columns: AdvancedColumn<Rank>[] = [
    { header: t("configuration.department"), cell: ({ row }) => deptName(row.original.departmentId) },
    { header: t("configuration.category", "Ladder"), cell: ({ row }) => row.original.certificateCategory },
    { header: t("configuration.rankOrder", "Rung"), cell: ({ row }) => row.original.ladderOrder },
    { header: t("configuration.key", "Key"), cell: ({ row }) => row.original.key },
    { header: t("configuration.name"), cell: ({ row }) => localized(row.original.name) },
    {
      header: "actions",
      size: 90,
      cell: ({ row }) => (
        <Group gap="xs">
          <Button variant="subtle" size="xs" onClick={() => openEdit(row.original)}>
            {t("configuration.edit", "Edit")}
          </Button>
          <Button
            variant="subtle"
            color="red"
            size="xs"
            onClick={() => {
              setDeleteTarget(row.original);
              openDelete();
            }}
          >
            {t("configuration.delete")}
          </Button>
        </Group>
      ),
    },
  ];

  return (
    <Stack gap="sm">
      <Group justify="space-between" align="flex-end">
        <Title order={4}>{t("configuration.ranks", "Ranks")}</Title>
        {!showForm && (
          <Button
            variant="light"
            size="sm"
            leftSection={<IconPlus size={16} />}
            onClick={() => {
              form.reset();
              setShowForm(true);
            }}
            disabled={deptOptions.length === 0}
          >
            {t("configuration.addRank", "Add rank")}
          </Button>
        )}
      </Group>

      <AdvancedTable
        columns={columns}
        data={sortedRanks}
        tableName={t("configuration.ranks", "Ranks")}
        itemCount={sortedRanks.length}
        pageIndex={0}
        onPageChange={() => {}}
        pageSize={sortedRanks.length || 10}
        onPageSizeChange={() => {}}
        refresh={refetch}
        isLoading={isFetching}
      />

      <Modal
        opened={showForm}
        onClose={resetForm}
        title={editing ? t("configuration.update") : t("configuration.addRank", "Add rank")}
        size="sm"
      >
        <form onSubmit={handleSubmit}>
          <Stack gap="sm">
            <Select
              label={t("configuration.department")}
              data={deptOptions}
              {...form.getInputProps("departmentId")}
              size="sm"
              searchable
            />
            <Select
              label={t("configuration.category", "Ladder")}
              data={CATEGORY_OPTIONS}
              {...form.getInputProps("certificateCategory")}
              size="sm"
              allowDeselect={false}
            />
            <TextInput
              label={t("configuration.key", "Key")}
              placeholder="CHIEF_MATE"
              {...form.getInputProps("key")}
              size="sm"
              disabled={!!editing}
              description={
                editing
                  ? t(
                      "configuration.keyLockedNotice",
                      "Not editable — issued licences already carry this key.",
                    )
                  : undefined
              }
            />
            <TextInput label={t("configuration.nameEn")} {...form.getInputProps("nameEn")} size="sm" />
            <TextInput label={t("configuration.nameAm")} {...form.getInputProps("nameAm")} size="sm" />
            <NumberInput
              label={t("configuration.rankOrder", "Rung (0 = entry rank)")}
              min={0}
              {...form.getInputProps("ladderOrder")}
              size="sm"
            />
            <ModalFooter>
              <Button variant="default" onClick={resetForm} size="sm">
                {t("configuration.cancel")}
              </Button>
              <Button type="submit" size="sm" loading={isCreating || isUpdating}>
                {editing ? t("configuration.update") : t("configuration.create")}
              </Button>
            </ModalFooter>
          </Stack>
        </form>
      </Modal>

      <Modal opened={deleteOpened} onClose={closeDelete} title={t("configuration.confirmDelete")} size="sm">
        <Text mb="md">
          {t("configuration.deleteConfirmText", { name: deleteTarget ? localized(deleteTarget.name) : "" })}
        </Text>
        <ModalFooter>
          <Button variant="default" onClick={closeDelete} size="sm">
            {t("configuration.cancel")}
          </Button>
          <Button color="red" onClick={confirmDelete} size="sm">
            {t("configuration.delete")}
          </Button>
        </ModalFooter>
      </Modal>
    </Stack>
  );
}
