import { useEffect, useCallback, useState } from 'react';
import {
    ZoomIn, ZoomOut, Grid3X3, Magnet, Undo2, Redo2,
    Save, Download, Plus, MousePointer, Move, Square,
    ChevronDown, Layers, Settings, Home, Loader2
} from 'lucide-react';
import { Link } from 'react-router-dom';
import { useLayoutStore, ROOM_COLORS, LayoutRoom } from '../../stores/layoutStore';
import { LayoutCanvas } from './components/LayoutCanvas';
import { LayersPanel } from './components/LayersPanel';
import { ElementsPanel } from './components/ElementsPanel';
import { InspectorPanel } from './components/InspectorPanel';
import { FloorSelector } from './components/FloorSelector';
import { PropertySetup } from './components/PropertySetup';
import { AddBuildingModal } from './components/AddBuildingModal';
import { AddFloorModal } from './components/AddFloorModal';
import { PlantInventory } from './components/PlantInventory';
import { layoutApi } from '../../lib/layoutApi';

export default function LayoutDesignerPage() {
    const {
        zoom, zoomIn, zoomOut, resetView,
        showGrid, toggleGrid,
        snapToGrid, toggleSnap,
        activeTool, setActiveTool,
        canUndo, canRedo, undo, redo,
        selectedIds,
        rooms,
        sections,
        property,
        buildingId,
        floorId,
        setProperty,
        setBuilding,
        setFloor,
        loadRooms,
        loadSections,
        clearRooms,
    } = useLayoutStore();

    const [loading, setLoading] = useState(true);
    const [saving, setSaving] = useState(false);
    const [showFloorSelector, setShowFloorSelector] = useState(false);
    const [showPropertySetup, setShowPropertySetup] = useState(false);
    const [showAddFloorModal, setShowAddFloorModal] = useState(false);
    const [showAddBuildingModal, setShowAddBuildingModal] = useState(false);
    const [buildingForFloor, setBuildingForFloor] = useState<string | null>(null);
    const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
    const [sidebarMode, setSidebarMode] = useState<'design' | 'plants'>('design');

    // Load properties on mount
    useEffect(() => {
        loadProperties();
    }, []);

    // Track unsaved changes
    useEffect(() => {
        setHasUnsavedChanges(rooms.length > 0);
    }, [rooms, sections]);

    // Load positions for selected room
    useEffect(() => {
        if (selectedIds.length === 1 && selectedIds[0].startsWith('room-')) {
            const roomId = selectedIds[0].replace('room-', '');
            // Check if we need to load positions (if any section created but has no positions loaded)
            const currSections = sections.filter(s => s.roomId === roomId);
            const needsLoad = currSections.some(s => (!s.positions || s.positions.length === 0) && (s.rows * s.columns > 0));

            if (needsLoad && currSections.length > 0) {
                layoutApi.getRoomSections(roomId).then(apiSections => {
                    loadSections(apiSections.map(s => ({
                        id: s.id,
                        roomId: s.roomId,
                        name: s.name,
                        code: s.code,
                        type: s.type as any,
                        position: { x: s.posX, y: s.posY },
                        size: { width: s.width, height: s.height },
                        rows: s.rows,
                        columns: s.columns,
                        spacing: s.spacing || 12,
                        positions: s.positions as any
                    })));
                }).catch(console.error);
            }
        }
    }, [selectedIds]); // Intentionally omitting sections to avoid loop, we rely on selection change or explicit refresh
    // Wait, if sections update (e.g. added new section locally), we want to fetch positions?
    // If I add a section locally, it has positions: []. needsLoad is true.
    // Effect runs. Fetches from backend.
    // backend might NOT have it yet if I haven't saved!
    // If I add section locally, I should generate positions locally too?
    // Currently AddSectionDialog does NOT generate positions locally, it sets [].
    // If I haven't saved, backend returns nothing or old data.
    // So my local new section would be overwritten by backend old section data (missing)?
    // Or I'm updating sections by ID.
    // If new section has random ID, backend doesn't have it. `updateSections` won't find it to update?
    // No, `updateSections` adds if not found.
    // But backend `getRoomSections` only returns SAVED sections.
    // So `updateSections` only touches backend sections.
    // The local new section remains untouched?
    // Yes.
    // But `needsLoad` will still be true for the local section.
    // So loop continues?
    // If `sections` is in deps -> Infinite Loop.
    // If `sections` NOT in deps -> Runs once on selection.
    // Logic: Only load when *Selection* changes to a room.
    // This is safer.


    const loadProperties = async () => {
        setLoading(true);
        try {
            const properties = await layoutApi.getProperties();
            if (properties.length > 0) {
                const prop = properties[0];
                setProperty({
                    id: prop.id,
                    name: prop.name,
                    address: prop.address,
                    buildings: prop.buildings.map(b => ({
                        id: b.id,
                        name: b.name,
                        code: b.code,
                        floors: b.floors.map(f => ({
                            id: f.id,
                            name: f.name,
                            number: f.number,
                            width: f.width * 20, // Convert feet to pixels
                            height: f.height * 20,
                        }))
                    }))
                });

                // Select first building and floor
                if (prop.buildings.length > 0) {
                    const firstBuilding = prop.buildings[0];
                    setBuilding(firstBuilding.id);

                    if (firstBuilding.floors.length > 0) {
                        const firstFloor = firstBuilding.floors[0];
                        setFloor(firstFloor.id);

                        // Load rooms for this floor
                        loadFloorRooms(firstFloor.id);
                    }
                }
            } else {
                setShowPropertySetup(true);
            }
        } catch (error) {
            console.error('Failed to load properties:', error);
        } finally {
            setLoading(false);
        }
    };

    const loadFloorRooms = async (floorId: string) => {
        try {
            const floor = await layoutApi.getFloor(floorId);
            // Convert API rooms to store format
            const storeRooms: LayoutRoom[] = floor.rooms.map(r => ({
                id: r.id,
                name: r.name,
                code: r.code,
                type: r.type as any,
                floorId: r.floorId,
                position: { x: r.posX, y: r.posY },
                size: { width: r.width, height: r.height },
                rotation: r.rotation,
                color: r.color,
                sections: (r.sections || []).map((s: any) => ({
                    id: s.id,
                    roomId: s.roomId,
                    name: s.name,
                    code: s.code,
                    type: s.type,
                    position: { x: s.posX, y: s.posY },
                    size: { width: s.width, height: s.height },
                    rows: s.rows,
                    columns: s.columns,
                    spacing: s.spacing,
                }))
            }));
            loadRooms(storeRooms);
            setHasUnsavedChanges(false);
        } catch (error) {
            console.error('Failed to load floor rooms:', error);
        }
    };

    const handleSelectFloor = (newFloorId: string, newBuildingId: string) => {
        if (hasUnsavedChanges) {
            if (!confirm('You have unsaved changes. Discard and switch floors?')) {
                return;
            }
        }
        setBuilding(newBuildingId);
        setFloor(newFloorId);
        loadFloorRooms(newFloorId);
    };

    const handleSave = async () => {
        if (!floorId) return;

        setSaving(true);
        try {
            // Convert store rooms to API format
            const apiRooms = rooms.map(r => ({
                id: r.id,
                name: r.name,
                code: r.code,
                type: r.type,
                posX: r.position.x,
                posY: r.position.y,
                width: r.size.width,
                height: r.size.height,
                rotation: r.rotation,
                color: r.color,
                sections: sections
                    .filter(s => s.roomId === r.id)
                    .map(s => ({
                        id: s.id,
                        name: s.name,
                        code: s.code,
                        type: s.type,
                        posX: s.position.x,
                        posY: s.position.y,
                        width: s.size.width,
                        height: s.size.height,
                        rows: s.rows,
                        columns: s.columns,
                        spacing: s.spacing
                    }))
            }));

            await layoutApi.saveFloorLayout(floorId, apiRooms as any);
            setHasUnsavedChanges(false);
        } catch (error) {
            console.error('Failed to save layout:', error);
        } finally {
            setSaving(false);
        }
    };

    // Keyboard shortcuts
    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            // Ignore if typing in input
            if ((e.target as HTMLElement).tagName === 'INPUT') return;

            const isMod = e.metaKey || e.ctrlKey;

            if (isMod && e.key === 'z' && !e.shiftKey) {
                e.preventDefault();
                undo();
            }
            if (isMod && e.key === 'z' && e.shiftKey) {
                e.preventDefault();
                redo();
            }
            if (isMod && e.key === 's') {
                e.preventDefault();
                handleSave();
            }
            if (e.key === 'g' && !isMod) {
                toggleGrid();
            }
            if (e.key === 's' && !isMod) {
                toggleSnap();
            }
            if (e.key === '=' || e.key === '+') {
                zoomIn();
            }
            if (e.key === '-') {
                zoomOut();
            }
            if (e.key === '0' && isMod) {
                e.preventDefault();
                resetView();
            }
            if (e.key === 'v') {
                setActiveTool('select');
            }
            if (e.key === 'h') {
                setActiveTool('pan');
            }
            if (e.key === 'r') {
                setActiveTool('room');
            }
            if (e.key === 'Escape') {
                useLayoutStore.getState().clearSelection();
                setActiveTool('select');
            }
        };

        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, [floorId, rooms]);

    const currentBuilding = property?.buildings.find(b => b.id === buildingId);
    const currentFloor = currentBuilding?.floors.find(f => f.id === floorId);

    if (loading) {
        return (
            <div className="h-screen flex items-center justify-center bg-neutral-950">
                <div className="flex flex-col items-center gap-4">
                    <Loader2 className="w-8 h-8 text-accent animate-spin" />
                    <p className="text-neutral-400">Loading layout...</p>
                </div>
            </div>
        );
    }

    return (
        <div className="h-screen flex flex-col bg-neutral-950 text-white overflow-hidden">
            {/* Top Toolbar */}
            <header className="h-14 bg-neutral-900/80 backdrop-blur-xl border-b border-white/10 flex items-center justify-between px-4 shrink-0">
                <div className="flex items-center gap-4">
                    <Link to="/" className="flex items-center gap-2 text-neutral-400 hover:text-white transition-colors">
                        <Home size={18} />
                    </Link>
                    <div className="w-px h-6 bg-white/10" />
                    <h1 className="font-semibold text-lg flex items-center gap-2">
                        <Layers size={18} className="text-accent" />
                        Layout Designer
                    </h1>

                    {/* Building/Floor Selector */}
                    <div className="flex items-center gap-2 ml-4">
                        <button
                            onClick={() => setShowFloorSelector(true)}
                            className="flex items-center gap-2 px-3 py-1.5 bg-neutral-800 hover:bg-neutral-700 rounded-md text-sm transition-colors"
                        >
                            {currentBuilding?.name || 'Select Building'}
                            <ChevronDown size={14} />
                        </button>
                        <button
                            onClick={() => setShowFloorSelector(true)}
                            className="flex items-center gap-2 px-3 py-1.5 bg-neutral-800 hover:bg-neutral-700 rounded-md text-sm transition-colors"
                        >
                            {currentFloor?.name || 'Floor 1'}
                            <ChevronDown size={14} />
                        </button>
                    </div>
                </div>

                {/* Center Tools */}
                <div className="flex items-center gap-1 bg-neutral-800/50 rounded-md p-1">
                    <ToolButton
                        icon={<MousePointer size={16} />}
                        active={activeTool === 'select'}
                        onClick={() => setActiveTool('select')}
                        tooltip="Select (V)"
                    />
                    <ToolButton
                        icon={<Move size={16} />}
                        active={activeTool === 'pan'}
                        onClick={() => setActiveTool('pan')}
                        tooltip="Pan (H)"
                    />
                    <ToolButton
                        icon={<Square size={16} />}
                        active={activeTool === 'room'}
                        onClick={() => setActiveTool('room')}
                        tooltip="Add Room (R)"
                    />

                    <div className="w-px h-6 bg-white/10 mx-1" />

                    <ToolButton
                        icon={<ZoomOut size={16} />}
                        onClick={zoomOut}
                        tooltip="Zoom Out (-)"
                    />
                    <span className="text-xs text-neutral-400 w-12 text-center">
                        {Math.round(zoom * 100)}%
                    </span>
                    <ToolButton
                        icon={<ZoomIn size={16} />}
                        onClick={zoomIn}
                        tooltip="Zoom In (+)"
                    />

                    <div className="w-px h-6 bg-white/10 mx-1" />

                    <ToolButton
                        icon={<Grid3X3 size={16} />}
                        active={showGrid}
                        onClick={toggleGrid}
                        tooltip="Toggle Grid (G)"
                    />
                    <ToolButton
                        icon={<Magnet size={16} />}
                        active={snapToGrid}
                        onClick={toggleSnap}
                        tooltip="Snap to Grid (S)"
                    />

                    <div className="w-px h-6 bg-white/10 mx-1" />

                    <ToolButton
                        icon={<Undo2 size={16} />}
                        onClick={undo}
                        disabled={!canUndo()}
                        tooltip="Undo (⌘Z)"
                    />
                    <ToolButton
                        icon={<Redo2 size={16} />}
                        onClick={redo}
                        disabled={!canRedo()}
                        tooltip="Redo (⌘⇧Z)"
                    />
                </div>

                {/* Right Actions */}
                <div className="flex items-center gap-2">
                    {hasUnsavedChanges && (
                        <span className="text-xs text-warning mr-2">● Unsaved</span>
                    )}
                    <button className="flex items-center gap-2 px-3 py-1.5 bg-neutral-700 hover:bg-neutral-600 rounded-md text-sm transition-colors">
                        <Download size={14} />
                        Export
                    </button>
                    <button
                        onClick={handleSave}
                        disabled={saving || !hasUnsavedChanges}
                        className="flex items-center gap-2 px-3 py-1.5 bg-accent hover:bg-accent-light disabled:bg-neutral-700 disabled:text-neutral-500 rounded-md text-sm font-medium transition-colors"
                    >
                        {saving ? (
                            <Loader2 size={14} className="animate-spin" />
                        ) : (
                            <Save size={14} />
                        )}
                        {saving ? 'Saving...' : 'Save'}
                    </button>
                </div>
            </header>

            {/* Main Content */}
            <div className="flex-1 flex min-h-0">
                {/* Left Sidebar */}
                <aside className="w-64 bg-neutral-900/50 border-r border-white/10 flex flex-col shrink-0">
                    <div className="flex p-2 gap-1 border-b border-white/10">
                        <button
                            onClick={() => setSidebarMode('design')}
                            className={`flex-1 text-xs py-1.5 rounded-md transition-colors ${sidebarMode === 'design' ? "bg-accent text-white font-medium" : "text-neutral-400 hover:bg-neutral-800"}`}
                        >
                            Design
                        </button>
                        <button
                            onClick={() => setSidebarMode('plants')}
                            className={`flex-1 text-xs py-1.5 rounded-md transition-colors ${sidebarMode === 'plants' ? "bg-accent text-white font-medium" : "text-neutral-400 hover:bg-neutral-800"}`}
                        >
                            Plants
                        </button>
                    </div>

                    {sidebarMode === 'design' ? (
                        <div className="flex-1 flex flex-col overflow-hidden">
                            <LayersPanel />
                            <div className="border-t border-white/10" />
                            <ElementsPanel />
                        </div>
                    ) : (
                        <PlantInventory />
                    )}
                </aside>

                {/* Canvas */}
                <main className="flex-1 relative overflow-hidden bg-neutral-950">
                    <LayoutCanvas />

                    {/* Status Bar */}
                    <div className="absolute bottom-0 left-0 right-0 h-7 bg-neutral-900/80 backdrop-blur-xl border-t border-white/10 flex items-center justify-between px-4 text-[11px] text-neutral-400">
                        <div className="flex items-center gap-3">
                            <span>{rooms.length} rooms</span>
                            <span className="text-neutral-600">·</span>
                            <span>{selectedIds.length} selected</span>
                        </div>
                        <div className="flex items-center gap-3">
                            <span>Grid: {showGrid ? 'On' : 'Off'}</span>
                            <span>Snap: {snapToGrid ? 'On' : 'Off'}</span>
                        </div>
                    </div>
                </main>

                {/* Right Sidebar - Inspector */}
                <aside className="w-72 bg-neutral-900/50 border-l border-white/10 shrink-0">
                    <InspectorPanel />
                </aside>
            </div>

            {/* Modals */}
            <FloorSelector
                isOpen={showFloorSelector}
                onClose={() => setShowFloorSelector(false)}
                onSelectFloor={handleSelectFloor}
                onAddProperty={() => setShowPropertySetup(true)}
                onAddBuilding={() => setShowAddBuildingModal(true)}
                onAddFloor={(bId) => {
                    setBuildingForFloor(bId);
                    setShowAddFloorModal(true);
                }}
            />
            <PropertySetup
                isOpen={showPropertySetup}
                onClose={() => setShowPropertySetup(false)}
                onCreated={loadProperties}
            />
            <AddBuildingModal
                isOpen={showAddBuildingModal}
                onClose={() => setShowAddBuildingModal(false)}
                propertyId={property?.id || null}
                onCreated={loadProperties}
            />
            <AddFloorModal
                isOpen={showAddFloorModal}
                onClose={() => setShowAddFloorModal(false)}
                buildingId={buildingForFloor}
                onCreated={(newFloorId) => {
                    loadProperties().then(() => {
                        if (buildingForFloor) {
                            handleSelectFloor(newFloorId, buildingForFloor);
                        }
                    });
                }}
            />
        </div>
    );
}

// Tool Button Component
function ToolButton({
    icon,
    active,
    onClick,
    disabled,
    tooltip
}: {
    icon: React.ReactNode;
    active?: boolean;
    onClick: () => void;
    disabled?: boolean;
    tooltip?: string;
}) {
    return (
        <button
            onClick={onClick}
            disabled={disabled}
            title={tooltip}
            className={`
                p-2 rounded-md transition-all
                ${active
                    ? 'bg-accent text-white'
                    : 'text-neutral-400 hover:text-white hover:bg-neutral-700'
                }
                ${disabled ? 'opacity-30 cursor-not-allowed' : ''}
            `}
        >
            {icon}
        </button>
    );
}
