import { memo, useCallback, useEffect, useState } from 'react'

import LoaderPortal from '@components/LoaderPortal'
import { PermissionView, RoleView } from '@components/views'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { EditableTable, makeActionHandler, makeColumn, makeTagColumn } from '@components/Table'
import { AdminPermissionService, AdminUserRoleService } from '@api'
import { arrayOrDefault } from '@utils'
import { min1 } from '@utils/validationRules'
import { hasPermission } from '@utils/permissions'

export const RoleController = memo(() => {
    const [permissions, setPermissions] = useState([])
    const [roles, setRoles] = useState([])
    const [showLoader, setShowLoader] = useState(false)
    const [columns, setColumns] = useState([])

    const loadRoles = useCallback(async () => {
        const roles = await AdminUserRoleService.getAll()
        setRoles(arrayOrDefault(roles))
    }, [])

    useEffect(() => {
        setColumns([
            makeColumn('Название', 'caption', { width: 100, editable: true, formItemRules: min1 }),
            makeTagColumn('Включённые роли', 'roles', roles, 'id', 'caption', {
                width: 400,
                editable: true,
                render: (role) => <RoleView role={role} />
            }, { allowClear: true }),
            makeTagColumn('Разрешения', 'permissions', permissions, 'id', 'name', {
                width: 600,
                editable: true,
                render: (permission) => <PermissionView info={permission} />,
            }),
        ])
    }, [roles, permissions])

    useEffect(() => invokeWebApiWrapperAsync(
        async () => {
            const permissions = await AdminPermissionService.getAll()
            setPermissions(arrayOrDefault(permissions))
            await loadRoles()
        },
        setShowLoader,
        `Не удалось загрузить список ролей`,
        'Получение списка ролей'
    ), [loadRoles])

    const handlerProps = {
        service: AdminUserRoleService,
        setLoader: setShowLoader,
        errorMsg: `Не удалось выполнить операцию`,
        onComplete: async () => invokeWebApiWrapperAsync(
            loadRoles,
            setShowLoader,
            `Не удалось загрузить список ролей`,
            'Получение списка ролей'
        )
    }

    return (
        <LoaderPortal show={showLoader}>
            <EditableTable
                bordered
                size={'small'}
                columns={columns}
                dataSource={roles}
                onRowAdd={hasPermission('AdminUserRole.edit') && makeActionHandler('insert', handlerProps, null, 'Добавление роли')}
                onRowEdit={hasPermission('AdminUserRole.edit') && makeActionHandler('update', handlerProps, null, 'Редактирование роли')}
                onRowDelete={hasPermission('AdminUserRole.delete') && makeActionHandler('delete', handlerProps, null, 'Удаление роли')}
            />
        </LoaderPortal>
    )
})

export default RoleController
