import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
import { editTask } from "../../../../Settings/store/taskSlice";
import { MultiSelect, Box } from "@mantine/core";
import { IconLink } from '@tabler/icons-react';
import { translate } from '../../../../../utils/i18n';
import { notifications } from '@mantine/notifications';
import { IconAlertTriangle } from '@tabler/icons-react';

const TaskDependency = ({ taskId, currentDependencies, disabled, onChange }) => {
    const dispatch = useDispatch();
    const { loggedUserId } = useSelector((state) => state.auth.user);
    const { loggedInUser } = useSelector((state) => state.auth.session);

    // Grab all project tasks from state to populate the dropdown
    const { columns, childColumns, allTasks, ganttTasks } = useSelector((state) => state.settings.task);

    const [selectedDependencies, setSelectedDependencies] = useState(
        currentDependencies ? currentDependencies.map(id => id.toString()) : []
    );

    useEffect(() => {
        if (currentDependencies) {
            setSelectedDependencies(currentDependencies.map(id => id.toString()));
        }
    }, [currentDependencies]);

    // Build task options
    const tasksOptions = [];
    if (allTasks && allTasks.length > 0) {
        allTasks.forEach(t => tasksOptions.push({ value: t.id.toString(), label: t.name }));
    }
    if (ganttTasks && ganttTasks.length > 0) {
        ganttTasks.forEach(t => tasksOptions.push({ value: t.id.toString(), label: t.name }));
    }
    if (columns) {
        Object.values(columns).forEach(columnTasks => {
            if (Array.isArray(columnTasks)) {
                columnTasks.forEach(t => tasksOptions.push({ value: t.id.toString(), label: t.name }));
            }
        });
    }
    if (childColumns) {
        Object.values(childColumns).forEach(columnTasks => {
            if (Array.isArray(columnTasks)) {
                columnTasks.forEach(t => tasksOptions.push({ value: t.id.toString(), label: t.name }));
            }
        });
    }

    // Filter out the current task so it cannot depend on itself
    // Also deduplicate in case combinations of state arrays produced duplicates
    const availableTasksMap = new Map();
    tasksOptions.forEach(t => {
        if (t.value !== taskId?.toString() && !availableTasksMap.has(t.value)) {
            availableTasksMap.set(t.value, t);
        }
    });
    const availableTasks = Array.from(availableTasksMap.values());

    const handleChange = (val) => {
        // Build a dependency map from all tasks (excluding current task's old deps)
        // to detect circular dependencies before saving.
        const depMap = {};
        tasksOptions.forEach(t => { depMap[t.value] = []; });
        allTasks && allTasks.forEach(t => {
            if (t.id.toString() !== taskId?.toString() && t.dependencies) {
                depMap[t.id.toString()] = t.dependencies.map(String);
            }
        });
        ganttTasks && ganttTasks.forEach(t => {
            if (t.id.toString() !== taskId?.toString() && t.dependencies) {
                depMap[t.id.toString()] = t.dependencies.map(String);
            }
        });
        // Set the proposed new deps for this task
        depMap[taskId?.toString()] = val;

        // DFS reachability: check if taskId is reachable from any dep in val
        const isCircular = val.some(depId => {
            const visited = new Set();
            const stack = [depId];
            while (stack.length > 0) {
                const node = stack.pop();
                if (node === taskId?.toString()) return true;
                if (visited.has(node)) continue;
                visited.add(node);
                const children = depMap[node] || [];
                children.forEach(c => stack.push(c));
            }
            return false;
        });

        if (isCircular) {
            notifications.show({
                color: 'red',
                title: translate('Circular Dependency Detected'),
                message: translate('This selection would create a circular dependency and has been blocked.'),
                icon: <IconAlertTriangle />,
                autoClose: 4000,
            });
            return; // Abort — do not update state or dispatch
        }

        setSelectedDependencies(val);
        if (onChange) {
            onChange(val);
        }
        if (taskId) {
            dispatch(editTask({
                id: taskId,
                data: {
                    dependencies: val,
                    updated_by: loggedInUser ? loggedInUser.loggedUserId : loggedUserId
                }
            }));
        }
    };

    return (
        <Box className="flex items-start w-full gap-2">
            <Box className="w-[30px] h-[30px] rounded-full flex items-center justify-center flex-shrink-0 pt-[4px]">
                <IconLink size="20" color="#ED7D31" stroke={1.25} />
            </Box>
            <Box className="flex-grow max-w-[calc(100%-40px)]">
                <MultiSelect
                    data={availableTasks}
                    value={selectedDependencies}
                    onChange={handleChange}
                    placeholder={translate("Dependencies...")}
                    searchable
                    clearable
                    disabled={disabled}
                    variant="unstyled"
                    styles={{
                        input: { minHeight: '30px', paddingLeft: 0, paddingRight: 0, fontSize: '12px' },
                        value: { fontSize: '11px' }
                    }}
                />
            </Box>
        </Box>
    );
};

export default TaskDependency;
