/**
 * ═══════════════════════════════════════════════════════════════════
 * Micro-Action In-App Component (Feature-Flagged)
 * ═══════════════════════════════════════════════════════════════════
 * 
 * Wrapper component that mounts Micro-Action form logic inside app shell.
 * Uses extracted logic from pages/logic/microActionFormLogic.js
 * 
 * SYSTEM_MAP COMPLIANT:
 * - Bearer token is the ONLY identity source
 * - NO URL identity params
 * - All authenticated calls use window.SylvanFlowAuth.authenticatedFetch
 */

(function() {
  'use strict';

  const { useState, useEffect, useRef } = React;

  function MicroActionInApp({ tabParams }) {
    const containerRef = useRef(null);
    // ✅ UI STATE MACHINE: Explicit states for Scenario A/B handling
    const [uiState, setUiState] = useState('idle'); // idle | loading_preview | preview_ready | selecting | success | error_governed | error_network
    const [error, setError] = useState(null);
    const [errorCode, setErrorCode] = useState(null); // Governed error code (e.g., ERR_ITINERARY_REQUIRED)
    const [options, setOptions] = useState([]);
  const [selectedOption, setSelectedOption] = useState(null);
    const [patchStatus, setPatchStatus] = useState(null); // 'success' | 'failed' | null
    const [patchCode, setPatchCode] = useState(null); // Governed error code if patch failed
  const [region, setRegion] = useState('GLOBAL');
  const [languageCode, setLanguageCode] = useState(() => {
    const tabLang = tabParams?.language;
    const appLang = (typeof window !== 'undefined' && window.SylvanFlowState?.getLanguage)
      ? window.SylvanFlowState.getLanguage()
      : null;
    return tabLang || appLang || 'en';
  });
  const [intentKey, setIntentKey] = useState(null);
  const [intentLabelText, setIntentLabelText] = useState(null);
  const [microAction, setMicroAction] = useState(null);
  const [clientDayKey, setClientDayKey] = useState(null); // ✅ DAY_TRIP_BASELINE: Store client_day_key from preview
  // ✅ PAGE LOADING GATE: Track when translations are ready
  const [translationsReady, setTranslationsReady] = useState(false);
  // ✅ SYS_MESSAGES_KV: State for micro-action UI strings (NO hardcoded fallback - must be in SYS_MESSAGES_KV)
  const [headerSubtitle, setHeaderSubtitle] = useState('');
  const [chooseOptionText, setChooseOptionText] = useState('');
  const [viewOnMapText, setViewOnMapText] = useState('');
  // Distinguish page-entry selected state vs newly applied mutation state.
  const [selectionSource, setSelectionSource] = useState('preview'); // preview | selected_existing | selected_new
  const [uiText, setUiText] = useState(() => {
    const initialLang = tabParams?.language
      || ((typeof window !== 'undefined' && window.SylvanFlowState?.getLanguage) ? window.SylvanFlowState.getLanguage() : null)
      || 'en';
    const isZh = initialLang === 'zh-CN';
    return {
    loadingOptions: isZh ? '正在加载微行动选项...' : 'Loading Micro-Action options...',
    addingToItinerary: isZh ? '正在添加到您的行程...' : 'Adding to your itinerary...',
    networkErrorDefault: 'Network error. Please try again.',
    back: 'Back',
    governedErrorTitle: 'Selection saved, itinerary update needs attention',
    itineraryRequiredHint: 'Please create an itinerary first, then retry adding this option.',
    patchFailedHint: 'This option was saved, but itinerary update did not complete.',
    selectedOnlyAck: 'Option selected',
    patchSuccessAck: isZh ? '已添加到今日 Flow Plan' : 'Added to today\'s Flow Plan',
    selectedHeader: isZh ? '已选择选项' : 'Option Selected',
    openInMaps: isZh ? '在地图上打开' : 'Open in Maps',
    activeForTwoHours: 'Active for 2 hours',
    feedbackTitle: isZh ? '帮助我们持续优化' : 'Help us improve!',
    feedbackSubtitle: isZh ? '你的反馈是可选的，但能帮助我们提供更好的建议' : 'Your feedback is optional but helps us make better suggestions',
    feedbackQ1Title: isZh ? '1. 这个建议吸引你的原因是什么？' : '1. What appealed to you about this suggestion?',
    feedbackQ1Hint: isZh ? '这能帮助我们理解什么样的建议更适合你' : 'This helps us understand what makes suggestions work for you',
    feedbackQ2Title: isZh ? '2. 你对这些建议整体感觉如何？' : '2. How do you feel about these suggestions?',
    feedbackQ2Hint: isZh ? '你的意见能帮助我们改进建议系统' : 'Your opinion helps us improve the suggestion system',
    feedbackQ3Title: isZh ? '3. 这些建议对你有帮助吗？' : '3. Are these suggestions helpful?',
    feedbackQ3Hint: isZh ? '这些建议是否真的帮助你做决定？' : 'Does this actually help you decide?',
    feedbackQ4Title: isZh ? '4. 到目前为止你对 SylvanFlow 的体验如何？' : '4. How are you enjoying SylvanFlow so far?',
    feedbackQ4Hint: isZh ? '你的整体体验对我们非常重要' : 'Your overall experience matters to us',
    submitFeedback: isZh ? '提交反馈' : 'Submit Feedback',
    skipHint: isZh ? '你可以跳过任意问题，我们感谢你的任何反馈！' : 'You can skip any question - we appreciate whatever you share!',
    feedbackThanks: isZh ? '非常感谢！你的反馈正在帮助我们持续改进 SylvanFlow。' : 'Thank you so much! Your feedback helps us make SylvanFlow better.',
    labelPerfectMatch: isZh ? '非常匹配' : 'Perfect Match',
    labelInteresting: isZh ? '很有意思' : 'Interesting',
    labelConvenient: isZh ? '位置方便' : 'Convenient',
    labelGoodTiming: isZh ? '时机合适' : 'Good Timing',
    labelOther: isZh ? '其他' : 'Other',
    placeholderReasonOther: isZh ? '可选：告诉我们这个建议为什么吸引你…' : 'Optional: Tell us what made this suggestion appealing to you...',
    labelExcellent: isZh ? '非常好' : 'Excellent',
    labelGood: isZh ? '不错' : 'Good',
    labelOkay: isZh ? '一般' : 'Okay',
    labelNeedsWork: isZh ? '仍需改进' : 'Needs Work',
    labelVeryHelpful: isZh ? '非常有帮助' : 'Very Helpful',
    labelSomewhatHelpful: isZh ? '有一点帮助' : 'Somewhat',
    labelNotHelpful: isZh ? '帮助不大' : 'Not Really',
    labelLovingIt: isZh ? '很喜欢' : 'Loving It',
    labelEnjoying: isZh ? '还不错' : 'Enjoying',
    labelNeutral: isZh ? '一般' : 'Neutral',
    labelNotEnjoying: isZh ? '不太喜欢' : 'Not Really',
    menuFeedbackHint: isZh
      ? '可在菜单 → 反馈 中分享对此建议的看法。'
      : 'Share your thoughts from Menu → Feedback.'
  };
  });

    useEffect(() => {
      if (!selectedOption?.id || !tabParams?.micro_action_id) return;
      if (window.SylvanFlowMicroActionFeedbackPending) {
        window.SylvanFlowMicroActionFeedbackPending.save({
          micro_action_id: tabParams.micro_action_id,
          option_id: selectedOption.id,
          poi_name: selectedOption.poi?.name || selectedOption.summary || ''
        });
      }
    }, [selectedOption?.id, tabParams?.micro_action_id]);

    const normalizeSysMessage = (value) => {
      return typeof value === 'string' ? value.trim() : '';
    };

    const resolveSysMessage = async (key, locale) => {
      if (typeof window === 'undefined' || !window.getSysMessage) return null;
      const primary = normalizeSysMessage(await window.getSysMessage(key, locale));
      if (primary) return primary;
      if (locale !== 'en') {
        const fallback = normalizeSysMessage(await window.getSysMessage(key, 'en'));
        if (fallback) return fallback;
      }
      return null;
    };

    const resolvePreferredLanguage = (candidateLanguageCode) => {
      const appLang = (typeof window !== 'undefined' && window.SylvanFlowState?.getLanguage)
        ? window.SylvanFlowState.getLanguage()
        : null;
      if (candidateLanguageCode && candidateLanguageCode !== 'en') return candidateLanguageCode;
      if (languageCode && languageCode !== 'en') return languageCode;
      if (appLang && appLang !== 'en') return appLang;
      return candidateLanguageCode || languageCode || appLang || 'en';
    };

    useEffect(() => {
      // ✅ HARD GATING: Must not call protected endpoints until authChecked === true
      // Check if auth is ready (via window.appState or localStorage)
      const sessionToken = localStorage.getItem('sylvanflow_session_token');
      if (!sessionToken) {
        setError('Authentication required. Please log in.');
        setUiState('error_network');
        return;
      }

      // ✅ Extract params from tabParams
      const microActionId = tabParams?.micro_action_id || null;

      if (!microActionId) {
        setError('Missing micro_action_id');
        setUiState('error_network');
        return;
      }

      // ✅ Use extracted logic
      if (!window.MicroActionFormLogic) {
        setError('Micro-Action form logic not loaded');
        setUiState('error_network');
        return;
      }

      // ✅ Flow 1 UI: Seed language from deep link/app state so CTAs localize immediately
      setLanguageCode((prev) => resolvePreferredLanguage(tabParams?.language || prev));

      // ✅ STATE MACHINE: Transition to loading_preview
      setUiState('loading_preview');
      setError(null);
      setErrorCode(null);

      // Load options
      window.MicroActionFormLogic.loadOptions(
        { microActionId },
        (result) => {
          if (result.type === 'selected') {
            setSelectedOption(result.option);
            setRegion(result.region || 'GLOBAL');
            setLanguageCode(resolvePreferredLanguage(result.languageCode));
            setMicroAction(result.microAction || null);
            // ✅ Extract intent_key when selected
            if (result.intent_key) {
              setIntentKey(result.intent_key);
            } else if (result.microAction?.intent_key) {
              setIntentKey(result.microAction.intent_key);
            }
            setSelectionSource('selected_existing');
            setPatchStatus(null);
            setPatchCode(null);
            setUiState('success'); // Already selected, show truthful selected-only state
          } else {
            setOptions(result.options || []);
            setRegion(result.region || 'GLOBAL');
            setLanguageCode(resolvePreferredLanguage(result.languageCode));
            setMicroAction(result.microAction || null);
            // ✅ DAY_TRIP_BASELINE: Store clientDayKey from preview response for select payload
            if (result.clientDayKey) {
              setClientDayKey(result.clientDayKey);
            }
            // Extract intent_key from result (API returns it at top level)
            if (result.intent_key) {
              setIntentKey(result.intent_key);
            } else if (result.microAction?.intent_key) {
              setIntentKey(result.microAction.intent_key);
            }
            // ✅ OPTIONAL: Store hasDayItinerary from preview response (if available)
            if (result.hasDayItinerary !== undefined) {
              // Can be used for UI state alignment
            }
            setUiState('preview_ready'); // Options loaded, ready for selection
          }
        },
        (errorMsg) => {
          setError(errorMsg);
          setUiState('error_network');
        }
      );
    }, [tabParams]);

    // ✅ FIX: Load system messages for micro-action UI strings
    useEffect(() => {
      const loadSysMessages = async () => {
        const lang = languageCode || window.SylvanFlowState?.getLanguage() || 'en';
        
        // ✅ PAGE LOADING GATE: Reset translations ready state when loading new language
        setTranslationsReady(false);
        
        try {
          if (typeof window !== 'undefined' && window.getSysMessage) {
            const [
              headerSubtitleMsg,
              chooseOptionMsg,
              viewOnMapMsg,
              loadingOptionsMsg,
              addingToItineraryMsg,
              networkErrorMsg,
              backMsg,
              governedErrorTitleMsg,
              itineraryRequiredHintMsg,
              patchFailedHintMsg,
              selectedOnlyAckMsg,
              patchSuccessAckMsg,
              selectedHeaderMsg,
              openInMapsMsg,
              activeForTwoHoursMsg,
              feedbackTitleMsg,
              feedbackSubtitleMsg,
              feedbackQ1TitleMsg,
              feedbackQ1HintMsg,
              feedbackQ2TitleMsg,
              feedbackQ2HintMsg,
              feedbackQ3TitleMsg,
              feedbackQ3HintMsg,
              feedbackQ4TitleMsg,
              feedbackQ4HintMsg,
              submitFeedbackMsg,
              skipHintMsg,
              feedbackThanksMsg,
              labelPerfectMatchMsg,
              labelInterestingMsg,
              labelConvenientMsg,
              labelGoodTimingMsg,
              labelOtherMsg,
              placeholderReasonOtherMsg,
              labelExcellentMsg,
              labelGoodMsg,
              labelOkayMsg,
              labelNeedsWorkMsg,
              labelVeryHelpfulMsg,
              labelSomewhatHelpfulMsg,
              labelNotHelpfulMsg,
              labelLovingItMsg,
              labelEnjoyingMsg,
              labelNeutralMsg,
              labelNotEnjoyingMsg
            ] = await Promise.all([
              resolveSysMessage('ui:micro_action:header_subtitle', lang),
              resolveSysMessage('ui:micro_action:choose_option', lang),
              resolveSysMessage('ui:micro_action:view_on_map', lang),
              resolveSysMessage('ui:micro_action:loading_options', lang),
              resolveSysMessage('ui:micro_action:adding_to_itinerary', lang),
              resolveSysMessage('ui:micro_action:network_error_default', lang),
              resolveSysMessage('ui:micro_action:back', lang),
              resolveSysMessage('ui:micro_action:governed_error_title', lang),
              resolveSysMessage('ui:micro_action:itinerary_required_hint', lang),
              resolveSysMessage('ui:micro_action:patch_failed_hint', lang),
              resolveSysMessage('ui:micro_action:selected_only_ack', lang),
              resolveSysMessage('ui:micro_action:patch_success_ack', lang),
              resolveSysMessage('ui:micro_action:selected_header', lang),
              resolveSysMessage('ui:micro_action:open_in_maps', lang),
              resolveSysMessage('ui:micro_action:active_for_two_hours', lang),
              resolveSysMessage('ui:micro_action:feedback_title', lang),
              resolveSysMessage('ui:micro_action:feedback_subtitle', lang),
              resolveSysMessage('ui:micro_action:feedback_q1_title', lang),
              resolveSysMessage('ui:micro_action:feedback_q1_hint', lang),
              resolveSysMessage('ui:micro_action:feedback_q2_title', lang),
              resolveSysMessage('ui:micro_action:feedback_q2_hint', lang),
              resolveSysMessage('ui:micro_action:feedback_q3_title', lang),
              resolveSysMessage('ui:micro_action:feedback_q3_hint', lang),
              resolveSysMessage('ui:micro_action:feedback_q4_title', lang),
              resolveSysMessage('ui:micro_action:feedback_q4_hint', lang),
              resolveSysMessage('ui:micro_action:submit_feedback', lang),
              resolveSysMessage('ui:micro_action:skip_hint', lang),
              resolveSysMessage('ui:micro_action:feedback_thanks', lang),
              resolveSysMessage('ui:micro_action:label_perfect_match', lang),
              resolveSysMessage('ui:micro_action:label_interesting', lang),
              resolveSysMessage('ui:micro_action:label_convenient', lang),
              resolveSysMessage('ui:micro_action:label_good_timing', lang),
              resolveSysMessage('ui:micro_action:label_other', lang),
              resolveSysMessage('ui:micro_action:placeholder_reason_other', lang),
              resolveSysMessage('ui:micro_action:label_excellent', lang),
              resolveSysMessage('ui:micro_action:label_good', lang),
              resolveSysMessage('ui:micro_action:label_okay', lang),
              resolveSysMessage('ui:micro_action:label_needs_work', lang),
              resolveSysMessage('ui:micro_action:label_very_helpful', lang),
              resolveSysMessage('ui:micro_action:label_somewhat_helpful', lang),
              resolveSysMessage('ui:micro_action:label_not_helpful', lang),
              resolveSysMessage('ui:micro_action:label_loving_it', lang),
              resolveSysMessage('ui:micro_action:label_enjoying', lang),
              resolveSysMessage('ui:micro_action:label_neutral', lang),
              resolveSysMessage('ui:micro_action:label_not_enjoying', lang)
            ]);
            
            if (headerSubtitleMsg) setHeaderSubtitle(headerSubtitleMsg);
            if (chooseOptionMsg) {
              setChooseOptionText(chooseOptionMsg);
            } else {
              const errorLabel = await resolveSysMessage('ui:system_error_label', lang);
              if (errorLabel) setChooseOptionText(errorLabel);
            }
            if (viewOnMapMsg) setViewOnMapText(viewOnMapMsg);
            setUiText(prev => ({
              ...prev,
              loadingOptions: loadingOptionsMsg || prev.loadingOptions,
              addingToItinerary: addingToItineraryMsg || prev.addingToItinerary,
              networkErrorDefault: networkErrorMsg || prev.networkErrorDefault,
              back: backMsg || prev.back,
              governedErrorTitle: governedErrorTitleMsg || prev.governedErrorTitle,
              itineraryRequiredHint: itineraryRequiredHintMsg || prev.itineraryRequiredHint,
              patchFailedHint: patchFailedHintMsg || prev.patchFailedHint,
              selectedOnlyAck: selectedOnlyAckMsg || prev.selectedOnlyAck,
              patchSuccessAck: patchSuccessAckMsg || prev.patchSuccessAck,
              selectedHeader: selectedHeaderMsg || prev.selectedHeader,
              openInMaps: openInMapsMsg || prev.openInMaps,
              activeForTwoHours: activeForTwoHoursMsg || prev.activeForTwoHours,
              feedbackTitle: feedbackTitleMsg || prev.feedbackTitle,
              feedbackSubtitle: feedbackSubtitleMsg || prev.feedbackSubtitle,
              feedbackQ1Title: feedbackQ1TitleMsg || prev.feedbackQ1Title,
              feedbackQ1Hint: feedbackQ1HintMsg || prev.feedbackQ1Hint,
              feedbackQ2Title: feedbackQ2TitleMsg || prev.feedbackQ2Title,
              feedbackQ2Hint: feedbackQ2HintMsg || prev.feedbackQ2Hint,
              feedbackQ3Title: feedbackQ3TitleMsg || prev.feedbackQ3Title,
              feedbackQ3Hint: feedbackQ3HintMsg || prev.feedbackQ3Hint,
              feedbackQ4Title: feedbackQ4TitleMsg || prev.feedbackQ4Title,
              feedbackQ4Hint: feedbackQ4HintMsg || prev.feedbackQ4Hint,
              submitFeedback: submitFeedbackMsg || prev.submitFeedback,
              skipHint: skipHintMsg || prev.skipHint,
              feedbackThanks: feedbackThanksMsg || prev.feedbackThanks,
              labelPerfectMatch: labelPerfectMatchMsg || prev.labelPerfectMatch,
              labelInteresting: labelInterestingMsg || prev.labelInteresting,
              labelConvenient: labelConvenientMsg || prev.labelConvenient,
              labelGoodTiming: labelGoodTimingMsg || prev.labelGoodTiming,
              labelOther: labelOtherMsg || prev.labelOther,
              placeholderReasonOther: placeholderReasonOtherMsg || prev.placeholderReasonOther,
              labelExcellent: labelExcellentMsg || prev.labelExcellent,
              labelGood: labelGoodMsg || prev.labelGood,
              labelOkay: labelOkayMsg || prev.labelOkay,
              labelNeedsWork: labelNeedsWorkMsg || prev.labelNeedsWork,
              labelVeryHelpful: labelVeryHelpfulMsg || prev.labelVeryHelpful,
              labelSomewhatHelpful: labelSomewhatHelpfulMsg || prev.labelSomewhatHelpful,
              labelNotHelpful: labelNotHelpfulMsg || prev.labelNotHelpful,
              labelLovingIt: labelLovingItMsg || prev.labelLovingIt,
              labelEnjoying: labelEnjoyingMsg || prev.labelEnjoying,
              labelNeutral: labelNeutralMsg || prev.labelNeutral,
              labelNotEnjoying: labelNotEnjoyingMsg || prev.labelNotEnjoying
            }));
            
            // ✅ PAGE LOADING GATE: Mark translations as ready
            setTranslationsReady(true);
          } else {
            // ✅ PAGE LOADING GATE: If getSysMessage not available, still mark as ready (fallback will be used)
            setTranslationsReady(true);
          }
        } catch (error) {
          if (window.uiLogger) {
            window.uiLogger.uiWarn('[MICRO-ACTION] Error loading system messages:', error.message || error);
          }
          // ✅ PAGE LOADING GATE: Still mark as ready even on error (fallback values are acceptable)
          setTranslationsReady(true);
        }
      };
      
      if (languageCode) {
        loadSysMessages();
      }
    }, [languageCode]);

    useEffect(() => {
      const loadIntentLabelText = async () => {
        if (!intentKey) {
          setIntentLabelText(null);
          return;
        }
        const lang = languageCode || window.SylvanFlowState?.getLanguage() || 'en';
        const labelKey = `ui:intent_label:${intentKey}`;
        const [labelMsg, formatMsg] = await Promise.all([
          resolveSysMessage(labelKey, lang),
          resolveSysMessage('ui:intent_label_format', lang)
        ]);
        const safeLabel = labelMsg || intentKey;
        if (formatMsg) {
          setIntentLabelText(formatMsg.replace('{label}', safeLabel));
          return;
        }
        setIntentLabelText(safeLabel);
      };

      loadIntentLabelText();
    }, [intentKey, languageCode]);

    const handleSelectOption = async (optionId) => {
      // 🔍 UI-BUG-03 INVESTIGATION: Log entry point (admin-only, sanitized)
      const entryTimestamp = Date.now();
      if (window.uiLogger) {
        window.uiLogger.uiLog(`[UI-BUG-03] handleSelectOption ENTRY`, {
          timestamp: entryTimestamp,
          optionId,
          hasSelectedOption: !!selectedOption,
          uiState,
          guardCheck: { selectedOption: !!selectedOption, uiStateIsSelecting: uiState === 'selecting' }
        });
      }

      if (selectedOption || uiState === 'selecting') {
        if (window.uiLogger) {
          window.uiLogger.uiLog(`[UI-BUG-03] handleSelectOption GUARD BLOCKED`, {
            timestamp: Date.now(),
            reason: selectedOption ? 'selectedOption exists' : 'uiState === selecting',
            optionId
          });
        }
        return; // Already selected or selection in progress
      }

      const microActionId = tabParams?.micro_action_id || null;

      // 🔍 UI-BUG-03 INVESTIGATION: Log before state update (admin-only, sanitized)
      if (window.uiLogger) {
        window.uiLogger.uiLog(`[UI-BUG-03] handleSelectOption BEFORE STATE UPDATE`, {
          timestamp: Date.now(),
          optionId,
          microActionIdLength: microActionId?.length || 0,
          currentUiState: uiState
        });
      }

      // ✅ STATE MACHINE: Transition to selecting
      setSelectionSource('selected_new');
      setUiState('selecting');
      setError(null);
      setErrorCode(null);
      setPatchStatus(null);
      setPatchCode(null);

      // 🔍 UI-BUG-03 INVESTIGATION: Log before API call (admin-only, sanitized)
      if (window.uiLogger) {
        window.uiLogger.uiLog(`[UI-BUG-03] handleSelectOption BEFORE API CALL`, {
          timestamp: Date.now(),
          optionId,
          hasClientDayKey: !!clientDayKey
        });
      }

      // ✅ DAY_TRIP_BASELINE: Pass clientDayKey from preview response to select payload
      window.MicroActionFormLogic.selectOption(
        { microActionId, optionId, clientDayKey, requestId: tabParams?.request_id || null },
        (result) => {
          // 🔍 UI-BUG-03 INVESTIGATION: Log after API response (admin-only, sanitized)
          if (window.uiLogger) {
            window.uiLogger.uiLog(`[UI-BUG-03] handleSelectOption AFTER API RESPONSE`, {
              timestamp: Date.now(),
              optionId,
              resultOk: result.ok,
              patchStatus: result.patch_status,
              patchCode: result.patch_code,
              code: result.code
            });
          }

          // ✅ Handle Scenario A/B outcomes
          if (result.code === 'ERR_ITINERARY_REQUIRED') {
            // Scenario A: No itinerary exists
            setErrorCode('ERR_ITINERARY_REQUIRED');
            setError(result.message || 'Please create an itinerary first before selecting micro-actions');
            setUiState('error_governed');
            // Still show the selected option (selection was stored)
          const option = options.find(o => (o.id || o.id) === optionId);
          if (option) {
            setSelectedOption(option);
          }
          } else if (result.patch_status === 'success') {
            // Scenario B: Patch succeeded
            setPatchStatus('success');
            setPatchCode(null);
            setUiState('success');
            const option = options.find(o => (o.id || o.id) === optionId);
            if (option) {
              setSelectedOption(option);
            }
          } else if (result.patch_code) {
            // Patch failed with governed error code
            setPatchStatus('failed');
            setPatchCode(result.patch_code);
            setErrorCode(result.patch_code);
            setError(result.patch_error || result.message || 'Failed to add to itinerary');
            setUiState('error_governed');
            // Still show the selected option (selection was stored)
            const option = options.find(o => (o.id || o.id) === optionId);
            if (option) {
              setSelectedOption(option);
            }
          } else {
            // Generic success (no patch attempted or patch status not returned)
            setPatchStatus(null);
            setUiState('success');
            const option = options.find(o => (o.id || o.id) === optionId);
            if (option) {
              setSelectedOption(option);
            }
          }
        },
        (errorObj) => {
          // 🔍 UI-BUG-03 INVESTIGATION: Log error callback (admin-only, sanitized)
          if (window.uiLogger) {
            window.uiLogger.uiLog(`[UI-BUG-03] handleSelectOption ERROR CALLBACK`, {
              timestamp: Date.now(),
              optionId,
              errorType: typeof errorObj,
              errorCode: errorObj?.code,
              errorMessage: typeof errorObj === 'string' ? errorObj : errorObj?.message || errorObj?.error
            });
          }

          // ✅ Handle error object (may be string or object with code)
          if (typeof errorObj === 'string') {
            setError(errorObj);
            setUiState('error_network');
          } else if (errorObj?.code === 'ERR_ITINERARY_REQUIRED') {
            // Scenario A: No itinerary exists
            setErrorCode('ERR_ITINERARY_REQUIRED');
            setError(errorObj.message || errorObj.error || 'Please create an itinerary first before selecting micro-actions');
            setUiState('error_governed');
            // Still show the selected option (selection was stored)
            const option = options.find(o => (o.id || o.id) === optionId);
            if (option) {
              setSelectedOption(option);
            }
          } else {
            setError(errorObj?.error || errorObj?.message || 'Failed to select option');
            setUiState('error_network');
          }
        }
      );
    };

    // ✅ STATE MACHINE: Render based on current state
    // ✅ PAGE LOADING GATE: Show loading until both data and translations are ready
    if (uiState === 'idle' || uiState === 'loading_preview' || !translationsReady) {
      return (
        <div className="p-4 text-center text-slate-500">
          <p>{uiText.loadingOptions}</p>
        </div>
      );
    }

    if (uiState === 'selecting') {
      return (
        <div className="p-4 text-center text-slate-500">
          <p>{uiText.addingToItinerary}</p>
        </div>
      );
    }

    if (uiState === 'error_network') {
      return (
        <div className="p-4 text-center text-red-600">
          <p>{error || uiText.networkErrorDefault}</p>
          <button
            onClick={() => {
              // ✅ FIX: Navigate to Ask Sylvan tab instead of retrying
              if (window.appState) {
                window.appState.set({ view: 'ask-sylvan' });
              } else if (window.uiLogger) {
                window.uiLogger.uiWarn('[MICRO-ACTION] appState not available, cannot navigate to ask-sylvan');
              }
            }}
            className="mt-4 px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700"
          >
            {uiText.back}
          </button>
        </div>
      );
    }

    if (uiState === 'error_governed') {
      return (
        <div className="p-4 text-center">
          <div className="mx-auto max-w-2xl bg-amber-50 border border-amber-300 rounded-xl p-5 text-amber-900">
            <p className="font-semibold mb-2">{uiText.governedErrorTitle}</p>
            <p className="mb-2">{error || errorCode || 'Governed error'}</p>
            {errorCode === 'ERR_ITINERARY_REQUIRED' ? (
              <p className="text-sm">{uiText.itineraryRequiredHint}</p>
            ) : (
              <p className="text-sm">{uiText.patchFailedHint}</p>
            )}
          </div>
        </div>
      );
    }

    // Helper function to build region-aware map URL
    const buildMapUrl = (poi, region) => {
      if (poi?.maps_url) return poi.maps_url;
      if (!poi?.lat || !poi?.lng) return null;
      
      if (region === 'CN') {
        // Gaode Maps for China
        return `https://uri.amap.com/marker?position=${poi.lng},${poi.lat}&name=${encodeURIComponent(poi.name || 'Location')}`;
      } else {
        // Google Maps for GLOBAL
        return `https://www.google.com/maps?q=${poi.lat},${poi.lng}`;
      }
    };

    // Helper function to format distance
    const formatDistance = (km) => {
      if (!km) return null;
      return `${km.toFixed(1)}km`;
    };

    // Helper function to format rating
    const formatRating = (rating, reviewCount) => {
      if (!rating) return null;
      const stars = '⭐'.repeat(Math.round(rating));
      const count = reviewCount ? ` (${reviewCount} reviews)` : '';
      return `${stars} ${rating.toFixed(1)}${count}`;
    };

    return (
      <div ref={containerRef} className="w-full h-full overflow-y-auto bg-gradient-to-br from-slate-50 to-white">
        <div className="max-w-4xl mx-auto p-4 md:p-6">
          {intentLabelText && (
            <div className="text-center mb-6 py-4 px-5 rounded-2xl bg-gradient-to-r from-teal-500 to-cyan-600 shadow-lg">
              <p className="text-white text-2xl font-bold">
                {intentLabelText}
              </p>
            </div>
          )}
          
          {/* ✅ REMOVED: situation_summary display (ugly debug info - User: Weather: Mood:) */}
          
          {/* ✅ FIX 2: Show explicit acknowledgement when selected=true */}
          {selectedOption && uiState === 'success' && (
            <div className="mb-6 p-4 bg-gradient-to-r from-teal-50 to-cyan-50 rounded-xl border-2 border-teal-200">
              <div className="flex items-center gap-2">
                <span className="text-2xl">✅</span>
                <p className="text-teal-700 font-semibold text-lg">
                  {(selectionSource === 'selected_new' && patchStatus === 'success')
                    ? uiText.patchSuccessAck
                    : uiText.selectedOnlyAck}
                </p>
              </div>
            </div>
          )}
          
          <h2 className="text-3xl font-bold mb-6 text-center text-slate-800">{headerSubtitle}</h2>
          
          {selectedOption ? (
            <div className="bg-white rounded-2xl p-6 md:p-8 shadow-xl border-2 border-teal-200">
              <div className="selected-option-header mb-6 pb-4 border-b-2 border-teal-100">
                <div className="flex items-center gap-2 mb-3">
                  <span className="text-2xl">✅</span>
                  <h3 className="text-2xl font-bold text-slate-800">{uiText.selectedHeader}</h3>
                </div>
                <h4 className="text-xl font-semibold text-teal-700 mb-2">{selectedOption.poi?.name || selectedOption.summary}</h4>
                {selectedOption.summary && <p className="text-slate-600 mb-2 text-lg">{selectedOption.summary}</p>}
                {selectedOption.expires_at && (() => {
                  const expiresAt = new Date(selectedOption.expires_at);
                  const minutesRemaining = Math.ceil((expiresAt - new Date()) / 60000);
                  const expiresText = minutesRemaining < 0
                    ? `Expired (${Math.abs(minutesRemaining)} minutes ago)`
                    : `Active until ${expiresAt.toLocaleTimeString()} (${minutesRemaining} min remaining)`;
                  return (
                    <div className="text-sm text-slate-500 mt-2">
                      {expiresText}
                    </div>
                  );
                })()}
                {!selectedOption.expires_at && (
                  <div className="text-sm text-slate-500 mt-2">
                    {uiText.activeForTwoHours}
                  </div>
                )}
              </div>
              
              {selectedOption.poi?.photos && selectedOption.poi.photos.length > 0 && (
                <div className="mb-6 overflow-hidden rounded-xl shadow-lg">
                  <img 
                    src={(() => {
                      // 🔍 UI-BUG-01 INVESTIGATION: Log selected option photo structure
                      const photoValue = selectedOption.poi.photos[0];
                      const photoType = typeof photoValue;
                      const isString = photoType === 'string';
                      const isObject = photoType === 'object' && photoValue !== null;
                      const photoUrl = isString ? photoValue : (isObject ? photoValue?.url || photoValue?.src : null);
                      
                      if (window.uiLogger) {
                        window.uiLogger.uiLog(`[UI-BUG-01] Selected option photo render`, {
                          hasOptionId: !!selectedOption.id,
                          hasPoiName: !!selectedOption.poi.name,
                          poiNameLength: selectedOption.poi.name?.length || 0,
                          photosArrayLength: selectedOption.poi.photos?.length,
                          photos0Type: photoType,
                          photos0ValueLength: isString ? photoValue?.length || 0 : (isObject ? JSON.stringify(photoValue)?.length || 0 : 0),
                          hasResolvedUrl: !!photoUrl,
                          resolvedUrlLength: photoUrl?.length || 0
                        });
                      }
                      
                      return photoUrl || photoValue;
                    })()}
                    alt={selectedOption.poi.name || 'POI'} 
                    className="w-full h-72 object-cover"
                    onError={(e) => {
                      // 🔍 UI-BUG-01 INVESTIGATION: Log image load error (admin-only, sanitized)
                      if (window.uiLogger) {
                        window.uiLogger.uiError(`[UI-BUG-01] Selected option image load error`, {
                          hasOptionId: !!selectedOption.id,
                          hasPoiName: !!selectedOption.poi.name,
                          srcLength: e.target.src?.length || 0,
                          error: e.type,
                          timestamp: Date.now()
                        });
                      }
                      e.target.style.display = 'none';
                    }}
                    onLoad={(e) => {
                      // 🔍 UI-BUG-01 INVESTIGATION: Log successful image load (admin-only, sanitized)
                      if (window.uiLogger) {
                        window.uiLogger.uiLog(`[UI-BUG-01] Selected option image load success`, {
                          hasOptionId: !!selectedOption.id,
                          hasPoiName: !!selectedOption.poi.name,
                          srcLength: e.target.src?.length || 0,
                          timestamp: Date.now()
                        });
                      }
                    }}
                  />
                </div>
              )}
              
              <div className="option-meta mb-6 flex flex-wrap gap-4 p-4 bg-gradient-to-r from-teal-50 to-cyan-50 rounded-xl border border-teal-200">
                {selectedOption.poi?.distance_km && (
                  <div className="flex items-center gap-2 px-3 py-2 bg-white rounded-lg shadow-sm">
                    <span className="text-lg">📍</span>
                    <span className="font-semibold text-slate-700">{formatDistance(selectedOption.poi.distance_km)} away</span>
                  </div>
                )}
                {selectedOption.poi?.rating && (
                  <div className="flex items-center gap-2 px-3 py-2 bg-white rounded-lg shadow-sm">
                    <span className="text-lg">⭐</span>
                    <span className="font-semibold text-slate-700">{formatRating(selectedOption.poi.rating, selectedOption.poi.review_count)}</span>
                  </div>
                )}
                {selectedOption.poi?.category && (
                  <div className="flex items-center gap-2 px-3 py-2 bg-white rounded-lg shadow-sm">
                    <span className="text-lg">🏷️</span>
                    <span className="font-semibold text-slate-700">{selectedOption.poi.category}</span>
                  </div>
                )}
              </div>
              
              {selectedOption.poi?.rich_description && (
                <div className="poi-description mb-4 text-slate-700">
                  {selectedOption.poi.rich_description}
                </div>
              )}
              
              {selectedOption.poi?.address && (
                <div className="text-slate-500 text-sm mb-4">
                  📍 {selectedOption.poi.address}
                </div>
              )}
              
              {buildMapUrl(selectedOption.poi || {}, region) && (
                <div className="option-actions mb-6">
                  <a 
                    href={buildMapUrl(selectedOption.poi || {}, region)} 
                    target="_blank" 
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-teal-600 to-cyan-600 text-white rounded-xl font-semibold shadow-lg hover:shadow-xl transition-all hover:scale-105"
                  >
                    <span className="text-xl">🗺️</span>
                    <span>{uiText.openInMaps}</span>
                  </a>
                </div>
              )}

              <p className="text-slate-600 text-sm mb-2 px-1">💬 {uiText.menuFeedbackHint}</p>

            </div>
          ) : (
            <div className="space-y-4">
              {options.map((option, idx) => {
                const poi = option.poi || {};
                const mapsUrl = buildMapUrl(poi, region);
                
                // Format price level if available
                const formatPrice = (priceLevel) => {
                  if (!priceLevel) return '';
                  const levels = { 1: '$', 2: '$$', 3: '$$$', 4: '$$$$' };
                  return levels[priceLevel] || '';
                };
                
                // Build compact meta line: "distance • category • price"
                const metaParts = [];
                if (poi.distance_km) {
                  metaParts.push(formatDistance(poi.distance_km));
                }
                if (poi.category) {
                  metaParts.push(poi.category);
                }
                if (poi.price_level) {
                  const price = formatPrice(poi.price_level);
                  if (price) metaParts.push(price);
                }
                const metaLine = metaParts.join(' • ');
                
                return (
                  <div key={option.id || idx} className="bg-white rounded-2xl p-6 shadow-lg border-2 border-teal-100 hover:border-teal-300 transition-all">
                    <div className="option-header mb-4 pb-3 border-b border-teal-100">
                      <div className="flex items-center gap-3 mb-2">
                        <div className="option-badge inline-flex min-h-10 max-w-[140px] items-center justify-center px-2 py-1 bg-gradient-to-br from-teal-500 to-cyan-600 text-white rounded-xl text-[10px] font-bold leading-tight shadow-md text-center">
                          {option.label || (idx === 0 ? 'STRONG FIT' : 'Alternative')}
                        </div>
                        <h3 className="text-xl font-bold text-slate-800 flex-1">
                          {poi.name || option.summary || 'Option'}
                        </h3>
                      </div>
                      {option.summary && (
                        <p className="text-slate-600 text-base ml-[52px]">{option.summary}</p>
                      )}
                    </div>
                    
                    {/* ✅ FIX: Compact meta line - distance • category • price */}
                    {metaLine && (
                      <div className="option-meta mb-4 px-3 py-2 bg-gradient-to-r from-teal-50 to-cyan-50 rounded-lg border border-teal-200">
                        <span className="text-sm font-semibold text-slate-700">{metaLine}</span>
                      </div>
                    )}
                    
                    {poi.photos && poi.photos.length > 0 && (
                      <div className="poi-photo mb-4 overflow-hidden rounded-xl shadow-md">
                        <img 
                          src={(() => {
                            // 🔍 UI-BUG-01 INVESTIGATION: Log photo structure
                            const photoValue = poi.photos[0];
                            const photoType = typeof photoValue;
                            const isString = photoType === 'string';
                            const isObject = photoType === 'object' && photoValue !== null;
                            const photoUrl = isString ? photoValue : (isObject ? photoValue?.url || photoValue?.src : null);
                            
                            if (window.uiLogger) {
                              window.uiLogger.uiLog(`[UI-BUG-01] Option card photo render`, {
                                hasOptionId: !!option.id,
                                hasPoiName: !!poi.name,
                                poiNameLength: poi.name?.length || 0,
                                photosArrayLength: poi.photos?.length,
                                photos0Type: photoType,
                                photos0ValueLength: isString ? photoValue?.length || 0 : (isObject ? JSON.stringify(photoValue)?.length || 0 : 0),
                                hasResolvedUrl: !!photoUrl,
                                resolvedUrlLength: photoUrl?.length || 0
                              });
                            }
                            
                            return photoUrl || photoValue;
                          })()}
                          alt={poi.name || 'POI'} 
                          className="w-full h-56 object-cover"
                          loading="lazy"
                          crossOrigin="anonymous"
                          onError={(e) => {
                            // 🔍 UI-BUG-01 INVESTIGATION: Log image load error (admin-only, sanitized)
                            if (window.uiLogger) {
                              window.uiLogger.uiError(`[UI-BUG-01] Image load error`, {
                                hasOptionId: !!option.id,
                                hasPoiName: !!poi.name,
                                srcLength: e.target.src?.length || 0,
                                error: e.type,
                                timestamp: Date.now()
                              });
                            }
                            e.target.style.display = 'none';
                          }}
                          onLoad={(e) => {
                            // 🔍 UI-BUG-01 INVESTIGATION: Log successful image load (admin-only, sanitized)
                            if (window.uiLogger) {
                              window.uiLogger.uiLog(`[UI-BUG-01] Image load success`, {
                                hasOptionId: !!option.id,
                                hasPoiName: !!poi.name,
                                srcLength: e.target.src?.length || 0,
                                timestamp: Date.now()
                              });
                            }
                          }}
                        />
                      </div>
                    )}
                    
                    {poi.rich_description && (
                      <div className="poi-details mb-3">
                        <div className="poi-description text-slate-700 text-sm mb-2">
                          {poi.rich_description}
                        </div>
                        {poi.address && (
                          <div className="text-slate-400 text-xs mb-2">
                            📍 {poi.address}
                          </div>
                        )}
                      </div>
                    )}
                    
                    {/* ✅ FIX: Button row - equal height, mobile-friendly */}
                    <div className="option-actions flex flex-col sm:flex-row gap-3 mt-5">
                      <button
                        onClick={() => {
                          // 🔍 UI-BUG-03 INVESTIGATION: Log button click (admin-only, sanitized)
                          if (window.uiLogger) {
                            window.uiLogger.uiLog(`[UI-BUG-03] Button click`, {
                              timestamp: Date.now(),
                              optionId: option.id,
                              currentUiState: uiState,
                              hasSelectedOption: !!selectedOption,
                              buttonEnabled: !(selectedOption || uiState === 'selecting')
                            });
                          }
                          handleSelectOption(option.id);
                        }}
                        disabled={selectedOption || uiState === 'selecting'}
                        className={`flex-1 px-6 py-3.5 bg-gradient-to-r from-teal-600 to-cyan-600 text-white rounded-xl hover:from-teal-700 hover:to-cyan-700 font-semibold text-base shadow-lg hover:shadow-xl transition-all hover:scale-[1.02] active:scale-[0.98] min-h-[48px] flex items-center justify-center ${
                          selectedOption || uiState === 'selecting' ? 'opacity-50 cursor-not-allowed' : ''
                        }`}
                      >
                        {chooseOptionText}
                      </button>
                      {mapsUrl && (
                        <a
                          href={mapsUrl}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="flex-1 sm:flex-initial sm:min-w-[160px] px-6 py-3.5 bg-white border-2 border-teal-300 text-slate-700 rounded-xl hover:bg-teal-50 hover:border-teal-400 font-semibold text-base shadow-md hover:shadow-lg transition-all min-h-[48px] flex items-center justify-center gap-2"
                        >
                          <span className="text-lg">🗺️</span>
                          <span>{viewOnMapText}</span>
                        </a>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>
    );
  }

  // Export to window
  if (typeof window !== 'undefined') {
    window.MicroActionInApp = MicroActionInApp;
  }
})();

