import React, { useState, useEffect, useCallback } from 'react';
import {
    Box, IconButton, CircularProgress, Tooltip, Collapse,
} from '@mui/material';
import {
    ChevronLeft, ChevronRight,
    ExpandMore, ChevronRight as ChevronRightIcon,
    Home as HomeIcon, CalendarToday, DateRange, Event,
} from '@mui/icons-material';
import { useNavigationStore } from '../../stores/navigationStore';
import { useAuth } from '../../contexts/AuthContext';
import { NeoGraphNode } from '../../types/navigation';
import { logger } from '../../debugConfig';

interface TreeNode extends NeoGraphNode {
    has_children?: boolean;
    children?: TreeNode[];
}

const NODE_ICONS: Record<string, React.ElementType> = {
    User: HomeIcon,
    CalendarYear: CalendarToday,
    CalendarMonth: DateRange,
    CalendarWeek: DateRange,
    CalendarDay: Event,
};

const SIDEBAR_WIDTH = 220;

interface TreeItemProps {
    node: TreeNode;
    depth: number;
    onSelect: (node: TreeNode) => void;
    onExpand: (node: TreeNode) => Promise<TreeNode[]>;
    activeRoomId?: string;
}

function TreeItem({ node, depth, onSelect, onExpand, activeRoomId }: TreeItemProps) {
    const [expanded, setExpanded] = useState(false);
    const [children, setChildren] = useState<TreeNode[]>(node.children || []);
    const [loading, setLoading] = useState(false);

    const Icon = NODE_ICONS[node.node_type] || HomeIcon;
    const canExpand = node.has_children !== false && node.node_type !== 'CalendarDay';

    const handleToggle = async (e: React.MouseEvent) => {
        e.stopPropagation();
        if (!expanded && children.length === 0 && canExpand) {
            setLoading(true);
            try {
                const loaded = await onExpand(node);
                setChildren(loaded);
            } finally {
                setLoading(false);
            }
        }
        setExpanded(v => !v);
    };

    return (
        <Box>
            <Box
                onClick={() => onSelect(node)}
                sx={{
                    display: 'flex', alignItems: 'center',
                    pl: depth * 1.5 + 0.5, pr: 0.5, py: 0.4,
                    cursor: 'pointer', borderRadius: 1, mx: 0.5,
                    fontSize: '0.78rem', minHeight: 28,
                    bgcolor: 'transparent',
                    '&:hover': { bgcolor: 'action.hover' },
                }}
            >
                <Box sx={{ width: 18, flexShrink: 0, display: 'flex', alignItems: 'center' }}>
                    {canExpand && (
                        loading
                            ? <CircularProgress size={10} />
                            : (
                                <IconButton
                                    size="small" sx={{ p: 0, color: 'text.secondary' }}
                                    onClick={handleToggle}
                                >
                                    {expanded
                                        ? <ExpandMore sx={{ fontSize: 14 }} />
                                        : <ChevronRightIcon sx={{ fontSize: 14 }} />}
                                </IconButton>
                            )
                    )}
                </Box>
                <Icon sx={{ fontSize: 14, mr: 0.75, flexShrink: 0, color: 'text.secondary' }} />
                <Box sx={{
                    overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                    flexGrow: 1, color: 'text.primary',
                }}>
                    {node.label}
                </Box>
            </Box>
            {canExpand && (
                <Collapse in={expanded} timeout="auto">
                    {children.map(child => (
                        <TreeItem
                            key={child.neo4j_node_id}
                            node={child}
                            depth={depth + 1}
                            onSelect={onSelect}
                            onExpand={onExpand}
                            activeRoomId={activeRoomId}
                        />
                    ))}
                </Collapse>
            )}
        </Box>
    );
}

interface GraphSidebarProps {
    open: boolean;
    onToggle: () => void;
}

export function GraphSidebar({ open, onToggle }: GraphSidebarProps) {
    const { accessToken } = useAuth();
    const { navigateToNeoNode, context } = useNavigationStore();
    const [tree, setTree] = useState<TreeNode | null>(null);
    const [loading, setLoading] = useState(false);

    const apiBase = import.meta.env.VITE_API_BASE as string;

    const fetchTree = useCallback(async () => {
        if (!accessToken) return;
        setLoading(true);
        try {
            const res = await fetch(`${apiBase}/graph/tree`, {
                headers: { Authorization: `Bearer ${accessToken}` },
            });
            if (!res.ok) throw new Error(`Graph tree fetch failed: ${res.status}`);
            const data = await res.json();
            setTree(data.tree);
        } catch (err) {
            logger.error('graph-sidebar', 'Failed to load graph tree', err);
        } finally {
            setLoading(false);
        }
    }, [accessToken, apiBase]);

    useEffect(() => {
        if (open && !tree && accessToken) fetchTree();
    }, [open, tree, accessToken, fetchTree]);

    const handleExpand = useCallback(async (node: TreeNode): Promise<TreeNode[]> => {
        if (!accessToken) return [];
        const params = new URLSearchParams({
            neo4j_node_id: node.neo4j_node_id,
            neo4j_db_name: node.neo4j_db_name,
            node_type: node.node_type,
        });
        try {
            const res = await fetch(`${apiBase}/graph/node/children?${params}`, {
                headers: { Authorization: `Bearer ${accessToken}` },
            });
            if (!res.ok) return [];
            const data = await res.json();
            return data.children || [];
        } catch {
            return [];
        }
    }, [accessToken, apiBase]);

    return (
        <Box sx={{ position: 'relative', height: '100%', display: 'flex', flexShrink: 0 }}>
            <Box
                sx={{
                    width: open ? SIDEBAR_WIDTH : 0,
                    overflow: 'hidden',
                    transition: 'width 0.2s ease',
                    bgcolor: 'background.paper',
                    borderRight: 1,
                    borderColor: 'divider',
                    display: 'flex',
                    flexDirection: 'column',
                    height: '100%',
                }}
            >
                <Box sx={{ overflowY: 'auto', flexGrow: 1, pt: 1 }}>
                    {loading ? (
                        <Box sx={{ display: 'flex', justifyContent: 'center', pt: 3 }}>
                            <CircularProgress size={20} />
                        </Box>
                    ) : tree ? (
                        <TreeItem
                            node={tree}
                            depth={0}
                            onSelect={n => navigateToNeoNode(n)}
                            onExpand={handleExpand}
                            activeRoomId={context.node?.id}
                        />
                    ) : null}
                </Box>
            </Box>
            <Tooltip title={open ? 'Collapse sidebar' : 'Expand sidebar'} placement="right">
                <IconButton
                    onClick={onToggle}
                    size="small"
                    sx={{
                        position: 'absolute',
                        right: -14,
                        top: '50%',
                        transform: 'translateY(-50%)',
                        zIndex: 10,
                        bgcolor: 'background.paper',
                        border: 1,
                        borderColor: 'divider',
                        width: 22,
                        height: 44,
                        borderRadius: '0 4px 4px 0',
                        '&:hover': { bgcolor: 'action.hover' },
                    }}
                >
                    {open
                        ? <ChevronLeft sx={{ fontSize: 14 }} />
                        : <ChevronRight sx={{ fontSize: 14 }} />}
                </IconButton>
            </Tooltip>
        </Box>
    );
}
