import { ActionLink, ColumnDef, DataTable, Loading } from '@/components/shared'
import AdaptableCard from '@/components/shared/AdaptableCard'
import Container from '@/components/shared/Container'
import {
  Button,
  Card,
  Dialog,
  FormContainer,
  FormItem,
  Input,
  Notification,
  Select,
  Table,
  Tabs,
  toast,
} from '@/components/ui'
import TBody from '@/components/ui/Table/TBody'
import Td from '@/components/ui/Table/Td'
import Th from '@/components/ui/Table/Th'
import THead from '@/components/ui/Table/THead'
import Tr from '@/components/ui/Table/Tr'
import TabContent from '@/components/ui/Tabs/TabContent'
import TabList from '@/components/ui/Tabs/TabList'
import TabNav from '@/components/ui/Tabs/TabNav'
import { getRoles, getUsers } from '@/services/identity.service'
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
import {
  CreateUpdateOrganizationUnitDto,
  OrganizationUnitDto,
} from '@/proxy/admin/organization-unit/models'
import {
  ouDelete,
  ouDeleteMembers,
  ouDeleteRoles,
  ouGetAll,
  ouGetMembers,
  ouGetRoles,
  ouMoveAllUsers,
  ouPost,
  ouPut,
  ouPutMembers,
  ouPutMove,
  ouPutRoles,
} from '@/services/organization-unit.service'
import { SelectBoxOption } from '@/types/shared'
import { useLocalization } from '@/utils/hooks/useLocalization'
import TableNoRecords from '@/views/shared/TableNoRecords'
import classNames from 'classnames'
import { Field, FieldProps, Form, Formik, FormikHelpers } from 'formik'
import isEmpty from 'lodash/isEmpty'
import { memo, Suspense, useEffect, useMemo, useState } from 'react'
import { NodeApi, NodeRendererProps } from 'react-arborist'
import { Tree } from 'react-arborist/dist/module/components/tree'
import { Helmet } from 'react-helmet'
import {
  FaCheckCircle,
  FaUser,
  FaFolder,
  FaMinusCircle,
  FaPlusCircle,
  FaTrash,
  FaTrashAlt,
  FaEdit,
  FaUsers,
  FaUserPlus,
  FaUserFriends,
} from 'react-icons/fa'
import { object, string } from 'yup'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { APP_NAME } from '@/constants/app.constant'

const schema = object().shape({
  id: string(),
  parentId: string(),
  displayName: string().required(),
})

const schemaMoveAllUsers = object().shape({
  id: string().required(),
  newId: string().required(),
})

interface TreeViewData {
  id: string
  name: string
  children?: TreeViewData[]
}

const convertToTreeViewData = (
  items: (OrganizationUnitDto & { isAdded?: boolean })[],
  parentId?: string,
) => {
  const levelItems = items.filter((a) => a.parentId == parentId)
  if (!levelItems?.length) {
    return
  }

  const data: TreeViewData[] = []

  for (let item of levelItems) {
    if (!item.id || item.isAdded) {
      continue
    }

    item.isAdded = true
    data.push({
      id: item.id,
      name: item.displayName,
      children: convertToTreeViewData(items, item.id),
    })
  }

  return data
}

interface DeleteTypeData {
  id: string
  name: 'Organization Unit' | 'User' | 'Role'
}

const OrganizationUnits = () => {
  const [loading, setLoading] = useState(true)
  const [ous, setOus] = useState<SelectBoxOption[]>([])
  const [list, setList] = useState<TreeViewData[]>([])
  const [activeOu, setActiveOu] = useState<string>()
  const [dialogItem, setDialogItem] = useState<CreateUpdateOrganizationUnitDto | undefined>()
  const [ouMembers, setOuMembers] = useState<IdentityUserDto[]>([])
  const [userSelectionList, setUserSelectionList] = useState<IdentityUserDto[]>([])
  const [userSelectedRows, setUserSelectedRows] = useState<string[]>([])
  const [roleSelectionList, setRoleSelectionList] = useState<IdentityRoleDto[]>([])
  const [ouRoles, setOuRoles] = useState<IdentityRoleDto[]>([])
  const [roleSelectedRows, setRoleSelectedRows] = useState<string[]>([])
  const [deleteRow, setDeleteRow] = useState<DeleteTypeData | null>()
  const [isMoveAllUsersOpen, setIsMoveAllUsersOpen] = useState(false)
  const [treeSearch, setTreeSearch] = useState('')

  const { translate } = useLocalization()

  const userSelectionColumns: ColumnDef<IdentityUserDto>[] = useMemo(
    () => [
      {
        header: 'Name',
        accessorKey: 'fullName',
        cell: ({ row }) => (
          <>
            {row.original.name} {row.original.surname}
          </>
        ),
      },
      {
        header: 'Email',
        accessorKey: 'email',
      },
    ],
    [],
  )

  const roleSelectionColumns: ColumnDef<IdentityRoleDto>[] = useMemo(
    () => [
      {
        header: 'Name',
        accessorKey: 'Name',
        cell: ({ row }) => <>{row.original.name}</>,
      },
    ],
    [],
  )

  const handleUserRowSelect = (checked: boolean, row: IdentityUserDto) => {
    if (checked) {
      const newState = [...userSelectedRows, row.id!]
      setUserSelectedRows(newState)
    } else {
      const newState = [...userSelectedRows.filter((id) => id !== row.id)]
      setUserSelectedRows(newState)
    }
  }

  const handleRoleRowSelect = (checked: boolean, row: IdentityRoleDto) => {
    if (checked) {
      const newState = [...roleSelectedRows, row.id!]
      setRoleSelectedRows(newState)
    } else {
      const newState = [...roleSelectedRows.filter((id) => id !== row.id)]
      setRoleSelectedRows(newState)
    }
  }

  const fetchData = async () => {
    setLoading(true)
    const response = await ouGetAll()
    if (response.data?.items) {
      setOus(
        response.data.items.map((a) => ({
          value: a.id,
          label: a.displayName,
        })),
      )
      var list = convertToTreeViewData(response.data.items) ?? []
      setList(list)
    }
    setLoading(false)
  }

  useEffect(() => {
    if (isEmpty(list)) {
      fetchData()
    }
  }, [])

  const handleDialogSubmit = async (
    values: CreateUpdateOrganizationUnitDto,
    { setSubmitting }: FormikHelpers<CreateUpdateOrganizationUnitDto>,
  ) => {
    setLoading(true)
    setSubmitting(true)

    try {
      if (values.id) {
        await ouPut(values)
      } else {
        await ouPost(values)
      }
      toast.push(
        <Notification type="success" duration={2000}>
          {translate('::Kaydet')}
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )

      fetchData()
      onDialogClose()
    } catch (error) {
      toast.push(
        <Notification type="danger" duration={2000}>
          Hata
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )
    } finally {
      setLoading(false)
      setSubmitting(false)
    }
  }

  const onDialogClose = () => {
    setDialogItem(undefined)
  }

  const onDropdownItemClick = (node: NodeApi<TreeViewData>, eventKey: string) => {
    if (eventKey == 'edit') {
      setDialogItem({
        id: node.data.id,
        displayName: node.data.name,
        parentId: node.parent?.isRoot ? undefined : node.parent?.data.id,
      })
    } else if (eventKey == 'add-sub-unit') {
      setDialogItem({
        displayName: '',
        parentId: node.data.id,
      })
    } else if (eventKey == 'delete') {
      setDeleteRow({ id: node.data.id, name: 'Organization Unit' })
    }
  }

  const onSelect = async (nodes: NodeApi<TreeViewData>[]) => {
    if (nodes.length === 0) {
      setActiveOu(undefined)
    } else {
      const node = nodes[0]
      setActiveOu(node.data.id)
    }
  }

  const fetchUsersAndRoles = async (id: string) => {
    try {
      setLoading(true)
      const memberList = await ouGetMembers(id)
      const members = memberList.data?.items ?? []
      setOuMembers(members)
      setUserSelectedRows(members.map((a) => a.id!))

      const roleList = await ouGetRoles(id)
      const roles = roleList.data?.items ?? []
      setOuRoles(roles)
      setRoleSelectedRows(roles.map((a) => a.id!))
    } catch (error) {
      toast.push(
        <Notification type="danger" duration={2000}>
          Hata
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    const fn = async () => {
      setOuMembers([])
      setUserSelectedRows([])
      setOuRoles([])
      setRoleSelectedRows([])

      if (activeOu) {
        await fetchUsersAndRoles(activeOu)
      }
    }
    fn()
  }, [activeOu])

  const handleEdit = async (id: string, name: string) => {
    setLoading(true)

    try {
      if (!id) {
        return
      }

      await ouPut({ id, displayName: name })
      toast.push(
        <Notification type="success" duration={2000}>
          {translate('::Kaydet')}
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )

      fetchData()
    } catch (error) {
      toast.push(
        <Notification type="danger" duration={2000}>
          Hata
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )
    } finally {
      setLoading(false)
    }
  }

  const handleMove = async (id: string, newParentId?: string) => {
    setLoading(true)

    try {
      if (!id) {
        return
      }

      await ouPutMove(id, newParentId)
      toast.push(
        <Notification type="success" duration={2000}>
          {translate('::Kaydet')}
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )

      fetchData()
    } catch (error) {
      toast.push(
        <Notification type="danger" duration={2000}>
          Hata
        </Notification>,
        {
          placement: 'bottom-end',
        },
      )
    } finally {
      setLoading(false)
    }
  }

  const Node = memo(function Node({ node, style, dragHandle }: NodeRendererProps<any>) {
    return (
      <div
        className={classNames(
          'h-8 text-md flex gap-2 items-center',
          node.isSelected ? 'bg-indigo-100 text-gray-900 dark:bg-gray-700 dark:text-gray-100' : '',
        )}
        style={style}
        ref={dragHandle}
      >
        <div
          className="flex items-center h-full w-full"
          onClick={() => node.isInternal && node.toggle()}
        >
          <div className="w-3">
            {node.isInternal && (node.isOpen ? <FaMinusCircle /> : <FaPlusCircle />)}
          </div>

          <FaFolder className="w-3" />

          <span className="node-text m-1">
            {node.isEditing ? (
              <Input
                className="h-4"
                type="text"
                defaultValue={node.data.name}
                onBlur={() => node.reset()}
                onKeyDown={(e) => {
                  if (e.key === 'Escape') {
                    node.reset()
                  }
                  if (e.key === 'Enter') {
                    node.submit(e.currentTarget.value)
                  }
                }}
                autoFocus
              />
            ) : (
              <span>{node.data.name}</span>
            )}
          </span>
        </div>

        <div className="file-actions">
          <div className="flex gap-1 folderFileActions">
            <Button
              size='xs'
              variant='plain'
              shape="circle"
              className="!h-6 !w-6 !bg-blue-50 !p-0 text-blue-600 hover:!bg-blue-100 hover:text-blue-700 dark:!bg-blue-900/30 dark:text-blue-300 dark:hover:!bg-blue-800/60 dark:hover:text-blue-100"
              icon={<FaUserPlus className="text-xs" />}
              onClick={() => setIsMoveAllUsersOpen(true)}
              title={translate('::Abp.Identity.OrganizationUnit.MoveAllUsers')}
            ></Button>
            <Button
              size='xs'
              variant='plain'
              shape="circle"
              className="!h-6 !w-6 !bg-teal-50 !p-0 text-teal-600 hover:!bg-teal-100 hover:text-teal-700 dark:!bg-teal-900/30 dark:text-teal-300 dark:hover:!bg-teal-800/60 dark:hover:text-teal-100"
              icon={<FaEdit className="text-xs" />}
              onClick={() => node.edit()}
              title={translate('::Abp.Identity.OrganizationUnit.Rename')}
            ></Button>
            <Button
              size='xs'
              variant='plain'
              shape="circle"
              className="!h-6 !w-6 !bg-red-50 !p-0 text-red-600 hover:!bg-red-100 hover:text-red-700 dark:!bg-red-900/30 dark:text-red-300 dark:hover:!bg-red-800/60 dark:hover:text-red-100"
              icon={<FaTrashAlt className="text-xs" />}
              onClick={() => setDeleteRow({ id: node.data.id, name: 'Organization Unit' })}
              title={translate('::Delete')}
            ></Button>
          </div>
        </div>
      </div>
    )
  })

  return (
    <>
      <Helmet
        titleTemplate={`%s | ${APP_NAME}`}
        title={translate('::Abp.Identity.OrganizationUnits')}
        defaultTitle={APP_NAME}
      ></Helmet>
      <Loading type="cover" className="h-full" loading={loading}>
        <Container className="h-full">
          <div className="flex flex-col lg:flex-row gap-4 h-full">
            <Card
              className="md:w-3/12 min-w-fit h-full"
              header={translate('::Abp.Identity.OrganizationUnits')}
              headerExtra={
                <div className="flex gap-1">
                  <Button
                    variant="solid"
                    size="sm"
                    icon={activeOu ? <FaUserFriends /> : <FaUserPlus />}
                    title={translate('::Abp.Identity.OrganizationUnit.AddUnit')}
                    onClick={(e) => {
                      e.preventDefault()
                      setDialogItem({
                        parentId: activeOu,
                        displayName: '',
                      })
                    }}
                  ></Button>

                  <Button
                    variant="solid"
                    size="sm"
                    icon={<FaUsers />}
                    title={translate('::Abp.Identity.OrganizationUnit.MoveAllUsers')}
                    onClick={(e) => {
                      e.preventDefault()
                      setIsMoveAllUsersOpen(true)
                    }}
                  ></Button>
                </div>
              }
            >
              <Input
                className="h-8"
                type="text"
                placeholder={translate('::App.Search')}
                value={treeSearch}
                onChange={(e) => {
                  setTreeSearch(e.target.value)
                }}
              />
              <Tree
                openByDefault={false}
                data={list}
                onSelect={onSelect}
                onMove={({ dragIds, parentId }) => {
                  if (dragIds.length > 0) {
                    handleMove(dragIds[0], parentId ?? '')
                  }
                }}
                onRename={({ id, name }) => {
                  handleEdit(id, name)
                }}
                className="mt-2 cursor-pointer"
                searchTerm={treeSearch}
                indent={10}
                searchMatch={(node, term) =>
                  node.data.name.toLowerCase().includes(term.toLowerCase())
                }
                width={'100%'}
              >
                {Node}
              </Tree>
            </Card>
            <Card className="md:w-9/12 w-full">
              <Tabs defaultValue="users">
                <TabList>
                  <TabNav value="users" icon={<FaUser />}>
                    {translate('::AbpIdentity.Users')}
                  </TabNav>
                  <TabNav value="roles" icon={<FaCheckCircle />}>
                    {translate('::AbpIdentity.Roles')}
                  </TabNav>
                </TabList>
                <TabContent value="users">
                  {activeOu ? (
                    <AdaptableCard
                      headerClass="text-right"
                      header={
                        <Button
                          variant="solid"
                          size="sm"
                          icon={<FaUserPlus />}
                          onClick={async (e) => {
                            e.preventDefault()
                            const response = await getUsers(0, 1000)
                            setUserSelectionList(response.data?.items ?? [])
                          }}
                        ></Button>
                      }
                    >
                      <Table compact>
                        {!!ouMembers.length && (
                          <THead>
                            <Tr>
                              <Th></Th>
                              <Th>Adı Soyadı</Th>
                              <Th>E-Posta</Th>
                              <Th>Durum</Th>
                            </Tr>
                          </THead>
                        )}
                        <TBody>
                          {ouMembers.map((user) => (
                            <Tr key={user.id}>
                              <Td>
                                <Button
                                  className="mr-auto"
                                  type="button"
                                  icon={<FaTrash />}
                                  size="sm"
                                  onClick={() => {
                                    setDeleteRow({
                                      id: user.id ?? '',
                                      name: 'User',
                                    })
                                  }}
                                ></Button>
                              </Td>
                              <Td>
                                <ActionLink
                                  href={ROUTES_ENUM.protected.admin.identity.user.detail.replace(
                                    ':userId',
                                    user.id!,
                                  )}
                                  className="font-bold"
                                  target="_blank"
                                >
                                  {user.name} {user.surname}
                                </ActionLink>
                              </Td>
                              <Td>{user.email}</Td>
                              <Td>{user.isActive ? 'Aktif' : 'Pasif'}</Td>
                            </Tr>
                          ))}
                          <TableNoRecords show={!ouMembers.length} />
                        </TBody>
                      </Table>
                    </AdaptableCard>
                  ) : (
                    <div className="p-3">
                      {translate('::Abp.Identity.OrganizationUnit.Users.Description')}
                    </div>
                  )}
                </TabContent>
                <TabContent value="roles">
                  {activeOu ? (
                    <AdaptableCard
                      headerClass="text-right"
                      header={
                        <Button
                          variant="solid"
                          size="sm"
                          icon={<FaUserPlus />}
                          onClick={async (e) => {
                            e.preventDefault()
                            const response = await getRoles(0, 1000)
                            setRoleSelectionList(response.data?.items ?? [])
                          }}
                        ></Button>
                      }
                    >
                      <Table compact>
                        {!!ouRoles.length && (
                          <THead>
                            <Tr>
                              <Th></Th>
                              <Th>Rol</Th>
                            </Tr>
                          </THead>
                        )}
                        <TBody>
                          {ouRoles.map((role) => (
                            <Tr key={role.id}>
                              <Td>
                                <Button
                                  className="mr-auto"
                                  type="button"
                                  size="sm"
                                  icon={<FaTrash />}
                                  onClick={() => {
                                    setDeleteRow({
                                      id: role.id ?? '',
                                      name: 'Role',
                                    })
                                  }}
                                ></Button>
                              </Td>
                              <Td>{role.name}</Td>
                            </Tr>
                          ))}
                          <TableNoRecords show={!ouRoles.length} />
                        </TBody>
                      </Table>
                    </AdaptableCard>
                  ) : (
                    <div className="p-3">
                      {translate('::Abp.Identity.OrganizationUnit.Roles.Description')}
                    </div>
                  )}
                </TabContent>
              </Tabs>
            </Card>
          </div>
        </Container>
      </Loading>

      <Dialog isOpen={!!dialogItem} onClose={onDialogClose} onRequestClose={onDialogClose}>
        <h5 className="mb-4">{translate('::Abp.Identity.OrganizationUnit.NewUnit')}</h5>
        <hr className="my-2"></hr>
        <Suspense fallback={<></>}>
          <Formik
            initialValues={dialogItem ?? ({ displayName: '' } as CreateUpdateOrganizationUnitDto)}
            validationSchema={schema}
            onSubmit={handleDialogSubmit}
          >
            {({ touched, errors, isSubmitting }) => {
              return (
                <Form>
                  <FormContainer size="sm">
                    <FormItem
                      label={translate('::Abp.Identity.OrganizationUnit.Parent')}
                      invalid={errors.parentId && touched.parentId}
                      errorMessage={errors.parentId}
                    >
                      {/* Parent Name göster */}
                      <Field
                        type="text"
                        disabled
                        autoComplete="off"
                        name="parentId"
                        component={Input}
                      />
                    </FormItem>

                    <FormItem
                      label={translate('::Abp.Identity.OrganizationUnit.DisplayName')}
                      invalid={errors.displayName && touched.displayName}
                      errorMessage={errors.displayName}
                    >
                      <Field
                        type="text"
                        autoComplete="off"
                        name="displayName"
                        component={Input}
                        autoFocus
                      />
                    </FormItem>

                    <div className="mt-6 flex flex-row justify-end gap-3">
                      <Button size="sm" variant="solid" loading={isSubmitting} type="submit">
                        {isSubmitting ? translate('::...') : translate('::Save')}
                      </Button>
                      <Button size="sm" type="button" variant="plain" onClick={onDialogClose}>
                        {translate('::Cancel')}
                      </Button>
                    </div>
                  </FormContainer>
                </Form>
              )
            }}
          </Formik>
        </Suspense>
      </Dialog>

      <Dialog
        id="userSelection"
        isOpen={userSelectionList.length > 0}
        onClose={() => setUserSelectionList([])}
        onRequestClose={() => setUserSelectionList([])}
      >
        <h5 className="mb-4">{translate('::Abp.Identity.OrganizationUnit.SelectMembers')}</h5>

        <DataTable<IdentityUserDto>
          selectable
          selectedRows={[...userSelectedRows]}
          columns={userSelectionColumns}
          data={userSelectionList}
          loading={loading}
          // pagingData={tableData}
          // onPaginationChange={handlePaginationChange}
          // onSelectChange={handleSelectChange} // Items per page
          // onSort={handleSort}
          onCheckBoxChange={handleUserRowSelect}
          // onIndeterminateCheckBoxChange={handleAllRowSelect}
        />

        <div className="text-right mt-6">
          <Button
            className="ltr:mr-2 rtl:ml-2"
            variant="plain"
            onClick={() => {
              setUserSelectionList([])
            }}
          >
            {translate('::Cancel')}
          </Button>
          <Button
            variant="solid"
            onClick={async () => {
              if (!activeOu) {
                return
              }

              try {
                setLoading(true)
                await ouPutMembers(activeOu, userSelectedRows)
                toast.push(
                  <Notification type="success" duration={2000}>
                    Updated
                  </Notification>,
                  {
                    placement: 'bottom-end',
                  },
                )
                await fetchUsersAndRoles(activeOu)
                setUserSelectionList([])
              } catch (error) {
                toast.push(
                  <Notification type="danger" duration={2000}>
                    Hata
                  </Notification>,
                  {
                    placement: 'bottom-end',
                  },
                )
              } finally {
                setLoading(false)
              }
            }}
          >
            {translate('::Abp.Identity.OrganizationUnit.AddMembers')}
          </Button>
        </div>
      </Dialog>

      <Dialog
        id="roleSelection"
        isOpen={roleSelectionList.length > 0}
        onClose={() => setRoleSelectionList([])}
        onRequestClose={() => setRoleSelectionList([])}
      >
        <h5 className="mb-4">{translate('::Abp.Identity.OrganizationUnit.SelectRoles')}</h5>

        <DataTable<IdentityRoleDto>
          selectable
          selectedRows={[...roleSelectedRows]}
          columns={roleSelectionColumns}
          data={roleSelectionList}
          loading={loading}
          // pagingData={tableData}
          // onPaginationChange={handlePaginationChange}
          // onSelectChange={handleSelectChange} // Items per page
          // onSort={handleSort}
          onCheckBoxChange={handleRoleRowSelect}
          // onIndeterminateCheckBoxChange={handleAllRowSelect}
        />

        <div className="text-right mt-6">
          <Button
            className="ltr:mr-2 rtl:ml-2"
            variant="plain"
            onClick={() => {
              setRoleSelectionList([])
            }}
          >
            {translate('::Cancel')}
          </Button>
          <Button
            variant="solid"
            onClick={async () => {
              if (!activeOu) {
                return
              }

              try {
                setLoading(true)
                await ouPutRoles(activeOu, roleSelectedRows)
                toast.push(
                  <Notification type="success" duration={2000}>
                    {translate('::ListForms.FormBilgileriKaydedildi')}
                  </Notification>,
                  {
                    placement: 'bottom-end',
                  },
                )
                await fetchUsersAndRoles(activeOu)
                setRoleSelectionList([])
              } catch (error) {
                toast.push(
                  <Notification type="danger" duration={2000}>
                    Hata
                  </Notification>,
                  {
                    placement: 'bottom-end',
                  },
                )
              } finally {
                setLoading(false)
              }
            }}
          >
            {translate('::Abp.Identity.OrganizationUnit.AddRole')}
          </Button>
        </div>
      </Dialog>

      <Dialog
        id="confirmDelete"
        isOpen={!!deleteRow}
        onClose={() => setDeleteRow(null)}
        onRequestClose={() => setDeleteRow(null)}
      >
        <h5 className="mb-4">{translate('::Delete')}</h5>

        <p>{translate('::DeleteConfirmation')}</p>

        <div className="text-right mt-6">
          <Button
            className="ltr:mr-2 rtl:ml-2"
            variant="plain"
            onClick={() => {
              setDeleteRow(null)
            }}
          >
            {translate('::Cancel')}
          </Button>
          <Button
            variant="solid"
            onClick={async () => {
              if (!deleteRow) {
                return
              }

              try {
                setLoading(true)
                switch (deleteRow.name) {
                  case 'Organization Unit':
                    await ouDelete(deleteRow.id)
                    await fetchData()
                    break
                  case 'Role':
                    if (activeOu) {
                      await ouDeleteRoles(activeOu, deleteRow.id)
                      await fetchUsersAndRoles(activeOu)
                    }
                    break
                  case 'User':
                    if (activeOu) {
                      await ouDeleteMembers(activeOu, deleteRow.id)
                      await fetchUsersAndRoles(activeOu)
                    }
                    break
                  default:
                    break
                }
                setDeleteRow(null)

                toast.push(
                  <Notification type="success" duration={2000}>
                    {translate('::KayitSilindi')}
                  </Notification>,
                  {
                    placement: 'bottom-end',
                  },
                )
              } catch (error) {
                toast.push(
                  <Notification type="danger" duration={2000}>
                    Hata
                  </Notification>,
                  {
                    placement: 'bottom-end',
                  },
                )
              } finally {
                setLoading(false)
              }
            }}
          >
            {translate('::Delete')}
          </Button>
        </div>
      </Dialog>

      <Dialog
        id="moveAllUsers"
        isOpen={isMoveAllUsersOpen}
        onClose={() => setIsMoveAllUsersOpen(false)}
        onRequestClose={() => setIsMoveAllUsersOpen(false)}
      >
        <h5 className="mb-4">{translate('::Abp.Identity.OrganizationUnit.MoveAllUsers')}</h5>

        <Formik
          initialValues={{ id: activeOu, newId: '' }}
          validationSchema={schemaMoveAllUsers}
          onSubmit={async (values, { setSubmitting }) => {
            if (!values.id || values.id === values.newId) {
              return
            }

            setSubmitting(true)
            try {
              setLoading(true)
              await ouMoveAllUsers(values.id, values.newId)
              toast.push(
                <Notification type="success" duration={2000}>
                  {translate('::Abp.Identity.OrganizationUnit.MoveAllUsersMessage')}
                </Notification>,
                {
                  placement: 'bottom-end',
                },
              )
              await fetchUsersAndRoles(values.id)
              setIsMoveAllUsersOpen(false)
            } catch (error) {
              toast.push(
                <Notification type="danger" duration={2000}>
                  Hata
                </Notification>,
                {
                  placement: 'bottom-end',
                },
              )
            } finally {
              setSubmitting(false)
            }
          }}
        >
          {({ touched, errors, values, isSubmitting }) => {
            return (
              <Form>
                <FormContainer size="sm">
                  <FormItem
                    label={translate('::Abp.Identity.OrganizationUnit.CurrentOrganizationUnit')}
                    invalid={errors.id && touched.id}
                    errorMessage={errors.id}
                  >
                    <Field
                      type="text"
                      autoComplete="off"
                      name="id"
                      placeholder={translate(
                        '::Abp.Identity.OrganizationUnit.CurrentOrganizationUnit',
                      )}
                    >
                      {({ field, form }: FieldProps<OrganizationUnitDto>) => (
                        <Select
                          field={field}
                          form={form}
                          isClearable={true}
                          options={ous}
                          value={ous?.filter((option) => option.value === values.id)}
                          onChange={(option) => form.setFieldValue(field.name, option?.value)}
                        />
                      )}
                    </Field>
                  </FormItem>
                  <FormItem
                    label={translate('::Abp.Identity.OrganizationUnit.NewOrganizationUnit')}
                    invalid={errors.newId && touched.newId}
                    errorMessage={errors.newId}
                  >
                    <Field
                      type="text"
                      autoComplete="off"
                      name="newId"
                      placeholder={translate('::Abp.Identity.OrganizationUnit.NewOrganizationUnit')}
                    >
                      {({ field, form }: FieldProps<OrganizationUnitDto>) => (
                        <Select
                          field={field}
                          form={form}
                          isClearable={true}
                          options={ous}
                          value={ous?.filter((option) => option.value === values.newId)}
                          onChange={(option) => form.setFieldValue(field.name, option?.value)}
                        />
                      )}
                    </Field>
                  </FormItem>

                  <div className="mt-6 flex flex-row justify-end gap-3">
                    <Button size="sm" variant="solid" loading={isSubmitting} type="submit">
                      {isSubmitting ? translate('::...') : translate('::Save')}
                    </Button>
                    <Button
                      size="sm"
                      type="button"
                      variant="plain"
                      onClick={() => setIsMoveAllUsersOpen(false)}
                    >
                      {translate('::Cancel')}
                    </Button>
                  </div>
                </FormContainer>
              </Form>
            )
          }}
        </Formik>
      </Dialog>
    </>
  )
}

export default OrganizationUnits
