import React, { useState, useCallback, useEffect, useRef } from 'react';
import { useEditor } from '@craftjs/core';
import { TopBar } from '../panels/topbar/TopBar';
import { LeftPanel } from '../panels/left/LeftPanel';
import { RightPanel } from '../panels/right/RightPanel';
import { MobilePanelBar } from '../panels/mobile/MobilePanelBar';
import { MobileSelectionToolbar } from '../panels/mobile/MobileSelectionToolbar';
import { Canvas } from './Canvas';
import { ContextMenu } from '../panels/context-menu/ContextMenu';
import { useContextMenu } from '../hooks/useContextMenu';
import { useKeyboardShortcuts } from '../hooks/useKeyboardShortcuts';
import { useIsMobile } from '../hooks/useIsMobile';
import { MobileChromeProvider } from '../state/MobileChromeContext';
import { LayerFocusProvider } from '../panels/left/LayerFocusContext';
import { DeviceMode } from '../types';

const SHOW_GUIDES_STORAGE_KEY = 'craft-show-guides';

function loadShowGuides(): boolean {
  try {
    const stored = window.localStorage.getItem(SHOW_GUIDES_STORAGE_KEY);
    return stored === null ? true : stored === '1';
  } catch {
    return true;
  }
}

export const EditorShell: React.FC = () => {
  const isMobile = useIsMobile();
  const [device, setDevice] = useState<DeviceMode>('desktop');
  // Phase A: default the canvas to the "mobile" preview width the first
  // time we detect a mobile viewport, so the frame fits without the user
  // having to reach for the device switcher (now tucked in TopBar's
  // overflow menu on mobile). Only fires once, and only if the device is
  // still at its initial default -- it must not fight a device the user
  // has already picked (e.g. from the overflow menu) on a later re-render.
  const mobileDeviceAppliedRef = useRef(false);
  useEffect(() => {
    if (isMobile && !mobileDeviceAppliedRef.current) {
      mobileDeviceAppliedRef.current = true;
      setDevice((current) => (current === 'desktop' ? 'mobile' : current));
    }
  }, [isMobile]);
  // Item 10: canvas dashed "guide" outlines toggle -- default ON, persisted
  // so the choice survives a reload. Lifted here (rather than owned by
  // TopBar or Canvas alone) because the toggle button lives in TopBar but
  // the `.guides-off` class it drives is applied to Canvas's
  // `.canvas-device-frame`, mirroring how `device` is already lifted for
  // the same reason.
  const [showGuides, setShowGuidesState] = useState<boolean>(loadShowGuides);
  const setShowGuides = useCallback((next: boolean) => {
    setShowGuidesState(next);
    try {
      window.localStorage.setItem(SHOW_GUIDES_STORAGE_KEY, next ? '1' : '0');
    } catch {
      // Storage unavailable (private browsing, etc.) -- in-memory state still works.
    }
  }, []);
  const { menuState, show: showMenu, hide: hideMenu } = useContextMenu();
  const { query } = useEditor();

  // Register keyboard shortcuts
  useKeyboardShortcuts();

  const handleContextMenu = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    // Find the selected node id
    let nodeId: string | null = null;
    try {
      const selected = query.getEvent('selected').all();
      if (selected.length > 0) {
        nodeId = selected[0];
      }
    } catch {
      // No selection
    }
    showMenu(e.clientX, e.clientY, nodeId);
  }, [query, showMenu]);

  return (
    // Mobile-A2: shared sheet/modal-open state (see MobileChromeContext) --
    // provided around the whole shell so TopBar's Templates/Head Code modal
    // state and MobilePanelBar's sheet state live in one place. Desktop
    // doesn't render MobilePanelBar and TopBar's desktop branch behaves
    // identically to before (same booleans, just sourced from context).
    <MobileChromeProvider>
      <LayerFocusProvider>
        <div className="editor-app">
          <TopBar
            device={device}
            onDeviceChange={setDevice}
            showGuides={showGuides}
            onToggleGuides={() => setShowGuides(!showGuides)}
          />
          <div className="editor-container">
            {!isMobile && <LeftPanel />}
            <div onContextMenu={handleContextMenu} style={{ flex: 1, display: 'flex', minWidth: 0 }}>
              <Canvas device={device} showGuides={showGuides} />
            </div>
            {!isMobile && <RightPanel />}
          </div>
          {isMobile && <MobilePanelBar />}
          {isMobile && <MobileSelectionToolbar />}
          <ContextMenu
            visible={menuState.visible}
            x={menuState.x}
            y={menuState.y}
            nodeId={menuState.nodeId}
            onClose={hideMenu}
          />
        </div>
      </LayerFocusProvider>
    </MobileChromeProvider>
  );
};
