import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import ReactDOM from 'react-dom/client';

import { Sidebar } from './components/Sidebar';
import { Canvas } from './components/Canvas';
import { TopToolbar } from './components/TopToolbar';
import { CanvasControls } from './components/CanvasControls';
import { FurnitureToolbar } from './components/FurnitureToolbar';
import { BaguaDatabaseModal, getBaguaDataForGua } from './components/Bagua';
import { SettingsModal } from './components/SettingsModal';
import { useHistoryState } from './hooks/useHistoryState';
import { useCanvasInteraction } from './hooks/useCanvasInteraction';
import { createInitialState } from './utils';
import { calculateFlyingStarChart } from './logic/huyenKhong';
import type { FurnitureImage, PlacedFurniture, UndoableState } from './types';

const App = () => {
  const [sidebarOpen, setSidebarOpen] = useState(true);
  const [activeTab, setActiveTab] = useState('draw');
  const [furnitureTab, setFurnitureTab] = useState('basic');
  const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
  const [isBaguaModalOpen, setIsBaguaModalOpen] = useState(false);
  const [furnitureImages, setFurnitureImages] = useState<FurnitureImage[]>([]);
  const [isMapInteractive, setIsMapInteractive] = useState(false);

  const svgRef = useRef<SVGSVGElement>(null);

  const {
    currentState,
    setCurrentState: updateStateAndRecordHistory,
    undo,
    redo,
    canUndo,
    canRedo,
    setInitialState,
  } = useHistoryState<UndoableState>(createInitialState());
  
  const { 
      drawnRect, placedFurniture, fengShuiRotation, showBaTrach, baTrachOpacity, 
      selectedGua, showHuyenKhong, huyenKhongPeriod, huyenKhongFacingDegree, showDaiQuai, gridSettings, showMap, googleMapsApiKey, mapLocation
  } = currentState;

  const {
    viewBox,
    livePlacedFurniture,
    selectedFurnitureId,
    toolbarPosition,
    canvasProps,
    panMode,
    setPanMode,
    handleZoom,
    setSelectedFurnitureId,
    handleDeletePlacedFurniture,
    handleDuplicatePlacedFurniture,
    handleDimensionChange,
    commitDimensionChange,
    handleColorChange,
    recenterView,
  } = useCanvasInteraction({
    svgRef,
    currentState,
    updateStateAndRecordHistory,
    furnitureImages
  });

  const selectedItem = livePlacedFurniture.find(f => f.id === selectedFurnitureId);
  const currentBaguaData = getBaguaDataForGua(selectedGua);
  const flyingStarChart = useMemo(() => calculateFlyingStarChart(huyenKhongPeriod, huyenKhongFacingDegree), [huyenKhongPeriod, huyenKhongFacingDegree]);

  // Load from LocalStorage
  useEffect(() => {
    let loadedState = createInitialState();
    try {
      const savedImages = localStorage.getItem('furnitureImages');
      if (savedImages) setFurnitureImages(JSON.parse(savedImages));

      const savedState = localStorage.getItem('appState');
       if (savedState) {
         const parsed = JSON.parse(savedState);
         // Migration for old data structures if necessary
         loadedState = {
           ...loadedState,
           ...parsed,
           huyenKhongPeriod: parsed.huyenKhongPeriod || 9, // Add default for old states
           huyenKhongFacingDegree: parsed.huyenKhongFacingDegree || 0,
           placedFurniture: parsed.placedFurniture?.map((item: any) => ({
             id: item.id,
             furnitureId: item.furnitureId,
             width: item.width,
             height: item.height,
             cx: item.cx ?? item.x + item.width / 2,
             cy: item.cy ?? item.y + item.height / 2,
             rotation: item.rotation ?? 0,
             color: item.color,
           })) || [],
         };
       }
    } catch (error) { console.error("Failed to load from localStorage", error); }
    setInitialState(loadedState);
  }, []);

  // Save to LocalStorage
  useEffect(() => { localStorage.setItem('furnitureImages', JSON.stringify(furnitureImages)); }, [furnitureImages]);
  useEffect(() => { localStorage.setItem('appState', JSON.stringify(currentState)); }, [currentState]);

  // Keyboard shortcuts
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
        if ((e.ctrlKey || e.metaKey) && e.key === 'z') { e.preventDefault(); undo(); }
        if ((e.ctrlKey || e.metaKey) && e.key === 'y') { e.preventDefault(); redo(); }
        if (e.key === 'Delete' || e.key === 'Backspace') { if (selectedFurnitureId) handleDeletePlacedFurniture(); }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [selectedFurnitureId, undo, redo, handleDeletePlacedFurniture]);

  const handleDraw = useCallback((widthStr: string, heightStr: string) => {
    const numWidth = parseFloat(widthStr);
    const numHeight = parseFloat(heightStr);
    if (!isNaN(numWidth) && !isNaN(numHeight) && numWidth > 0 && numHeight > 0) {
      updateStateAndRecordHistory({ drawnRect: { width: numWidth * 100, height: numHeight * 100 } });
    }
  }, [updateStateAndRecordHistory]);
  
  const handleMapToggle = useCallback(() => {
    updateStateAndRecordHistory({ showMap: !showMap });
    if (showMap) { // If we are turning it off
        setIsMapInteractive(false);
    }
  }, [showMap, updateStateAndRecordHistory]);
  
  const handleToggleMapInteraction = useCallback(() => {
      if (showMap) {
          setIsMapInteractive(prev => !prev);
      }
  }, [showMap]);

  return (
    <div className="w-screen h-screen bg-gray-100 flex overflow-hidden relative">
      <Sidebar
        isOpen={sidebarOpen}
        setIsOpen={setSidebarOpen}
        activeTab={activeTab}
        setActiveTab={setActiveTab}
        furnitureTab={furnitureTab}
        setFurnitureTab={setFurnitureTab}
        setIsSettingsModalOpen={setIsSettingsModalOpen}
        selectedItem={selectedItem}
        furnitureImages={furnitureImages}
        setFurnitureImages={setFurnitureImages}
        onDraw={handleDraw}
        onDimensionChange={handleDimensionChange}
        onCommitDimensionChange={commitDimensionChange}
        // Feng Shui Props
        fengShuiRotation={fengShuiRotation}
        showBaTrach={showBaTrach}
        onStateChange={updateStateAndRecordHistory}
        onOpenBaguaModal={() => setIsBaguaModalOpen(true)}
        selectedGua={selectedGua}
        baTrachOpacity={baTrachOpacity}
        showHuyenKhong={showHuyenKhong}
        huyenKhongPeriod={huyenKhongPeriod}
        huyenKhongFacingDegree={huyenKhongFacingDegree}
        showDaiQuai={showDaiQuai}
      />
      
      <div className="flex-1 flex flex-col relative">
        <Canvas
          svgRef={svgRef}
          viewBox={viewBox}
          canvasProps={canvasProps}
          panMode={panMode}
          drawnRect={drawnRect}
          gridSettings={gridSettings}
          showBaTrach={showBaTrach}
          fengShuiRotation={fengShuiRotation}
          baTrachOpacity={baTrachOpacity}
          currentBaguaData={currentBaguaData}
          livePlacedFurniture={livePlacedFurniture}
          furnitureImages={furnitureImages}
          selectedItem={selectedItem}
          showMap={showMap}
          googleMapsApiKey={googleMapsApiKey}
          mapLocation={mapLocation}
          isMapInteractive={isMapInteractive}
          showHuyenKhong={showHuyenKhong}
          flyingStarChart={flyingStarChart}
          showDaiQuai={showDaiQuai}
        />

        <TopToolbar onUndo={undo} onRedo={redo} canUndo={canUndo} canRedo={canRedo} />
        <CanvasControls 
            onZoom={handleZoom} 
            onPanToggle={() => setPanMode(!panMode)} 
            panMode={panMode} 
            onMapToggle={handleMapToggle} 
            showMap={showMap}
            mapLocation={mapLocation}
            onLocationChange={(newLocation) => updateStateAndRecordHistory({ mapLocation: newLocation })}
            isMapInteractive={isMapInteractive}
            onToggleMapInteraction={handleToggleMapInteraction}
            onRecenterView={recenterView}
        />
        <FurnitureToolbar
          selectedItem={selectedItem}
          position={toolbarPosition}
          onColorChange={handleColorChange}
          onDuplicate={handleDuplicatePlacedFurniture}
          onDelete={handleDeletePlacedFurniture}
        />
      </div>

      <BaguaDatabaseModal isOpen={isBaguaModalOpen} onClose={() => setIsBaguaModalOpen(false)} data={currentBaguaData} selectedGua={selectedGua} />
      <SettingsModal 
        isOpen={isSettingsModalOpen} 
        onClose={() => setIsSettingsModalOpen(false)}
        gridSettings={gridSettings}
        googleMapsApiKey={googleMapsApiKey}
        onSettingsChange={(changedSettings) => updateStateAndRecordHistory(changedSettings)}
      />
       <style>{`.toggle-checkbox:checked { right: 0; border-color: #34D399; } .toggle-checkbox:checked + .toggle-label { background-color: #34D399; }`}</style>
    </div>
  );
};

const rootElement = document.getElementById('root');
if (rootElement) {
  const root = ReactDOM.createRoot(rootElement);
  root.render(<React.StrictMode><App /></React.StrictMode>);
} else {
  console.error("Failed to find the root element with id 'root'.");
}