'use client';

import { useCallback, useState } from 'react';
import { Plus, ShieldCheck } from 'lucide-react';

import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import { PERMISSIONS } from '@/constants/permissions';
import { PermissionGuard } from '@/guards';
import { useAppStore } from '@/store/app.store';
import type { Role } from '@/types';

import { useRoleColumns } from './components/RoleColumns';
import { RoleFilters } from './components/RoleFilters';
import { RoleSheet } from './components/RoleSheet';
import { RoleTable } from './components/RoleTable';
import { useRoleFilters } from './hooks/useRoleFilters';
import { useRoleForm } from './hooks/useRoleForm';
import {
  usePermissionsTreeQuery,
  useRolesQuery,
  useRoleStatusMutation,
} from './hooks/useRoleQueries';

export default function RolesPage() {
  const organizationId = useAppStore((state) => state.user?.organization_id ?? null);
  const [isSheetOpen, setIsSheetOpen] = useState(false);
  const {
    skip,
    setSkip,
    limit,
    setLimit,
    sorting,
    setSorting,
    searchTerm,
    debouncedSearchTerm,
    setSearchTerm,
    statusFilter,
    setStatusFilter,
  } = useRoleFilters();

  const rolesQuery = useRolesQuery({
    skip,
    limit,
    searchTerm: debouncedSearchTerm,
    statusFilter,
    sorting,
  });
  const permissionsQuery = usePermissionsTreeQuery(isSheetOpen);
  const roleForm = useRoleForm({
    organizationId,
    permissionTree: permissionsQuery.permissionTree,
    onSaved: () => setIsSheetOpen(false),
  });
  const {
    openCreate: prepareCreateRole,
    openEdit: prepareEditRole,
    register,
    onSubmit,
    roleId,
    permissionIds,
    setPermissionIds,
    errors,
    touchedFields,
    canSubmit,
    isSaving,
  } = roleForm;
  const statusMutation = useRoleStatusMutation();
  const { mutate: updateRoleStatus, isPending: isStatusPending } = statusMutation;

  const openCreate = useCallback(() => {
    prepareCreateRole();
    setIsSheetOpen(true);
  }, [prepareCreateRole]);

  const openEdit = useCallback(
    (role: Role) => {
      prepareEditRole(role);
      setIsSheetOpen(true);
    },
    [prepareEditRole],
  );

  const toggleStatus = useCallback(
    (role: Role) => {
      updateRoleStatus(role);
    },
    [updateRoleStatus],
  );

  const columns = useRoleColumns({
    onEdit: openEdit,
    onToggleStatus: toggleStatus,
    isStatusPending,
  });

  const total = rolesQuery.data?.total ?? 0;
  const roles = rolesQuery.data?.items ?? [];
  const toolbar = (
    <RoleFilters
      searchTerm={searchTerm}
      statusFilter={statusFilter}
      onSearchChange={setSearchTerm}
      onStatusChange={setStatusFilter}
    />
  );

  return (
    <>
      <main className="relative z-10 space-y-5">
        <PageHeader
          title="Role Management"
          description="Manage roles and permission access"
          icon={ShieldCheck}
          actions={
            <PermissionGuard permissions={PERMISSIONS.ROLE.CREATE}>
              <Button onClick={openCreate} size="sm">
                <Plus />
                Add Role
              </Button>
            </PermissionGuard>
          }
        />

        <RoleTable
          columns={columns}
          roles={roles}
          isLoading={rolesQuery.isLoading}
          toolbar={toolbar}
          skip={skip}
          limit={limit}
          total={total}
          sorting={sorting}
          onPageChange={setSkip}
          onLimitChange={setLimit}
          onSortingChange={setSorting}
        />
      </main>

      <RoleSheet
        open={isSheetOpen}
        onOpenChange={setIsSheetOpen}
        roleId={roleId}
        register={register}
        errors={errors}
        touchedFields={touchedFields}
        onSubmit={onSubmit}
        permissionTree={permissionsQuery.permissionTree}
        permissionIds={permissionIds}
        onPermissionIdsChange={setPermissionIds}
        isPermissionsLoading={permissionsQuery.isLoading}
        canSubmit={canSubmit}
        isSaving={isSaving}
      />
    </>
  );
}
