import { useEffect, useState } from "react";
import Offcanvas from "../components/OffCanvas";
import { PERMISSIONS } from "../constants/permissions";
import api from "../api/axios";
import { toast } from "react-toastify";
import { useSelector, useDispatch } from "react-redux";
import { setPermissions as setReduxPermissions } from "../store/permissionsSlice"; // Rename the import

type Action = 'view' | 'create' | 'edit' | 'delete';

type ChildMenu = {
    key: string;
    label: string;
    actions: readonly Action[]; 
};

type ParentMenu = {
    key: string;
    label: string;
    children: readonly ChildMenu[]; 
};

type SingleMenu = {
    key: string;
    label: string;
    actions: readonly Action[]; 
};

type MenuItem = ParentMenu | SingleMenu;

interface Props {
    open: boolean;
    onClose: () => void;
    data: any;
    onSave?: (payload: any) => void;
}

const RoleConfigure = ({ open, onClose, data, onSave }: Props) => {
    const dispatch = useDispatch();
    const [permissions, setPermissions] = useState<Record<string, string[]>>({});
    const [selectAll, setSelectAll] = useState<Record<string, boolean>>({});
    const [isSaving, setIsSaving] = useState(false);

    useEffect(() => {
        if (data?.permissions) {
            // If permissions come as array, convert to object format
            if (Array.isArray(data.permissions)) {
                const formattedPermissions: Record<string, string[]> = {};
                data.permissions.forEach((perm: string) => {
                    const [menu, action] = perm.split('.');
                    if (!formattedPermissions[menu]) {
                        formattedPermissions[menu] = [];
                    }
                    formattedPermissions[menu].push(action);
                });
                setPermissions(formattedPermissions);
            } else {
                setPermissions(data.permissions || {});
            }
        } else {
            setPermissions({});
        }
    }, [data]);

    const togglePermission = (menu: string, action: string) => {
        setPermissions((prev) => {
            const current = prev[menu] || [];
            const exists = current.includes(action);

            const newPermissions = {
                ...prev,
                [menu]: exists
                    ? current.filter((p) => p !== action)
                    : [...current, action],
            };

            // Update selectAll state for this menu
            const menuConfig = getMenuConfig(menu);
            if (menuConfig && 'actions' in menuConfig) {
                const allActions = menuConfig.actions;
                const allSelected = allActions.every((action: string)=> newPermissions[menu]?.includes(action));
                setSelectAll(prev => ({ ...prev, [menu]: allSelected }));
            }

            return newPermissions;
        });
    };

    const toggleSelectAll = (menu: string, actions: string[]) => {
        const isSelected = selectAll[menu];

        setPermissions((prev) => {
            if (isSelected) {
                // Unselect all
                const { [menu]: _, ...rest } = prev;
                return rest;
            } else {
                // Select all
                return {
                    ...prev,
                    [menu]: actions,
                };
            }
        });

        setSelectAll((prev) => ({
            ...prev,
            [menu]: !isSelected,
        }));
    };


    const toggleParentSelectAll = (
        parentKey: string,
        children: readonly ChildMenu[] //  FIX
    ) => {
        const allChildActions: string[] = [];

        children.forEach(child => {
            child.actions.forEach(action => {
                allChildActions.push(`${child.key}.${action}`);
            });
        });

        const allSelected = allChildActions.every(perm => {
            const [menu, action] = perm.split('.');
            return permissions[menu]?.includes(action);
        });

        children.forEach(child => {
            if (allSelected) {
                setPermissions(prev => {
                    const { [child.key]: _, ...rest } = prev;
                    return rest;
                });
            } else {
                setPermissions(prev => ({
                    ...prev,
                    [child.key]: [...child.actions], 
                }));
            }
        });
    };
    const getMenuConfig = (menuKey: string): any => {
        const menuList = Object.values(PERMISSIONS) as MenuItem[];

        for (const menu of menuList) {
            if ('children' in menu) {
                for (const child of menu.children) {
                    if (child.key === menuKey) {
                        return child;
                    }
                }
            } else if (menu.key === menuKey) {
                return menu;
            }
        }
        return null;
    };

    const handleSave = async () => {
        // Convert permissions object to array format for API
        const permissionsArray: string[] = [];
        Object.entries(permissions).forEach(([menu, actions]) => {
            actions.forEach(action => {
                permissionsArray.push(`${menu}.${action}`);
            });
        });

        setIsSaving(true);

        try {
            // Call API to update role permissions
            const response = await api.put(`/roles/${data?.id}/permissions`, {
                permissions: permissionsArray
            });

            console.log('API Response:', response.data);

            //  Fix: Check if status is true (not just === true)
            if (response.data.status) {

                //  Get user from localStorage (don't use useSelector inside async function)
                const currentUser = localStorage.getItem('user');
                let currentUserRoleId = null;

                if (currentUser) {
                    try {
                        const parsedUser = JSON.parse(currentUser);
                        currentUserRoleId = parsedUser.role_id;
                        console.log('Current user role ID from localStorage:', currentUserRoleId);
                    } catch (e) {
                        console.error('Error parsing user from localStorage:', e);
                    }
                }

                console.log('Updating role ID:', data?.id);
                console.log('Logged-in user role ID:', currentUserRoleId);

                //  Only update Redux and localStorage if the updated role matches the logged-in user's role
                if (currentUserRoleId === data?.id) {

                    // Update Redux store with new permissions
                    const updatedPermissions = {
                        role_id: data?.id,
                        role_name: data?.role,
                        permissions: permissionsArray,
                        status: 1,
                        permission_version: response.data.data?.permission_version || (data?.permission_version + 1),
                    };

                    dispatch(setReduxPermissions(updatedPermissions));

                    // Also update localStorage
                    localStorage.setItem('permissions', JSON.stringify(updatedPermissions));

                } else {
                    console.log(' Role does NOT match logged-in user. Skipping Redux/localStorage update.');
                }

                toast.success('Permissions updated successfully');

                // Call the onSave callback to refresh parent component
                if (onSave) {
                    onSave({
                        roleId: data?.id,
                        role: data?.role,
                        permissions: permissionsArray,
                        menuPermissions: permissions,
                    });
                }

                // Close the offcanvas
                onClose();

            } else {
                console.error('API returned status false:', response.data);
                toast.error(response.data.message || 'Failed to save permissions');
            }
        } catch (error: any) {
            console.error('Error saving permissions:', error);
            console.error('Error response:', error.response?.data);
            toast.error(error.response?.data?.message || 'Failed to save permissions');
        } finally {
            setIsSaving(false);
        }
    };
    const menuList = Object.values(PERMISSIONS) as MenuItem[];

    return (
        <Offcanvas
            open={open}
            title={`Configure Permissions - ${data?.role || ''}`}
            onClose={onClose}
            width="700px"
            footer={
                <div className="flex justify-end gap-2">
                    <button
                        className="px-4 py-2 border rounded hover:bg-gray-50"
                        onClick={onClose}
                        disabled={isSaving}
                    >
                        Cancel
                    </button>

                    <button
                        className="px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark disabled:opacity-50"
                        onClick={handleSave}
                        disabled={isSaving}
                    >
                        {isSaving ? 'Saving...' : 'Save Changes'}
                    </button>
                </div>
            }
        >
            <div className="space-y-6 max-h-[calc(100vh-200px)] overflow-y-auto p-2">
                {menuList.map((menu) => {
                    const isParent = "children" in menu;

                    return (
                        <div key={menu.key} className="border rounded-lg p-4 bg-gray-50">
                            {/* Parent Menu Header */}
                            <div className="font-semibold text-lg mb-3 text-gray-800 flex items-center justify-between">
                                <span>{menu.label}</span>
                                {isParent && (
                                    <button
                                        className="text-xs text-primary hover:underline"
                                        onClick={() => toggleParentSelectAll(menu.key, menu.children)}
                                    >
                                        {menu.children.every(child =>
                                            child.actions.every(action =>
                                                permissions[child.key]?.includes(action)
                                            )
                                        ) ? 'Unselect All' : 'Select All'}
                                    </button>
                                )}
                            </div>

                            {/* Parent Menu with Children */}
                            {isParent ? (
                                <div className="space-y-4">
                                    {menu.children.map((child) => {
                                        const allActions = child.actions;
                                        const selectedCount = permissions[child.key]?.length || 0;
                                        const isAllSelected = selectedCount === allActions.length;

                                        return (
                                            <div key={child.key} className="ml-4 border-l-2 pl-4">
                                                <div className="flex items-center justify-between mb-2">
                                                    <div className="text-sm font-medium text-gray-700">
                                                        {child.label}
                                                        <span className="ml-2 text-xs text-gray-400">
                                                            ({selectedCount}/{allActions.length})
                                                        </span>
                                                    </div>
                                                    <button
                                                        className="text-xs text-primary hover:underline"
                                                        onClick={() => toggleSelectAll(child.key, [...allActions])}
                                                    >
                                                        {isAllSelected ? 'Unselect All' : 'Select All'}
                                                    </button>
                                                </div>

                                                <div className="flex flex-wrap gap-2">
                                                    {child.actions.map((action) => (
                                                        <label
                                                            key={action}
                                                            className={`flex items-center gap-2 text-xs px-3 py-1.5 rounded-md cursor-pointer transition-all ${
                                                                permissions[child.key]?.includes(action)
                                                                    ? 'bg-primary/10 border-primary text-primary'
                                                                    : 'bg-white border-gray-200 text-gray-600 hover:bg-gray-50'
                                                            } border`}
                                                        >
                                                            <input
                                                                type="checkbox"
                                                                className="rounded border-gray-300 text-primary focus:ring-primary"
                                                                checked={permissions[child.key]?.includes(action) || false}
                                                                onChange={() => togglePermission(child.key, action)}
                                                            />
                                                            <span className="capitalize">{action}</span>
                                                        </label>
                                                    ))}
                                                </div>
                                            </div>
                                        );
                                    })}
                                </div>
                            ) : (
                                // Single Menu (no children)
                                <div>
                                    <div className="flex items-center justify-between mb-2">
                                        <div className="text-sm text-gray-500">
                                            {(permissions[menu.key]?.length || 0)}/{menu.actions.length} selected
                                        </div>
                                        <button
                                            className="text-xs text-primary hover:underline"
                                            onClick={() => toggleSelectAll(menu.key, [...menu.actions])}
                                        >
                                            {selectAll[menu.key] ? 'Unselect All' : 'Select All'}
                                        </button>
                                    </div>
                                    <div className="flex flex-wrap gap-2">
                                        {menu.actions.map((action) => (
                                            <label
                                                key={action}
                                                className={`flex items-center gap-2 text-xs px-3 py-1.5 rounded-md cursor-pointer transition-all ${
                                                    permissions[menu.key]?.includes(action)
                                                        ? 'bg-primary/10 border-primary text-primary'
                                                        : 'bg-white border-gray-200 text-gray-600 hover:bg-gray-50'
                                                } border`}
                                            >
                                                <input
                                                    type="checkbox"
                                                    className="rounded border-gray-300 text-primary focus:ring-primary"
                                                    checked={permissions[menu.key]?.includes(action) || false}
                                                    onChange={() => togglePermission(menu.key, action)}
                                                />
                                                <span className="capitalize">{action}</span>
                                            </label>
                                        ))}
                                    </div>
                                </div>
                            )}
                        </div>
                    );
                })}
            </div>
        </Offcanvas>
    );
};

export default RoleConfigure;
