"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 { User } from "@/lib/api/users";
import { getErrorMessage } from "@/lib/api/types";
import { queryKeys } from "@/lib/query/query-keys";
import {
  useCreateUser,
  useDeleteUser,
  useUpdateUser,
  useUpdateUserStatus,
  useUsers,
  type UserFormData,
} from "@/lib/query/hooks/users";
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 { ManagementUserFormModal } from "./management-user-form-modal";
import { ManagementUserTable } from "./management-user-table";

const EMPTY_ITEMS: User[] = [];
const EMPTY_BRANCHES: Branch[] = [];

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

export function ManagementUserView() {
  const queryClient = useQueryClient();
  const { showLoading, hideLoading } = useLoadingModal();
  const { showDeleteConfirm, showSaveSuccess } = useFeedbackModal();
  const usersQuery = useUsers();
  const [formModal, setFormModal] = useState<FormModalState | null>(null);
  const [modalBranches, setModalBranches] = useState<Branch[]>(EMPTY_BRANCHES);
  const [isOpeningFormModal, setIsOpeningFormModal] = useState(false);
  const createUserMutation = useCreateUser();
  const updateUserMutation = useUpdateUser();
  const deleteUserMutation = useDeleteUser();
  const updateUserStatusMutation = useUpdateUserStatus();

  const items = usersQuery.data ?? EMPTY_ITEMS;
  const {
    setPage,
    paginatedItems,
    startIndex,
    clampPageAfterDelete,
    paginationProps,
  } = useClientPagination(items);
  const [mutationError, setMutationError] = useState<string | null>(null);
  const [togglingId, setTogglingId] = useState<number | null>(null);

  const isSubmitting =
    createUserMutation.isPending ||
    updateUserMutation.isPending ||
    deleteUserMutation.isPending;

  const isInitialLoading = usersQuery.isPending;

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

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

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

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

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

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

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

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

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

    setMutationError(null);

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

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

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

  function handleDeleteRequest(item: User) {
    showDeleteConfirm({
      title: "Apakah Anda yakin ingin menghapus user ini?",
      onConfirm: () => handleDelete(item.id),
    });
  }

  async function handleToggleActive(item: User, isActive: boolean) {
    setTogglingId(item.id);
    setMutationError(null);

    try {
      await updateUserStatusMutation.mutateAsync({
        id: item.id,
        isActive,
      });
    } catch (err) {
      setMutationError(getErrorMessage(err, "Gagal memperbarui status user."));
    } finally {
      setTogglingId(null);
    }
  }

  function handleFormSubmit(data: UserFormData) {
    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"
          >
            Management User
          </PageTextEnter>
          <PageEnter delay={0.12}>
            <IconButton
              icon={<IconAdd />}
              onClick={() => void openFormModal({ mode: "create" })}
              disabled={isOpeningFormModal}
            >
              Tambah User
            </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>
          )}

          {isInitialLoading ? (
            <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} />}>
                <ManagementUserTable
                  items={paginatedItems}
                  startIndex={startIndex}
                  togglingId={togglingId}
                  onEdit={(item) => void openFormModal({ mode: "edit", item })}
                  onDelete={handleDeleteRequest}
                  onToggleActive={handleToggleActive}
                />
              </DataTableSection>
            </PageEnter>
          )}
        </div>
      </div>

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