"use client";

import { useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useFeedbackModal } from "@/app/components/providers/feedback-modal-provider";
import { useLoadingModal } from "@/app/components/providers/loading-modal-provider";
import { fetchBranches, type Branch } from "@/lib/api/branches";
import type { Printer } from "@/lib/api/printers";
import { fetchStands, type Stand } from "@/lib/api/stands";
import { getErrorMessage } from "@/lib/api/types";
import { queryKeys } from "@/lib/query/query-keys";
import {
  useCreatePrinter,
  useDeletePrinter,
  usePrinters,
  useUpdatePrinter,
  type PrinterFormData,
} from "@/lib/query/hooks/printers";
import { useClientPagination } from "@/lib/hooks/use-client-pagination";
import { DataPagination } from "../ui/data-pagination";
import { DataTableSection } from "../ui/data-table-section";
import { PageEnter, PageTextEnter } from "../ui/page-enter";
import { IconButton } from "../ui/button";
import { IconAdd } from "../ui/icons";
import { PrinterFormModal } from "./printer-form-modal";
import { PrinterTable } from "./printer-table";

const EMPTY_ITEMS: Printer[] = [];
const EMPTY_BRANCHES: Branch[] = [];
const EMPTY_STANDS: Stand[] = [];

type FormModalState =
  | { mode: "create" }
  | { mode: "edit"; item: Printer };

export function PrinterView() {
  const queryClient = useQueryClient();
  const { showLoading, hideLoading } = useLoadingModal();
  const { showDeleteConfirm, showSaveSuccess } = useFeedbackModal();
  const printersQuery = usePrinters();
  const createPrinterMutation = useCreatePrinter();
  const updatePrinterMutation = useUpdatePrinter();
  const deletePrinterMutation = useDeletePrinter();

  const items = printersQuery.data ?? EMPTY_ITEMS;
  const {
    setPage,
    paginatedItems,
    startIndex,
    clampPageAfterDelete,
    paginationProps,
  } = useClientPagination(items);
  const [formModal, setFormModal] = useState<FormModalState | null>(null);
  const [modalBranches, setModalBranches] = useState<Branch[]>(EMPTY_BRANCHES);
  const [modalStands, setModalStands] = useState<Stand[]>(EMPTY_STANDS);
  const [isOpeningFormModal, setIsOpeningFormModal] = useState(false);
  const [mutationError, setMutationError] = useState<string | null>(null);

  const cachedBranches =
    queryClient.getQueryData<Branch[]>(queryKeys.branches.all) ?? EMPTY_BRANCHES;
  const fallbackBranchName =
    cachedBranches.length === 1 ? cachedBranches[0].name : undefined;

  const isSubmitting =
    createPrinterMutation.isPending ||
    updatePrinterMutation.isPending ||
    deletePrinterMutation.isPending;

  const error =
    mutationError ??
    (printersQuery.error
      ? getErrorMessage(printersQuery.error, "Gagal memuat data printer.")
      : null);

  async function openFormModal(intent: FormModalState) {
    setMutationError(null);
    setIsOpeningFormModal(true);
    showLoading({
      message: "Memuat data cabang & stand...",
      ariaLabel: "Memuat data form printer",
    });

    try {
      const [branches, stands] = await Promise.all([
        queryClient.fetchQuery({
          queryKey: queryKeys.branches.all,
          queryFn: fetchBranches,
        }),
        queryClient.fetchQuery({
          queryKey: queryKeys.stands.all,
          queryFn: () => fetchStands(),
        }),
      ]);
      setModalBranches(branches);
      setModalStands(stands);
      setFormModal(intent);
    } catch (err) {
      setMutationError(
        getErrorMessage(err, "Gagal memuat data cabang atau stand."),
      );
    } finally {
      hideLoading();
      setIsOpeningFormModal(false);
    }
  }

  function closeFormModal() {
    setFormModal(null);
    setModalBranches(EMPTY_BRANCHES);
    setModalStands(EMPTY_STANDS);
    setMutationError(null);
  }

  async function runWithLoading<T>(
    message: string,
    action: () => Promise<T>,
  ): Promise<T> {
    showLoading({
      message,
      ariaLabel: "Memproses printer",
    });

    try {
      return await action();
    } finally {
      hideLoading();
    }
  }

  async function handleCreate(data: PrinterFormData) {
    setMutationError(null);

    try {
      await runWithLoading("Jangan tutup, proses sedang berlangsung", () =>
        createPrinterMutation.mutateAsync(data),
      );
      setFormModal(null);
      setPage(1);
      showSaveSuccess({
        description: "Data printer telah tersimpan dengan aman.",
        onPrimary: () => void openFormModal({ mode: "create" }),
      });
    } catch (err) {
      setMutationError(getErrorMessage(err, "Gagal menyimpan printer."));
    }
  }

  async function handleUpdate(data: PrinterFormData) {
    if (!formModal || formModal.mode !== "edit") return;

    setMutationError(null);

    try {
      await runWithLoading("Jangan tutup, proses sedang berlangsung", () =>
        updatePrinterMutation.mutateAsync({
          id: formModal.item.id,
          payload: data,
        }),
      );
      setFormModal(null);
      showSaveSuccess({
        description: "Data printer telah tersimpan dengan aman.",
        onPrimary: () => void openFormModal({ mode: "create" }),
      });
    } catch (err) {
      setMutationError(getErrorMessage(err, "Gagal memperbarui printer."));
    }
  }

  async function handleDelete(id: number) {
    setMutationError(null);

    try {
      await runWithLoading("Jangan tutup, proses sedang berlangsung", () =>
        deletePrinterMutation.mutateAsync(id),
      );
      clampPageAfterDelete(items.length - 1);
    } catch (err) {
      setMutationError(getErrorMessage(err, "Gagal menghapus printer."));
      throw err;
    }
  }

  function handleDeleteRequest(item: Printer) {
    showDeleteConfirm({
      onConfirm: () => handleDelete(item.id),
    });
  }

  function handleFormSubmit(data: PrinterFormData) {
    if (formModal?.mode === "edit") {
      void handleUpdate(data);
      return;
    }

    void handleCreate(data);
  }

  return (
    <PageEnter className="flex min-h-0 flex-1 flex-col">
      <div className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-[10px] border border-neutral-40 bg-neutral-10">
        <div className="relative flex shrink-0 items-center gap-2 px-5 pt-5">
          <div className="absolute top-5 left-0 h-5 w-1 rounded-r-sm bg-primary-500" />
          <PageTextEnter
            as="h1"
            delay={0.08}
            className="text-l-medium flex-1 text-neutral-100"
          >
            Semua Printer
          </PageTextEnter>
          <PageEnter delay={0.12}>
            <IconButton
              icon={<IconAdd />}
              onClick={() => void openFormModal({ mode: "create" })}
              disabled={isOpeningFormModal}
            >
              Tambah Printer
            </IconButton>
          </PageEnter>
        </div>

        <div className="flex min-h-0 flex-1 flex-col gap-4 overflow-hidden p-5">
          {error && (
            <PageEnter delay={0.1}>
              <p className="text-m-regular rounded-lg border border-danger-200 bg-danger-50 px-4 py-3 text-danger-700">
                {error}
              </p>
            </PageEnter>
          )}

          {printersQuery.isPending ? (
            <p className="text-m-regular text-neutral-80">Memuat data...</p>
          ) : (
            <PageEnter delay={0.2} className="flex min-h-0 flex-1 flex-col">
              <DataTableSection pagination={<DataPagination {...paginationProps} />}>
                <PrinterTable
                  items={paginatedItems}
                  startIndex={startIndex}
                  fallbackBranchName={fallbackBranchName}
                  onEdit={(item) => void openFormModal({ mode: "edit", item })}
                  onDelete={handleDeleteRequest}
                />
              </DataTableSection>
            </PageEnter>
          )}
        </div>
      </div>

      {formModal && (
        <PrinterFormModal
          key={
            formModal.mode === "edit"
              ? `edit-${formModal.item.id}`
              : "create"
          }
          open
          mode={formModal.mode}
          branches={modalBranches}
          stands={modalStands}
          initialData={formModal.mode === "edit" ? formModal.item : null}
          isSubmitting={isSubmitting}
          onClose={closeFormModal}
          onSubmit={handleFormSubmit}
        />
      )}
    </PageEnter>
  );
}
