import React, { Fragment, useEffect, useState, useRef, use } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
    Card,
    Table, Title,
    Group,
    ScrollArea,
    Checkbox,
    TextInput,
    LoadingOverlay,
    Text,
    Modal,
    Box,
    Button,
    Tooltip,
    ThemeIcon,
    Divider,
    Accordion,
    Stack,
} from '@mantine/core';
import {
    IconChevronDown,
    IconDeviceFloppy,
    IconPencil,
    IconPlus,
    IconTrash
} from '@tabler/icons-react';
import { fetchAllRoles, fetchAllPermission, fetchRolePermissions, editRolePermissions, createRole, updateRole, deleteRole } from "../../../store/auth/roleSlice";
import { showNotification, updateNotification } from "@mantine/notifications";
import { modals } from "@mantine/modals";
import { translate } from '../../../utils/i18n';
import PermissionTable from './PermissionTable';
import { useElementSize } from '@mantine/hooks';

const RolesPermission = () => {

    const dispatch = useDispatch();
    const { loggedUserId } = useSelector((state) => state.auth.user)
    const { loggedInUser } = useSelector((state) => state.auth.session)
    const { permissions, rolePermissions } = useSelector((state) => state.auth.role);

    const [roles, setRoles] = useState(rolePermissions || []);
    const [modalOpened, setModalOpened] = useState(false);
    const [infoModalOpened, setInfoModalOpened] = useState(false);
    const [newRoleName, setNewRoleName] = useState('');
    const [isSaving, setIsSaving] = useState(false);
    const contentEditableRef = useRef('');

    const [editingRoleIndex, setEditingRoleIndex] = useState(null);
    const [editingRoleName, setEditingRoleName] = useState('');
    const [editingUseGlobalPermissions, setEditingUseGlobalPermissions] = useState(false);
    const [editingUseProjectPermissions, setEditingUseProjectPermissions] = useState(false);
    const [editModalOpened, setEditModalOpened] = useState(false);
    const [isLoading, setIsLoading] = useState(true);
    const [useGlobalPermissions, setUseGlobalPermissions] = useState(false);
    const [useProjectPermissions, setUseProjectPermissions] = useState(false);
    const [errorMessage, setErrorMessage] = useState('');

    useEffect(() => {
        setIsLoading(true);
        dispatch(fetchAllPermission());
        dispatch(fetchRolePermissions()).then(() => {
            setIsLoading(false);
        });
    }, [dispatch]);

    useEffect(() => {
        if (rolePermissions) {
            setRoles(rolePermissions);
        }
    }, [rolePermissions]);

    const globalPermissions = permissions?.filter(p => p.type === "global") || [];
    const projectPermissions = permissions?.filter(p => p.type === "project") || [];

    const groupPermissions = (permissions) => {
        const groups = {};
        permissions.forEach(permission => {
            // Assuming permission names are in format: 'create_task', 'edit_task', etc.
            const groupName = permission.group || 'Other'; // Use existing group or fallback to 'Other'
            if (!groups[groupName]) {
                groups[groupName] = [];
            }
            groups[groupName].push(permission);
        });
        return groups;
    };

    const handleCheckAllGroup = (roleIndex, groupPermissions, checked) => {
        const updatedRoles = roles.map((role, index) => {
            if (index === roleIndex) {
                const otherPermissions = role.permissions.filter(p =>
                    !groupPermissions.some(gp => gp.id === p.id)
                );

                return {
                    ...role,
                    permissions: checked
                        ? [...otherPermissions, ...groupPermissions]
                        : otherPermissions
                };
            }
            return role;
        });
        setRoles(updatedRoles);
    };

    const togglePermission = (roleIndex, permission) => {
        const updatedRoles = roles.map((role, index) => {
            if (index === roleIndex) {
                // const hasPermission = role.permissions.some(p => p.id === permission.id);
                // return {
                //     ...role,
                //     permissions: hasPermission
                //         ? role.permissions.filter(p => p.id !== permission.id)
                //         : [...role.permissions, permission]
                // };
                const allowGlobal = role.use_global_permissions ?? true;
                const allowProject = role.use_project_permissions ?? true;
                // block toggling if this permission type isn't allowed for the role
                if (permission.type === 'global' && !allowGlobal) {
                    showNotification({ title: 'Error', message: 'This role cannot have global permissions', color: 'red' });
                    return role;
                }
                if (permission.type === 'project' && !allowProject) {
                    showNotification({ title: 'Error', message: 'This role cannot have project permissions', color: 'red' });
                    return role;
                }
                const hasPermission = role.permissions.some(p => p.id === permission.id);
                return {
                    ...role,
                    permissions: hasPermission
                        ? role.permissions.filter(p => p.id !== permission.id)
                        : [...role.permissions, permission]
                };
            }
            return role;
        });

        setRoles(updatedRoles);
    };

    // const handleCheckAll = (roleIndex, checked, permissionsArg) => {
    //     const updatedRoles = roles.map((role, index) => {
    //         if (index === roleIndex) {
    //             // return {
    //             //     ...role,
    //             //     permissions: checked ? [...permissions] : []
    //             // };
    //             const allowGlobal = role.use_global_permissions ?? true;
    //             const allowProject = role.use_project_permissions ?? true;
    //             const allowed = checked ? permissions.filter(p =>
    //                 (p.type === 'global' && allowGlobal) || (p.type === 'project' && allowProject)
    //             ) : [];
    //             return {
    //                 ...role,
    //                 permissions: allowed
    //             };
    //         }
    //         return role;
    //     });
    //     setRoles(updatedRoles);
    // };

    const handleCheckAll = (roleIndex, checked, permissionsArg) => {
        const sourcePermissions = permissionsArg || permissions;
        const updatedRoles = roles.map((role, index) => {
            if (index === roleIndex) {
                const allowGlobal = role.use_global_permissions ?? true;
                const allowProject = role.use_project_permissions ?? true;
                const allowed = checked ? sourcePermissions.filter(p =>
                    (p.type === 'global' && allowGlobal) || (p.type === 'project' && allowProject)
                ) : [];
                return {
                    ...role,
                    permissions: allowed
                };
            }
            return role;
        });
        setRoles(updatedRoles);
    };

    const handleCreateRole = () => {
        if (!newRoleName.trim()) {
            showNotification({
                title: 'Error',
                message: 'Role name is required',
                color: 'red',
            });
            return;
        }
        if (useGlobalPermissions === false && useProjectPermissions === false) {
            setErrorMessage('Select at least one permission type (Global or Project)');
            showNotification({
                title: 'Error',
                message: 'Select at least one permission type (Global or Project)',
                color: 'red',
            });
            return;
        }
        const roleData = {
            'name': newRoleName,
            use_global_permissions: useGlobalPermissions,
            use_project_permissions: useProjectPermissions
        };
        setIsSaving(true);
        dispatch(createRole(roleData)).then((res) => {
            if (res.payload.status && res.payload.status == 200) {
                dispatch(fetchRolePermissions());
                setNewRoleName('');
                setModalOpened(false);
                showNotification({
                    title: 'Success',
                    message: 'Role created successfully',
                    color: 'green',
                });
            } else {
                showNotification({
                    title: 'Error',
                    message: res.payload.message || 'Failed to create role',
                    color: 'red',
                });
            }
        })
            .catch((error) => {
                showNotification({
                    title: 'Error',
                    message: error.message || 'Something went wrong',
                    color: 'red',
                });
            })
            .finally(() => {
                setIsSaving(false);
            });
    };

    const handleSave = async () => {
        try {
            setIsSaving(true);
            const response = await dispatch(editRolePermissions({
                roles: roles
            })).unwrap();

            if (response.status === 200) {
                showNotification({
                    title: 'Success',
                    message: 'All permissions updated successfully',
                    color: 'green'
                });

                dispatch(fetchRolePermissions());
                setInfoModalOpened(true);
            }
        } catch (error) {
            showNotification({
                title: 'Error',
                message: 'Failed to update permissions',
                color: 'red'
            });
        } finally {
            setIsSaving(false);
        }

    };

    const openEditModal = (index) => {
        setEditingRoleIndex(index);
        setEditingRoleName(roles[index]?.name || '');
        setEditingUseGlobalPermissions(roles[index]?.use_global_permissions ?? false);
        setEditingUseProjectPermissions(roles[index]?.use_project_permissions ?? false);
        setEditModalOpened(true);
        setErrorMessage('');
    };

    const handleRoleNameSave = () => {

        // const roleEditableName = contentEditableRef.current.innerHTML;
        const roleEditableName = editingRoleName;
        const roleId = roles[editingRoleIndex]?.id;
        const prevRoleName = roles[editingRoleIndex]?.name?.trim();

        if (roleEditableName === '') {
            showNotification({
                title: 'Error',
                message: 'Role name cannot be empty',
                color: 'red',
            });
            return;
        }

        if (editingUseGlobalPermissions === false && editingUseProjectPermissions === false) {
            setErrorMessage('Select at least one permission type (Global or Project)');
            showNotification({
                title: 'Error',
                message: 'Select at least one permission type (Global or Project)',
                color: 'red',
            });
            return;
        }

        // if (roleEditableName === prevRoleName) {
        //     setEditModalOpened(false);
        //     return;
        // }

        const roleData = {
            name: roleEditableName.trim(),
            use_global_permissions: editingUseGlobalPermissions,
            use_project_permissions: editingUseProjectPermissions
        };

        dispatch(updateRole({ id: roleId, data: roleData }))
            .then((res) => {
                if (res.payload.status && res.payload.status === 200) {

                    setEditModalOpened(false);

                    showNotification({
                        title: 'Success',
                        message: 'Role updated successfully',
                        color: 'green',
                    });

                    // Refresh roles from server
                    dispatch(fetchRolePermissions());
                } else {
                    showNotification({
                        title: 'Error',
                        message: res.payload.message || 'Failed to update role',
                        color: 'red',
                    });
                }
            })
            .catch((error) => {
                showNotification({
                    title: 'Error',
                    message: error.message || 'Something went wrong',
                    color: 'red',
                });
            });
    };

    const roleDeleteHandler = (role) => {
        modals.openConfirmModal({
            title: translate('Delete Role'),
            centered: true,
            children: (
                <Text size="sm">
                    {translate('Are you sure you want to delete the role?')}
                </Text>
            ),
            labels: { confirm: translate('Yes'), cancel: translate('Cancel') },
            confirmProps: { color: 'orange' },
            onConfirm: () => {
                showNotification({
                    id: 'load-data',
                    loading: true,
                    title: 'Task',
                    message: "Deleting the role...",
                    disallowClose: true,
                    color: 'green',
                    styles: () => ({
                        root: {
                            zIndex: 3000,
                        },
                    }),
                });
                // return;
                dispatch(deleteRole(role?.id))
                    .then((response) => {
                        if (response.payload && response.payload.status && response.payload.status === 200) {
                            // Refresh roles from server
                            dispatch(fetchRolePermissions());
                            updateNotification({
                                id: 'load-data',
                                loading: false,
                                title: 'Task',
                                message: response.payload && response.payload.message && response.payload.message,
                                autoClose: 2000,
                                disallowClose: true,
                                color: 'green',
                            });
                        } else {
                            updateNotification({
                                id: 'load-data',
                                loading: false,
                                title: 'Task',
                                message: response.payload && response.payload.message && response.payload.message,
                                autoClose: 2000,
                                disallowClose: true,
                                color: 'red',
                            });
                        }
                    })
                    .catch((error) => {
                        console.error('Error deleting role:', error);
                        updateNotification({
                            id: 'load-data',
                            loading: false,
                            title: 'Error',
                            message: 'Failed to delete the role.',
                            autoClose: 3000,
                            disallowClose: false,
                            color: 'red',
                        });
                    });
            },
        });
    }
    const { ref, width, height } = useElementSize();

    return (
        <>
            <Card padding="md" radius="md" h={'100%'}>
                <LoadingOverlay visible={isLoading} zIndex={1000} overlayProps={{ radius: "sm", blur: 2 }} />
                <Stack spacing={4} justify="space-between"
                    align="stretch"
                >

                    <Group position="apart">
                        <Button
                            size='sm'
                            variant="filled"
                            color="#39758D"
                            onClick={() => setModalOpened(true)}>
                            <IconPlus size={22} color="#fff" stroke={1.75} />
                            {translate('Add New Role')}
                        </Button>
                    </Group>

                    <ScrollArea className={'h-[calc(100vh-385px)]'} type="scroll" scrollbarSize={4} ref={ref}>
                        <Accordion variant="separated" chevronPosition="left" defaultValue={["project"]}
                            multiple
                            chevron={<IconChevronDown size={30} stroke={2} />}
                            classNames={{
                                content: '!pb-0 !pt-0 !px-0',
                            }}
                        >

                            {/* GLOBAL ACCORDION */}
                            <Accordion.Item value="global" className="accordion-item !border-solid !border-[#dddddd] !rounded-t-md accordion-item">
                                <Accordion.Control
                                    className='!bg-[#EBF1F4]'
                                >{translate('Global Permissions')}</Accordion.Control>
                                <Accordion.Panel>
                                    <PermissionTable
                                    ref={ref}
                                    width={width}
                                    height={height} 
                                        roles={roles}
                                        permissions={globalPermissions}
                                        groupPermissions={groupPermissions}
                                        handleCheckAll={handleCheckAll}
                                        handleCheckAllGroup={handleCheckAllGroup}
                                        togglePermission={togglePermission}
                                        editingRoleIndex={editingRoleIndex}
                                        editingRoleName={editingRoleName}
                                        contentEditableRef={contentEditableRef}
                                        setEditingRoleIndex={setEditingRoleIndex}
                                        setEditingRoleName={setEditingRoleName}
                                        handleRoleNameSave={handleRoleNameSave}
                                        onOpenRoleEdit={openEditModal}
                                        roleDeleteHandler={roleDeleteHandler}
                                        allPermissions={permissions}
                                        type="global"
                                    />
                                </Accordion.Panel>
                            </Accordion.Item>

                            {/* PROJECT ACCORDION */}
                            <Accordion.Item value="project" className="accordion-item !border-solid !border-[#dddddd] !rounded-t-md accordion-item">
                                <Accordion.Control className='!bg-[#EBF1F4]'>{translate('Project Permissions')}</Accordion.Control>
                                <Accordion.Panel>
                                    <PermissionTable
                                        roles={roles}
                                        permissions={projectPermissions}
                                        groupPermissions={groupPermissions}
                                        handleCheckAll={handleCheckAll}
                                        handleCheckAllGroup={handleCheckAllGroup}
                                        togglePermission={togglePermission}
                                        editingRoleIndex={editingRoleIndex}
                                        editingRoleName={editingRoleName}
                                        contentEditableRef={contentEditableRef}
                                        setEditingRoleIndex={setEditingRoleIndex}
                                        setEditingRoleName={setEditingRoleName}
                                        handleRoleNameSave={handleRoleNameSave}
                                        onOpenRoleEdit={openEditModal}
                                        roleDeleteHandler={roleDeleteHandler}
                                        allPermissions={permissions}
                                        type="project"
                                    />
                                </Accordion.Panel>
                            </Accordion.Item>

                        </Accordion>
                    </ScrollArea>

                    <Group position="left">
                        <Button
                            size='sm'
                            variant="filled"
                            color="#39758D"
                            w="auto"
                            loading={isSaving}
                            disabled={isSaving}
                            onClick={handleSave}
                            loaderProps={{ type: 'dots' }}
                        >
                            <IconDeviceFloppy size={22} color="#fff" stroke={1.75} />
                            {' '}
                            {translate('Save Changes')}
                        </Button>
                    </Group>
                </Stack>
            </Card>

            {/* Modal to show permission update information */}
            <Modal
                opened={infoModalOpened}
                onClose={() => setInfoModalOpened(false)}
                title={
                    <>
                        <Group spacing="xs">
                            <ThemeIcon color="orange" radius="xl" size="lg" variant="light">
                                <IconPencil size={24} />
                            </ThemeIcon>
                            <Text size='md' weight={500}>
                                {translate('Permissions Updated')}
                            </Text>
                        </Group>

                    </>
                }
                centered
            >
                <Divider size="xs" className='!-ml-4 w-[calc(100%+2rem)]' />
                <Text mt={10} fw={700} size="sm" c="#4D4D4D" ta="center">
                    {translate('The permissions have been applied.')}
                </Text>

                <Text mt={10} size="sm" c="#4D4D4D" ta="center">
                    {translate('The users have to login again for it to take effect.')} <br />
                    {translate('Please advice your users accordingly.')}
                </Text>

                <Group position="right" mt="sm" justify='center'>
                    <Button
                        size='sm'
                        variant="filled"
                        color="#ED7D31"
                        mt="sm" onClick={() => setInfoModalOpened(false)}>
                        {translate('Okay')}
                    </Button>
                </Group>
            </Modal>

            {/* Modal to create new role */}
            <Modal
                opened={modalOpened}
                onClose={() => setModalOpened(false)}
                title={
                    <>
                        <Group spacing="xs">
                            <ThemeIcon color="orange" radius="xl" size="lg" variant="light">
                                <IconPencil size={24} />
                            </ThemeIcon>
                            <Text size='md' weight={500}>
                                {translate('Create New Role')}
                            </Text>
                        </Group>

                    </>
                }
                centered
            >
                <Divider size="xs" className='!-ml-4 w-[calc(100%+2rem)]' />
                <TextInput
                    mt={10}
                    label={translate('Role Name')}
                    placeholder={translate('Enter role name')}
                    value={newRoleName}
                    onChange={(e) => setNewRoleName(e.currentTarget.value)}
                    required
                />
                <Group position="right" mt={15} justify="space-between">
                    <Checkbox
                        color="orange"
                        label="Use Global Permissions"
                        checked={useGlobalPermissions}
                        onChange={(event) => setUseGlobalPermissions(event.currentTarget.checked)}
                    />

                    <Checkbox
                        color="orange"
                        label="Use Project Permissions"
                        checked={useProjectPermissions}
                        onChange={(event) => setUseProjectPermissions(event.currentTarget.checked)}
                    />
                </Group>

                <Text c="red" size="sm" mt={5}>
                    {errorMessage}
                </Text>
                <Button
                    size='sm'
                    variant="filled"
                    color="#ED7D31"
                    mt="md" onClick={handleCreateRole}>
                    {translate('Create Role')}
                </Button>
            </Modal>

            {/* Edit Role Modal */}
            <Modal
                opened={editModalOpened}
                onClose={() => setEditModalOpened(false)}
                title={
                    <>
                        <Group spacing="xs">
                            <ThemeIcon color="orange" radius="xl" size="lg" variant="light">
                                <IconPencil size={24} />
                            </ThemeIcon>
                            <Text size='md' weight={500}>
                                {translate('Edit Role')}
                            </Text>
                        </Group>
                    </>
                }
                centered
                trapFocus={false}
            >
                <Divider size="xs" className='!-ml-4 w-[calc(100%+2rem)]' />
                <TextInput
                    mt={10}
                    label={translate('Role Name')}
                    placeholder={translate('Enter role name')}
                    value={editingRoleName}
                    onChange={(e) => setEditingRoleName(e.currentTarget.value)}
                    required
                />
                <Text c="red" size="sm" mt={5}>
                    {errorMessage}
                </Text>
                <Group position="right" mt={15} justify="space-between">
                    <Checkbox
                        color="orange"
                        label="Use Global Permissions"
                        checked={editingUseGlobalPermissions}
                        onChange={(event) => setEditingUseGlobalPermissions(event.currentTarget.checked)}
                    />

                    <Checkbox
                        color="orange"
                        label="Use Project Permissions"
                        checked={editingUseProjectPermissions}
                        onChange={(event) => setEditingUseProjectPermissions(event.currentTarget.checked)}
                    />
                </Group>
                <Group position="right" mt="md">
                    <Button
                        size='sm'
                        variant="filled"
                        color="#ED7D31"
                        onClick={handleRoleNameSave}
                    >
                        {translate('Save')}
                    </Button>
                </Group>
            </Modal>
        </>
    );
};

export default RolesPermission;