import { memo, useCallback, useEffect, useMemo, useState } from 'react'
import { Input } from 'antd'

import { PermissionView, RoleView } from '@components/views'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { EditableTable, makeActionHandler, makeTagColumn, makeTextColumn } 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 [searchValue, setSearchValue] = useState('')

    const filteredRoles = useMemo(() => roles.filter((role) => role && (!searchValue ||
        role.caption?.toLowerCase()?.includes(searchValue.toLowerCase())
    )), [roles, searchValue])

    const columns = useMemo(() => [
        makeTextColumn('Название', 'caption', null, null, null, { 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])

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

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

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

    return (
        <>
            <Input.Search
                style={{ margin: '15px 0' }}
                placeholder={'Введите текст для поиска (по полю Название)...'}
                onChange={(e) => setSearchValue(e.target.value)}
                value={searchValue}
                loading={showLoader}
            />
            <EditableTable
                bordered
                size={'small'}
                columns={columns}
                loading={showLoader}
                dataSource={filteredRoles}
                onRowAdd={hasPermission('AdminUserRole.edit') && makeActionHandler('insert', handlerProps, null, 'Добавление роли')}
                onRowEdit={hasPermission('AdminUserRole.edit') && makeActionHandler('update', handlerProps, null, 'Редактирование роли')}
                onRowDelete={hasPermission('AdminUserRole.delete') && makeActionHandler('delete', handlerProps, null, 'Удаление роли')}
                tableName={'admin_role_controller'}
            />
        </>
    )
})

export default RoleController
