// Copyright (c) 2026 MASA_DEV_WORKS. All rights reserved.
// ==========================================================
// app.jsx　
// G_Mint Engine - Main Application Entry (Node.js/Vite版) 
// 2026.10.07 13:13 ver UP
// ==========================================================

import React, { useState, useEffect, useReducer } from 'react';
import { createRoot } from 'react-dom/client';

// ★ 1. 個室（モジュール）になった各ファイルから部品を取り寄せる（import）！
import { IntroScreen, Header, UpgradeModal, Resizer, FailsafeModal, LicensesModal } from './weaver_components.jsx';
import { LeftMiniViews, MainWorkspace, RightPanel } from './weaver_panels.jsx';
import { NumpadInjector } from './gdl_numpad_widget.jsx';
import { getInitialState, appReducer } from './gdl_state.jsx';
import { SettingsPanel, getDefaults } from './weaver_settings_panel.jsx';
import { setGlobalRefOpacity } from './weaver_canvas.jsx';

const App = () => {
  // --- 状態管理 (State) ---
  const [state, dispatch] = useReducer(appReducer, null, getInitialState);
  const [introDone, setIntroDone] = useState(false);

  const [isSettingsOpen, setIsSettingsOpen] = useState(false);

  // パネルの幅・高さ
  const uiSession = JSON.parse(localStorage.getItem('gdl_weaver_ui_session') || '{}');
  const defaults = getDefaults();
  const getUiState = (key, defaultVal) => (!defaults.autoSaveProject && uiSession[key] !== undefined) ? uiSession[key] : (defaults[key] !== undefined ? defaults[key] : defaultVal);

  const [leftWidth, setLeftWidth] = useState(() => getUiState('leftWidth', 500));
  const [rightWidth, setRightWidth] = useState(() => getUiState('rightWidth', 400));
  const [codeWidth, setCodeWidth] = useState(() => getUiState('codeWidth', 350));
  const [codeHeight, setCodeHeight] = useState(200);
  const [constantWidth, setConstantWidth] = useState(() => getUiState('constantWidth', 250));
  const [constantHeight, setConstantHeight] = useState(200);

  // GDLコードプレビューの配置設定 (0: 縦1列, 1: 横2列, 2: 3列)
  const [previewLayoutMode, setPreviewLayoutMode] = useState(() => getUiState('previewLayoutMode', 1));

  useEffect(() => {
    localStorage.setItem('gdl_weaver_preview_layout_mode', previewLayoutMode.toString());
    localStorage.setItem('gdl_weaver_ui_session', JSON.stringify({
      leftWidth, rightWidth, codeWidth, constantWidth, previewLayoutMode
    }));
  }, [previewLayoutMode, leftWidth, rightWidth, codeWidth, constantWidth]);

  // ツールの状態
  const [rulerMode, setRulerMode] = useState(false);
  const [multiSelectedPointIds, setMultiSelectedPointIds] = useState([]);
  const [deletePointsConfirm, setDeletePointsConfirm] = useState(null);
  const [modifierKeys, setModifierKeys] = useState({ shift: false, ctrl: false });

  // アップグレードモーダル
  const [upgradeModalOpen, setUpgradeModalOpen] = useState(false);
  const [upgradeFeature, setUpgradeFeature] = useState('');
  const [upgradeReqPlan, setUpgradeReqPlan] = useState('PRO');

  // フェイルセーフモーダル
  const [failsafeModalOpen, setFailsafeModalOpen] = useState(false);
  const [failsafeReason, setFailsafeReason] = useState(null);

  // ライセンスモーダル
  const [licensesModalOpen, setLicensesModalOpen] = useState(false);

  // トランジション（アニメーション）
  const [transitioning, setTransitioning] = useState(false);

  // --- イベントリスナー ---
  // キーボードイベントの監視 (Shift, Ctrlキーなど)
  useEffect(() => {
    const handleKeyDown = (e) => {
      if (e.key === 'Shift') setModifierKeys(prev => ({ ...prev, shift: true }));
      if (e.key === 'Control' || e.key === 'Meta') setModifierKeys(prev => ({ ...prev, ctrl: true }));
      if ((e.ctrlKey || e.metaKey) && e.key === 'z') {
        dispatch({ type: 'UNDO' });
      }
    };
    const handleKeyUp = (e) => {
      if (e.key === 'Shift') setModifierKeys(prev => ({ ...prev, shift: false }));
      if (e.key === 'Control' || e.key === 'Meta') setModifierKeys(prev => ({ ...prev, ctrl: false }));
    };

    window.addEventListener('keydown', handleKeyDown);
    window.addEventListener('keyup', handleKeyUp);
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('keyup', handleKeyUp);
    };
  }, []);

  // カスタムイベントの購読（モーダルなど）
  useEffect(() => {
    const handleShowUpgrade = (e) => {
      setUpgradeFeature(e.detail.feature);
      setUpgradeReqPlan(e.detail.reqPlan);
      setUpgradeModalOpen(true);
    };

    const handleFailsafe = (e) => {
      setFailsafeReason(e.detail.reason);
      setFailsafeModalOpen(true);
    };

    window.addEventListener('show-upgrade-modal', handleShowUpgrade);
    window.addEventListener('gdl-failsafe-alert', handleFailsafe);
    return () => {
      window.removeEventListener('show-upgrade-modal', handleShowUpgrade);
      window.removeEventListener('gdl-failsafe-alert', handleFailsafe);
    };
  }, []);

  // --- ハンドラー関数 ---
  const handlePlanChange = (plan) => {
    dispatch({ type: 'UPDATE_USER_PLAN', payload: plan });
  };

  const handleApplySettings = (settings) => {
    setLeftWidth(settings.leftWidth);
    setRightWidth(settings.rightWidth);
    setCodeWidth(settings.codeWidth);
    setConstantWidth(settings.constantWidth);
    setPreviewLayoutMode(settings.previewLayoutMode);
    if (settings.refOpacity) setGlobalRefOpacity(settings.refOpacity);
    dispatch({ type: 'UPDATE_GLOBAL_SETTINGS', payload: {
      displayMode: settings.displayMode,
      monoColorMode: settings.monoColorMode,
      wireframeRes: settings.wireframeRes
    }});
    // For numpadEnabled, isIconBarRight, codeWidth (in weaver_panels.jsx),
    // they require a reload or are only defaults, so they will take effect on next reload.
  };

  const handleSwitchView = (viewId) => {
    setTransitioning(true);
    setTimeout(() => {
      dispatch({ type: 'SET_ACTIVE_VIEW', payload: viewId });
      setTransitioning(false);
    }, 300);
  };

  // 削除確認の処理
  // 頂点削除の処理
  useEffect(() => {
    if (deletePointsConfirm) {
      dispatch({ type: 'SAVE_HISTORY' });
      deletePointsConfirm.forEach(pId => {
        dispatch({ type: 'DELETE_POINT', shapeId: state?.activeShapeId, pointId: pId });
      });
      setMultiSelectedPointIds([]);
      dispatch({ type: 'SET_SELECTED_POINT', payload: null });
      setDeletePointsConfirm(null);
    }
  }, [deletePointsConfirm, state?.activeShapeId, dispatch, setMultiSelectedPointIds]);

  // 図形削除確認の処理
  useEffect(() => {
    if (state && state.deleteConfirmTargetId !== null) {
      dispatch({ type: 'DELETE_SHAPE' });
    }
  }, [state ? state.deleteConfirmTargetId : null, dispatch]);

  // 自動保存の処理
  useEffect(() => {
    if (state) {
      localStorage.setItem('gdl_weaver_autosave', JSON.stringify({
        shapes: state.shapes,
        shapeCounter: state.shapeCounter,
        activeShapeId: state.activeShapeId,
        selectedShapeIds: state.selectedShapeIds,
        displayMode: state.displayMode,
        wireframeRes: state.wireframeRes,
        currentWorkspace: state.currentWorkspace,
        monoColorMode: state.monoColorMode,
        userPlan: state.userPlan,
        cameras: state.cameras,
        snapEnabled: state.snapEnabled,
        snapGridSize: state.snapGridSize,
        activeView: state.activeView
      }));
    }
  }, [state]);

  return (
    <>
      {/* --- イントロ画面 --- */}
      {!introDone && (
        <IntroScreen
          targetMasaId="header-signature-logo"
          targetGmintId="footer-gmint-logo"
          onComplete={() => setIntroDone(true)}
        />
      )}

      {/* --- メインUI --- */}
      <div className="flex flex-col h-screen w-screen bg-[#000] text-white overflow-hidden font-sans">

        {/* ヘッダー */}
        <Header
          onOpenLicenses={() => setLicensesModalOpen(true)}
          userPlan={state.userPlan}
          onPlanChange={handlePlanChange}
          onOpenSettings={() => setIsSettingsOpen(true)}
        />

        {/* メインレイアウト (Left / Center / Right) */}
        <div className="flex flex-1 overflow-hidden relative">

          <LeftMiniViews
            state={state}
            dispatch={dispatch}
            onSwitchView={handleSwitchView}
            width={leftWidth}
          />

          <Resizer
            orientation="vertical"
            onResize={(d) => setLeftWidth(w => Math.max(150, Math.min(500, w + d)))}
            onDoubleClick={() => setLeftWidth(500)}
          />

          <MainWorkspace
            state={state}
            dispatch={dispatch}
            transitioning={transitioning}
            multiSelectedPointIds={multiSelectedPointIds}
            setMultiSelectedPointIds={setMultiSelectedPointIds}
            setDeletePointsConfirm={setDeletePointsConfirm}
            rulerMode={rulerMode}
            setRulerMode={setRulerMode}
            modifierKeys={modifierKeys}
            setModifierKeys={setModifierKeys}
            previewLayoutMode={previewLayoutMode}
            setPreviewLayoutMode={setPreviewLayoutMode}
          />

          <Resizer
            orientation="vertical"
            onResize={(d) => setRightWidth(w => Math.max(200, Math.min(previewLayoutMode === 1 ? 1000 : (previewLayoutMode === 2 ? 1400 : 600), w - d)))}
            onDoubleClick={() => setRightWidth(400)}
          />

          <RightPanel
            state={state}
            dispatch={dispatch}
            width={previewLayoutMode === 0 ? rightWidth : (previewLayoutMode === 1 ? rightWidth + codeWidth : rightWidth + codeWidth + constantWidth)}
            codeWidth={codeWidth}
            setCodeWidth={setCodeWidth}
            codeHeight={codeHeight}
            setCodeHeight={setCodeHeight}
            constantWidth={constantWidth}
            setConstantWidth={setConstantWidth}
            constantHeight={constantHeight}
            setConstantHeight={setConstantHeight}
            onCodeDoubleClick={() => setCodeHeight(200)}
            multiSelectedPointIds={multiSelectedPointIds}
            setMultiSelectedPointIds={setMultiSelectedPointIds}
            setDeletePointsConfirm={setDeletePointsConfirm}
            modifierKeys={modifierKeys}
            previewLayoutMode={previewLayoutMode}
          />
        </div>
      </div>

      {/* --- ウィジェットとモーダル --- */}
      <UpgradeModal
        isOpen={upgradeModalOpen}
        onClose={() => setUpgradeModalOpen(false)}
        featureName={upgradeFeature}
        reqPlan={upgradeReqPlan}
      />

      <FailsafeModal
        isOpen={failsafeModalOpen}
        onClose={() => setFailsafeModalOpen(false)}
        reason={failsafeReason}
        onContinue={() => {
          dispatch({ type: 'SET_IGNORE_TIMEOUT', payload: true });
          setFailsafeModalOpen(false);
        }}
      />

      {/* 寄生型NumPadウィジェットをReactのツリー内でマウント */}
      <NumpadInjector />

      <SettingsPanel 
        isOpen={isSettingsOpen} 
        onClose={() => setIsSettingsOpen(false)} 
        onApplyTemporarily={handleApplySettings} 
      />

      <LicensesModal
        isOpen={licensesModalOpen}
        onClose={() => setLicensesModalOpen(false)}
      />
    </>
  );
};

export default App;

// ★ React(Vite環境)のルートレンダリング
// 同一ブラウザでの複数起動を制限する
const channel = new BroadcastChannel('app_single_instance_check');
let isPrimary = false;
let isAlreadyOpen = false;

channel.onmessage = (event) => {
  if (event.data.type === 'PING') {
    if (isPrimary) {
      channel.postMessage({ type: 'PONG' });
    }
  } else if (event.data.type === 'PONG') {
    if (!isPrimary && !isAlreadyOpen) {
      isAlreadyOpen = true;
      showAlreadyOpenWarning();
    }
  }
};

channel.postMessage({ type: 'PING' });

setTimeout(() => {
  if (!isAlreadyOpen && !isPrimary) {
    isPrimary = true;
    const rootElement = document.getElementById('root');
    if (rootElement) {
      const root = createRoot(rootElement);
      root.render(<App />);
    }
  }
}, 300);

function showAlreadyOpenWarning() {
  document.body.innerHTML = `
    <div style="text-align: center; padding: 50px; color: #fff; background: #111; height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; font-family: sans-serif;">
      <h2 style="color: #ff3366; margin-bottom: 20px;">すでに別のタブまたはウィンドウで開かれています</h2>
      <p style="color: #888;">Standard版は1つのタブのみでご利用いただけます。<br>既存のタブでお使いいただくか、このタブを閉じてください。</p>
    </div>
  `;
}