import React, { useState, useEffect, useMemo, useRef } from 'react';
import { io } from 'socket.io-client';
import { Capacitor } from '@capacitor/core';
import { BACKEND_URL } from '@/utils/backendEndpoint';
import { jsPDF } from 'jspdf';
import autoTable from 'jspdf-autotable';
import { robotoBase64, robotoBoldBase64 } from '../utils/pdfFont';
import { ItineraryTimeline } from '../components/ItineraryTimeline';
import { ExpenseManager } from '../components/ExpenseManager';
import { useTourStore } from '@/store/useTourStore';
import { useTranslation } from '../hooks/useTranslation';
import { AddLocationModal } from '@/components/AddLocationModal';
import { AddMemberModal } from '../components/AddMemberModal';
import { MembersTab } from '../components/MembersTab';
import { useConfirm } from '@/hooks/useConfirm';
import { useNotification } from '@/hooks/useNotification';
import { CommentModal } from '@/components/CommentModal';
import { AddPhotoModal } from '@/components/AddPhotoModal'; 
import { TourChat } from '../components/TourChat';
import { MapContainer, TileLayer, Marker, Popup, useMapEvents, Polyline, useMap, Tooltip } from 'react-leaflet';
import _MarkerClusterGroup from 'react-leaflet-cluster';
const MarkerClusterGroup = (_MarkerClusterGroup as any).default || _MarkerClusterGroup;
import { CoordinateSelectModal } from '../components/CoordinateSelectModal';
import {
  Map as MapIcon, 
  Wallet, 
  Image as ImageIcon, 
  Calendar, 
  Users,
  ChevronLeft,
  Settings,
  Quote,
  Plus,
  List,
  Map as MapIconLucide,
  MapPin,
  Search,
  LocateFixed,
  Loader2,
  Compass,
  Car,
  Bike,
  Navigation,
  Footprints,
  Flag,
  Clock,
  Check,
  X,
  MessageSquare,
  Share2,
  Tag as TagIcon,
  Trash2,
  FileText,
  Edit,
  Download,
  Heart
} from 'lucide-react';
import L from 'leaflet';

// Định nghĩa kiểu dữ liệu cho Địa điểm để khớp với Schema Prisma
type LocationType = 'MOVE' | 'VISIT' | 'REST' | 'EAT';

// Định nghĩa kiểu dữ liệu cho OSRM Route
interface OSRMRoute {
  geometry: {
    coordinates: [number, number][]; // [lng, lat]
  };
  distance: number; // meters
  duration: number; // seconds
  legs: { distance: number; duration: number; }[]; // OSRM's internal legs for a route
}

// Định nghĩa kiểu dữ liệu cho điểm (bao gồm cả userLocation khi được chuyển đổi)
interface LocationPoint {
  latitude: number;
  longitude: number;
  id: string;
  name: string;
  type: string;
  legId: string;
}

// Fix lỗi icon mặc định của Leaflet cho môi trường Vite
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
  iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
  iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
  shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
});

/**
 * Helper tính khoảng cách giữa 2 tọa độ (Haversine formula)
 */
function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number) {
  const p = 0.017453292519943295; // Math.PI / 180
  const c = Math.cos;
  const a = 0.5 - c((lat2 - lat1) * p) / 2 + 
            c(lat1 * p) * c(lat2 * p) * 
            (1 - c((lon2 - lon1) * p)) / 2;
  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

// Helper function to combine segment routes into a single overall route
const combineSegmentRoutes = (segmentRoutes: OSRMRoute[][], selectedIndices: number[]): OSRMRoute | null => {
  if (segmentRoutes.length === 0) return null;

  let combinedGeometry: [number, number][] = [];
  let combinedDistance = 0;
  let combinedDuration = 0;
  const combinedLegs: { distance: number; duration: number; }[] = [];

  for (let i = 0; i < segmentRoutes.length; i++) {
    const segmentIndex = selectedIndices[i] !== undefined ? selectedIndices[i] : 0; // Default to first alternative
    const chosenRoute = segmentRoutes[i][segmentIndex];

    if (!chosenRoute) {
      // If a segment has no chosen route (e.g., no alternatives or API failed),
      // we cannot form a complete route.
      return null;
    }

    // Concatenate geometry, avoiding duplicate points at segment junctions
    if (i > 0 && combinedGeometry.length > 0 && chosenRoute.geometry.coordinates.length > 0) {
      const lastPointOfPrev = combinedGeometry[combinedGeometry.length - 1];
      const firstPointOfCurrent = chosenRoute.geometry.coordinates[0];
      // OSRM coordinates are [lng, lat]
      if (Math.abs(lastPointOfPrev[0] - firstPointOfCurrent[0]) < 1e-6 &&
          Math.abs(lastPointOfPrev[1] - firstPointOfCurrent[1]) < 1e-6) {
        combinedGeometry = combinedGeometry.concat(chosenRoute.geometry.coordinates.slice(1));
      } else {
        combinedGeometry = combinedGeometry.concat(chosenRoute.geometry.coordinates);
      }
    } else {
      combinedGeometry = combinedGeometry.concat(chosenRoute.geometry.coordinates);
    }
    
    combinedDistance += chosenRoute.distance;
    combinedDuration += chosenRoute.duration;
    combinedLegs.push(...chosenRoute.legs); // OSRM legs are sub-segments within a route
  }

  return {
    geometry: { coordinates: combinedGeometry },
    distance: combinedDistance,
    duration: combinedDuration,
    legs: combinedLegs,
  };
};

// Component Helper để tự động điều chỉnh khung nhìn bản đồ bao phủ toàn bộ lộ trình
const MapTourBounds = ({ locations }: { locations: any[] }) => {
  const map = useMap();
  const shouldFitRef = useRef(true);
  const prevLocKeyRef = useRef<string | null>(null);

  const locKey = useMemo(() => JSON.stringify(locations.map((l: any) => [l.latitude, l.longitude])), [locations]);

  useEffect(() => {
    if (locations.length === 0) return;

    if (prevLocKeyRef.current !== null && prevLocKeyRef.current !== locKey) {
      shouldFitRef.current = true;
    }
    prevLocKeyRef.current = locKey;

    if (!shouldFitRef.current) return;

    const bounds = L.latLngBounds(locations.map((l: any) => [l.latitude, l.longitude]));
    if (locations.length === 1) {
      map.setView([locations[0].latitude, locations[0].longitude], 15, { animate: true });
    } else {
      map.fitBounds(bounds, { padding: [50, 50], maxZoom: 15 });
    }
    shouldFitRef.current = false;
  }, [locKey, map, locations.length]);

  return null;
};
// Component Helper để di chuyển tâm bản đồ về vị trí người dùng khi nhấn nút
const RecenterUser = ({ position, trigger }: { position: [number, number] | null, trigger: number }) => {
  const map = useMap();
  const lastTriggerRef = useRef(0);

  useEffect(() => {
    if (position && trigger > lastTriggerRef.current) {
      lastTriggerRef.current = trigger;
      map.setView(position, 16, { animate: true });
    }
  }, [trigger, position, map]);
  return null;
};

// Component Helper để xử lý xoay bản đồ theo hướng di chuyển
const MapRotationHandler = ({ rotation }: { rotation: number }) => {
  const map = useMap();
  // Sử dụng Ref để lưu trữ giá trị xoay cộng dồn, giúp bản đồ luôn xoay theo hướng ngắn nhất
  // Thay vì nhảy giá trị từ -359 về 0 (làm CSS xoay ngược 1 vòng), ta tính toán delta.
  const cumulativeRotationRef = useRef(0);
  const prevRotationRef = useRef(0);

  useEffect(() => {
    const container = map.getContainer();

    // Đảm bảo tâm xoay luôn ở giữa và kích hoạt tăng tốc phần cứng để giảm lag trên iOS
    container.style.transformOrigin = 'center center';
    container.style.willChange = 'transform';

    if (rotation === 0) {
      cumulativeRotationRef.current = 0;
      prevRotationRef.current = 0;
      container.style.transform = `rotate(0deg) scale(1)`;
      return;
    }

    let delta = rotation - prevRotationRef.current;
    // Chuẩn hóa delta trong khoảng [-180, 180] để tìm hướng xoay gần nhất
    if (delta > 180) delta -= 360;
    else if (delta < -180) delta += 360;

    cumulativeRotationRef.current += delta;
    prevRotationRef.current = rotation;

    // Áp dụng transform với giá trị cộng dồn liên tục. 
    // 1. Dùng translateZ(0) để kích hoạt GPU trên iOS.
    // 2. Giảm scale xuống ~1.6 (vừa đủ che góc) để giảm tải cho bộ nhớ đệm đồ họa.
    container.style.transform = `rotate(${cumulativeRotationRef.current}deg) scale(2.2) translateZ(0)`;
    container.style.transition = 'transform 0.15s ease-out';
  }, [rotation, map]);
  return null;
};

// Component Helper để hiển thị mẹo khi người dùng dừng chuột trên bản đồ quá 3 giây
const MapHoverTip = ({ canEdit }: { canEdit: boolean }) => {
  const [tipPos, setTipPos] = useState<L.LatLng | null>(null);
  const [visible, setVisible] = useState(false);
  const timerRef = React.useRef<any>(null);

  useMapEvents({
    mousemove: (e) => {
      if (!canEdit) return;
      setVisible(false);
      setTipPos(e.latlng);
      if (timerRef.current) clearTimeout(timerRef.current);
      timerRef.current = setTimeout(() => {
        setVisible(true);
      }, 3000);
    },
    mousedown: () => {
      if (timerRef.current) clearTimeout(timerRef.current);
      setVisible(false);
    },
    dragstart: () => {
      if (timerRef.current) clearTimeout(timerRef.current);
      setVisible(false);
    },
    contextmenu: () => {
      if (timerRef.current) clearTimeout(timerRef.current);
      setVisible(false);
    }
  });

  if (!visible || !tipPos) return null;

  return (
    <Marker position={tipPos} icon={L.divIcon({ className: 'opacity-0' })}>
      <Tooltip direction="top" offset={[0, -10]} opacity={0.9} permanent>
        <span className="text-[10px] font-bold text-blue-600 whitespace-nowrap">Mẹo: nhấn giữ chuột phải để ghim</span>
      </Tooltip>
    </Marker>
  );
};
// Menu ngữ cảnh cho bản đồ
const MapContextMenu = ({ onAction, onOpen }: { onAction: (action: string, latlng: L.LatLng) => void; onOpen?: () => void }) => {
  const [menuPos, setMenuPos] = useState<{ x: number, y: number, latlng: L.LatLng } | null>(null);
  const menuRef = React.useRef<HTMLDivElement>(null);
  
  // Sử dụng selector để tránh re-render khi mapCenter thay đổi
  const legs = useTourStore(state => state.legs);
  const setMapCenter = useTourStore(state => state.setMapCenter);

  useMapEvents({
    contextmenu: (e) => {
      // Ngăn menu mặc định của trình duyệt hiện lên.
      if (e.originalEvent) {
        L.DomEvent.preventDefault(e.originalEvent);
        L.DomEvent.stopPropagation(e.originalEvent);
      }
      
      console.log(`[MAP] Context menu triggered at: ${e.latlng.lat}, ${e.latlng.lng}`);
      setMenuPos({ x: e.containerPoint.x, y: e.containerPoint.y, latlng: e.latlng });
      if (onOpen) onOpen();
    },
    
    moveend: (e) => {
      const map = e.target;
      const center = map.getCenter();
      const zoom = map.getZoom();
      const coords: [number, number] = [center.lat, center.lng];

      // Chỉ cập nhật store nếu tọa độ thay đổi đáng kể (> 0.0001) để tránh loop
      const currentStored = useTourStore.getState().mapCenter;
      const diff = Math.abs(currentStored[0] - coords[0]) + Math.abs(currentStored[1] - coords[1]);
      
      if (diff > 0.0001) {
        setMapCenter(coords);
      }

      localStorage.setItem('map_view_state', JSON.stringify({ center: coords, zoom }));
    },
    click: () => setMenuPos(null),
    dragstart: () => setMenuPos(null),
  });

  // Ngăn chặn các sự kiện của bản đồ khi tương tác với menu
  useEffect(() => {
    if (menuPos && menuRef.current) {
      L.DomEvent.disableClickPropagation(menuRef.current);
      L.DomEvent.disableScrollPropagation(menuRef.current);
    }
  }, [menuPos]);

  if (!menuPos) return null;

  return (
    <div 
      ref={menuRef}
      className="absolute z-[2000] bg-[var(--surface)] rounded-2xl shadow-2xl border border-[var(--border)] py-2 w-48 animate-in zoom-in-95 duration-200"
      style={{ top: menuPos.y, left: menuPos.x }}
      onClick={(e) => e.stopPropagation()}
      onContextMenu={(e) => e.preventDefault()}
    >
      <button onClick={() => { onAction('START', menuPos.latlng); setMenuPos(null); }} className="w-full text-left px-4 py-2 hover:bg-[var(--background)] text-sm font-bold text-[var(--text-secondary)] flex items-center gap-2">
        <div className="w-2 h-2 rounded-full bg-blue-600" /> Bắt đầu từ đây
      </button>
      <button onClick={() => { onAction('END', menuPos.latlng); setMenuPos(null); }} className="w-full text-left px-4 py-2 hover:bg-[var(--background)] text-sm font-bold text-[var(--text-secondary)] flex items-center gap-2 border-b border-[var(--border)]">
        <div className="w-2 h-2 rounded-full bg-green-600" /> Kết thúc ở đây
      </button>
      <div className="px-4 py-2 text-[10px] font-black text-[var(--text-muted)] uppercase tracking-widest">Thêm vào chặng</div>
      {legs.map(leg => (
        <button 
          key={leg.id}
          onClick={() => { onAction(`ADD_TO_LEG_${leg.id}`, menuPos.latlng); setMenuPos(null); }}
          className="w-full text-left px-4 py-2 hover:bg-[var(--background)] text-sm font-medium text-[var(--text-secondary)] truncate"
        >
          Chặng {leg.sequence}: {leg.note || 'Không có ghi chú'}
        </button>
      ))}
    </div>
  );
};

const getMostLikedPhoto = (photos: any[]) => {
  if (!photos || photos.length === 0) return null;
  return [...photos].sort((a, b) => {
    const likesA = a.metadata?.likedUserIds?.length || 0;
    const likesB = b.metadata?.likedUserIds?.length || 0;
    return likesB - likesA;
  })[0];
};

export const TourDetailPage = ({ 
  onBack, 
  tourId, 
  isPublicView = false, 
  onOpenNotes,
  onOpenNavigationPage
}: { 
  onBack: () => void, 
  tourId: string, 
  isPublicView?: boolean, 
  onOpenNotes?: () => void,
  onOpenNavigationPage?: (routeData: { origin: { lat: number; lng: number }; destination: { lat: number; lng: number; name: string }; tourTitle: string }) => void 
}) => {
  // Tách biệt các state và actions để tối ưu performance - Chuyển lên đầu để tránh lỗi initialization
  const { t } = useTranslation();
  const notify = useNotification();
  const confirm = useConfirm();
  const currentTour = useTourStore(state => state.currentTour);
  const legs = useTourStore(state => state.legs);
  const userRole = useTourStore(state => state.userRole);
  const mapCenter = useTourStore(state => state.mapCenter);
  const [userLocation, setUserLocation] = useState<[number, number] | null>(null); // Vị trí hiện tại của người dùng
  const [gpsHeading, setGpsHeading] = useState<number | null>(null); // Hướng di chuyển từ GPS
  const [userSpeed, setUserSpeed] = useState<number | null>(null); // Tốc độ di chuyển từ GPS

  // Di chuyển khai báo state lên trên useEffect để tránh lỗi "before initialization"
  const [activeTab, setActiveTab] = useState<'plan' | 'expense' | 'photo' | 'settings' | 'members' | 'chat'>(() => {
    const defaultTab = localStorage.getItem('tour_detail_default_tab');
    localStorage.removeItem('tour_detail_default_tab');
    if (defaultTab === 'chat') return 'chat';
    return 'plan';
  });
  const [mergingId, setMergingId] = useState<string | null>(null);
  const [unreadChatCount, setUnreadChatCount] = useState(0);
  const [viewMode, setViewMode] = useState<'map' | 'timeline'>('timeline');
  const [isHeadingMode, setIsHeadingMode] = useState(false);
  const [mapRotation, setMapRotation] = useState(0);
  const [isAddLocationOpen, setIsAddLocationOpen] = useState(false);
  const [isMapFullscreen, setIsMapFullscreen] = useState(false);
  const [isAddMemberOpen, setIsAddMemberOpen] = useState(false);
  const [isAddPhotoOpen, setIsAddPhotoOpen] = useState(false);

  useEffect(() => {
    (window as any).activeTourChatTab = activeTab === 'chat';
    return () => {
      (window as any).activeTourChatTab = false;
    };
  }, [activeTab]);

  const [isRatingModalOpen, setIsRatingModalOpen] = useState(false);
  const [ratingTargetUser, setRatingTargetUser] = useState<any>(null);
  const [ratingScores, setRatingScores] = useState({
    honesty: 5,
    transparency: 5,
    enthusiasm: 5,
    cheerfulness: 5,
    seriousness: 5,
    planning: 5,
    survival: 5
  });
  const [ratingComment, setRatingComment] = useState('');
  const [isSubmittingRating, setIsSubmittingRating] = useState(false);

  const handleSubmitRating = async () => {
    if (!ratingTargetUser) return;
    setIsSubmittingRating(true);
    try {
      const token = localStorage.getItem('token');
      const res = await fetch(`/api/v1/tours/${tourId}/ratings`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        },
        body: JSON.stringify({
          targetUserId: ratingTargetUser.userId || ratingTargetUser.user?.id,
          ...ratingScores,
          comment: ratingComment
        })
      });
      if (res.ok) {
        notify({ title: 'Thành công', message: 'Cảm ơn bạn đã gửi đánh giá!', type: 'success' });
        setIsRatingModalOpen(false);
        setRatingComment('');
        setRatingScores({
          honesty: 5,
          transparency: 5,
          enthusiasm: 5,
          cheerfulness: 5,
          seriousness: 5,
          planning: 5,
          survival: 5
        });
      } else {
        const err = await res.json();
        notify({ title: 'Lỗi', message: err.message || 'Lỗi khi gửi đánh giá.', type: 'error' });
      }
    } catch (error) {
      console.error(error);
      notify({ title: 'Lỗi', message: 'Lỗi mạng khi gửi đánh giá.', type: 'error' });
    } finally {
      setIsSubmittingRating(false);
    }
  };

  const [shareStatus, setShareStatus] = useState<{ isEnabled: boolean; token: string } | null>(null);
  
  const fetchShareStatus = async () => {
    if (isPublicView) return;
    try {
      const token = localStorage.getItem('token');
      const res = await fetch(`/api/v1/tours/${tourId}/share`, {
        headers: { 'Authorization': `Bearer ${token}` }
      });
      if (res.ok) {
        const data = await res.json();
        setShareStatus(data);
      }
    } catch (e) {
      console.error('Error fetching share status:', e);
    }
  };

  const handleToggleShare = async (isEnabled: boolean) => {
    try {
      const token = localStorage.getItem('token');
      const res = await fetch(`/api/v1/tours/${tourId}/share`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        },
        body: JSON.stringify({ isEnabled })
      });
      if (res.ok) {
        const data = await res.json();
        setShareStatus(data);
        notify({
          title: 'Thành công',
          message: isEnabled ? 'Đã bật chia sẻ hành trình cứu hộ.' : 'Đã tắt chia sẻ.',
          type: 'success'
        });
      }
    } catch (e) {
      console.error(e);
    }
  };

  const handleExportPDF = async () => {
    const doc = new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' });

    doc.addFileToVFS("Roboto-Regular.ttf", robotoBase64);
    doc.addFont("Roboto-Regular.ttf", "Roboto", "normal");
    doc.addFileToVFS("Roboto-Bold.ttf", robotoBoldBase64);
    doc.addFont("Roboto-Bold.ttf", "Roboto", "bold");
    doc.setFont("Roboto");

    const titleText = `LỊCH TRÌNH TOUR: ${currentTour?.title?.toUpperCase() || 'HÀNH TRÌNH TOUR'}`;
    doc.setFontSize(16);
    doc.text(titleText, 148.5, 15, { align: 'center' });

    let startY = 22;
    if (currentTour?.description) {
      doc.setFontSize(10);
      doc.text(currentTour.description, 148.5, startY, { align: 'center' });
      startY += 6;
    }

    const dateRangeStr = `Thời gian: ${currentTour?.startDate ? new Date(currentTour.startDate).toLocaleDateString('vi-VN') : ''} - ${currentTour?.endDate ? new Date(currentTour.endDate).toLocaleDateString('vi-VN') : ''}`;
    doc.setFontSize(10);
    doc.text(dateRangeStr, 148.5, startY, { align: 'center' });
    startY += 8;

    const tableColumn = ["STT", "Ngày giờ", "Chặng", "Địa điểm", "Ghi chú"];
    const tableRows: any[] = [];
    const legRowRanges: Record<string, { start: number; count: number }> = {};
    const pdfMapLinks: { [key: number]: string } = {};

    let stt = 1;
    let globalRowIndex = 0;

    const extractAndFormatTimeInline = (primaryTime: any, fallbackLegObj: any) => {
      const absoluteTimeSource = primaryTime || 
                                  fallbackLegObj?.plannedStart || 
                                  fallbackLegObj?.startDate || 
                                  fallbackLegObj?.start_date || 
                                  fallbackLegObj?.date || 
                                  fallbackLegObj?.createdAt;

      if (!absoluteTimeSource) return '';

      const d = new Date(absoluteTimeSource);
      if (isNaN(d.getTime())) return '';

      const hhmm = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
      const ddmmyyyy = `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()}`;
      return `${hhmm}|${ddmmyyyy}`;
    };

    if (currentTour?.legs && currentTour.legs.length > 0) {
      currentTour.legs.forEach((leg: any, legIdx: number) => {
        const legName = leg.note || `Chặng ${legIdx + 1}`;
        const legNameCellObj = {
          content: legName,
          styles: { fontStyle: 'bold' as const }
        };

        const legLocations = (leg.locations || []).filter((loc: any) =>
          loc && (loc.plannedStart || loc.plannedEnd || loc.name)
        );

        const startRow = globalRowIndex;

        if (legLocations.length > 0) {
          legRowRanges[leg.id] = { start: startRow, count: legLocations.length };

          legLocations.forEach((loc: any, locIdx: number) => {
            const isStartPoint = loc.plannedStart && new Date(loc.plannedStart).getTime() === 0;
            const initialTimeSource = isStartPoint ? loc.plannedEnd : loc.plannedStart;

            const timeStr = extractAndFormatTimeInline(initialTimeSource, leg);

            const locName = loc.name || '';
            const addressStr = loc.address || '';
            const coordStr = loc.latitude && loc.longitude ? `\n${loc.latitude}, ${loc.longitude}` : '';
            const locationText = [locName, addressStr, coordStr].filter(Boolean).join('\n');
            const noteText = loc.note || '';

            let mapUrl = '';
            if (loc.latitude && loc.longitude) {
              mapUrl = `https://www.google.com/maps/search/?api=1&query=${loc.latitude},${loc.longitude}`;
            } else if (addressStr || locName) {
              mapUrl = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(addressStr || locName)}`;
            }

            const currentRowPosition = tableRows.length;
            if (mapUrl) {
              pdfMapLinks[currentRowPosition] = mapUrl;
            }

            const locationCellObj = {
              content: locationText,
              styles: mapUrl ? { textColor: [40, 83, 107], fontStyle: 'bold' as const } : {}
            };

            tableRows.push([
              stt++,
              timeStr,
              locIdx === 0 ? legNameCellObj : '',
              locationCellObj,
              noteText
            ]);
            globalRowIndex++;
          });
        } else {
          const legTimeStr = extractAndFormatTimeInline(null, leg);

          legRowRanges[leg.id] = { start: startRow, count: 1 };
          tableRows.push([
            stt++,
            legTimeStr,
            legNameCellObj,
            'Chưa có địa điểm trong chặng này',
            ''
          ]);
          globalRowIndex++;
        }
      });
    }

    if (tableRows.length === 0) {
      tableRows.push(["-", "-", "-", "Chưa có chặng hoặc địa điểm nào trong hành trình.", "-"]);
    }

    autoTable(doc, {
      head: [tableColumn],
      headStyles: {
        fillColor: [37, 99, 235],
        textColor: [255, 255, 255],
        font: 'Roboto',
        fontStyle: 'bold',
        halign: 'center',
        valign: 'middle'
      },
      body: tableRows,
      startY: startY,
      theme: 'grid',
      styles: {
        font: "Roboto",
        fontSize: 9,
        cellPadding: 3,
        overflow: 'linebreak',
        valign: 'top'
      },
      columnStyles: {
        0: { cellWidth: 12, halign: 'center', valign: 'middle' },
        1: { cellWidth: 50, halign: 'center', valign: 'middle' },
        2: { cellWidth: 45, halign: 'center', valign: 'middle' },
        3: { cellWidth: 90, valign: 'top' },
        4: { cellWidth: 70, valign: 'top' }
      },
      margin: { left: 15, right: 15 },
      didParseCell: (cell: any) => {
        if (cell.section === 'body') {
          if (cell.column.index === 2) {
            let assigned = false;
            for (const leg of currentTour?.legs || []) {
              const range = legRowRanges[leg.id];
              if (range && cell.row.index >= range.start && cell.row.index < range.start + range.count) {
                if (cell.row.index === range.start) {
                  cell.rowSpan = range.count;
                } else {
                  cell.rowSpan = 0;
                }
                assigned = true;
                break;
              }
            }
            if (!assigned) {
              cell.rowSpan = 1;
            }
          }
        }
      },
      willDrawCell: (data: any) => {
        if (data.section === 'body' && data.column.index === 1) {
          if (data.cell.text && data.cell.text.length > 0) {
            data.cell.customInlineBuffer = data.cell.text.join('');
          }
          data.cell.text = [];
        }
      },
      didDrawCell: (data: any) => {
        if (data.section === 'body' && data.column.index === 1) {
          const rawTextStr = data.cell.customInlineBuffer || data.cell.raw;

          if (rawTextStr && typeof rawTextStr === 'string' && rawTextStr.includes('|')) {
            const [timePart, datePart] = rawTextStr.split('|');
            const separatorSpace = "   ";

            data.doc.setFont(data.cell.styles.font, 'bold');
            const timeWidth = data.doc.getTextWidth(timePart);

            data.doc.setFont(data.cell.styles.font, 'normal');
            const spaceWidth = data.doc.getTextWidth(separatorSpace);
            const dateWidth = data.doc.getTextWidth(datePart);

            const totalBlockWidth = timeWidth + spaceWidth + dateWidth;

            const targetX = data.cell.x + (data.cell.width - totalBlockWidth) / 2;
            const targetY = data.cell.y + (data.cell.height / 2) + (data.cell.styles.fontSize / 2) - 1;

            data.doc.setFont(data.cell.styles.font, 'bold');
            data.doc.setTextColor(239, 68, 68);
            data.doc.text(timePart, targetX, targetY);

            data.doc.setFont(data.cell.styles.font, 'normal');
            data.doc.setTextColor(37, 99, 235);
            data.doc.text(datePart, targetX + timeWidth + spaceWidth, targetY);
          }
        }

        if (data.section === 'body' && data.column.index === 3) {
          const activeRowIndex = data.row.index;
          const targetMapUrl = pdfMapLinks[activeRowIndex];
          if (targetMapUrl) {
            data.doc.link(
              data.cell.x,
              data.cell.y,
              data.cell.width,
              data.cell.height,
              { url: targetMapUrl }
            );
          }
        }
      }
    });

    try {
      notify({ title: 'Đang tạo PDF...', message: 'Vui lòng chờ trong giây lát.', type: 'info' });
      doc.save(`Lich_trinh_${currentTour?.title || 'tour'}.pdf`);
      notify({ title: 'Thành công', message: 'Lịch trình đã được xuất ra tập tin PDF thành công.', type: 'success' });
    } catch (err) {
      console.error(err);
      notify({ title: 'Lỗi', message: 'Không thể xuất PDF lịch trình.', type: 'error' });
    }
  };

  const handleExportCSV = () => {
    if (!currentTour) return;

    // CSV Header với UTF-8 BOM để Excel hiển thị đúng dấu tiếng Việt
    let csvContent = '\uFEFF'; 
    csvContent += 'Chặng,Địa điểm,Địa chỉ,Thời gian đến,Thời gian đi,Ghi chú\n';

    if (currentTour.legs && currentTour.legs.length > 0) {
      currentTour.legs.forEach((leg: any, legIdx: number) => {
        const legTitle = leg.note || `Chặng ${legIdx + 1}`;
        if (leg.locations && leg.locations.length > 0) {
          leg.locations.forEach((loc: any) => {
            const row = [
              legTitle,
              loc.name || '',
              loc.address || '',
              loc.arrivalTime ? new Date(loc.arrivalTime).toLocaleString('vi-VN') : '',
              loc.departureTime ? new Date(loc.departureTime).toLocaleString('vi-VN') : '',
              loc.notes || ''
            ].map(val => `"${val.replace(/"/g, '""')}"`).join(',');
            csvContent += row + '\n';
          });
        } else {
          csvContent += `"${legTitle.replace(/"/g, '""')}","Chưa có địa điểm",,,,\n`;
        }
      });
    }

    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', `Lich_trinh_${currentTour.title || 'tour'}.csv`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    
    notify({
      title: 'Thành công',
      message: 'Đã xuất lịch trình ra tệp CSV (Google Sheets) thành công.',
      type: 'success'
    });
  };


  useEffect(() => {
    fetchShareStatus();
  }, [tourId]);

  // State cho vị trí và hướng của người dùng
  

 
  const [deviceOrientationHeading, setDeviceOrientationHeading] = useState<number | null>(null); // Hướng thiết bị (la bàn)

  // Xác định hướng hiển thị của người dùng (ưu tiên hướng di chuyển từ GPS, sau đó đến la bàn thiết bị)
  const currentHeading = useMemo(() => {
    if (gpsHeading !== null && userSpeed !== null && userSpeed > 0.5) {
      return gpsHeading;
    } else if (deviceOrientationHeading !== null) {
      return deviceOrientationHeading;
    }
    return 0;
  }, [gpsHeading, userSpeed, deviceOrientationHeading]);

  // Định nghĩa Icons bên trong Component bằng useMemo để đảm bảo tính ổn định và tránh lỗi render
  const mapIcons = useMemo(() => ({
    start: L.divIcon({
      className: '!bg-transparent !border-none',
      html: `<div class="w-7 h-7 bg-blue-600 rounded-full border-2 border-white shadow-xl flex items-center justify-center text-[11px] font-black text-white animate-in zoom-in duration-300">S</div>`,
      iconSize: [28, 28],
      iconAnchor: [14, 14]
    }),
    end: L.divIcon({
      className: '!bg-transparent !border-none',
      html: `<div class="w-7 h-7 bg-green-600 rounded-full border-2 border-white shadow-xl flex items-center justify-center text-[11px] font-black text-white animate-in zoom-in duration-300">E</div>`,
      iconSize: [28, 28],
      iconAnchor: [14, 14]
    }),
    visit: L.divIcon({
      className: '!bg-transparent !border-none',
      html: `<div class="w-5 h-5 bg-indigo-500 rounded-full border-2 border-white shadow-lg hover:scale-125 transition-transform flex items-center justify-center"><div class="w-1.5 h-1.5 bg-white rounded-full opacity-50"></div></div>`,
      iconSize: [20, 20],
      iconAnchor: [10, 10]
    }),
    user: L.divIcon({
      className: '!bg-transparent !border-none',
      html: `
        <div class="relative flex items-center justify-center">
          <!-- Hiệu ứng ping tỏa lan -->
          <div class="absolute w-8 h-8 bg-blue-400 rounded-full opacity-30 animate-ping"></div>
          
          <!-- Marker chính màu xanh -->
          <div class="w-5 h-5 bg-blue-600 rounded-full border-2 border-white shadow-xl flex items-center justify-center z-10">
            <!-- Mũi tên chỉ hướng nhìn (xoay theo heading) -->
            <div style="transform: rotate(${currentHeading}deg); transition: transform 0.2s ease-out;" class="absolute inset-0 flex flex-col items-center">
              <div class="w-0 h-0 border-l-[5px] border-l-transparent border-r-[5px] border-r-transparent border-b-[8px] border-b-white mt-[1px]"></div>
            </div>
          </div>
        </div>
      `,
      iconSize: [32, 32],
      iconAnchor: [16, 16]
    })
  }), [currentHeading]);

  useEffect(() => {
    // Theo dõi vị trí GPS của người dùng (bao gồm hướng và tốc độ khi di chuyển)
    if (!isPublicView && navigator.geolocation) {
      const watchId = navigator.geolocation.watchPosition(
        (pos) => {
          setUserLocation([pos.coords.latitude, pos.coords.longitude]);
          setGpsHeading(pos.coords.heading);
          setUserSpeed(pos.coords.speed);
        },
        (err) => console.warn("Lỗi định vị người dùng:", err),
        { enableHighAccuracy: true }
      );
      return () => navigator.geolocation.clearWatch(watchId);
    } else {
      setGpsHeading(null);
      setUserSpeed(null);
    }
  }, [isPublicView]); // Chỉ phụ thuộc vào isPublicView

  // State mới cho hướng thiết bị (la bàn)
  

  // Theo dõi hướng thiết bị (la bàn)
  useEffect(() => {
    let lastHeading: number | null = null;

    const handleOrientation = (event: any) => {
      let heading: number | null = null;

      // 1. Đối với iOS: Sử dụng webkitCompassHeading (đã chuẩn hóa hướng Bắc thực)
      if (event.webkitCompassHeading !== undefined && event.webkitCompassHeading !== null) {
        heading = event.webkitCompassHeading;
      } 
      // 2. Đối với Android (Chrome): Cần kiểm tra tính tuyệt đối của dữ liệu
      else if (event.alpha !== null && event.alpha !== undefined) {
        if (event.absolute === true || event.type === 'deviceorientationabsolute') {
          heading = (360 - event.alpha) % 360;
        }
      }

      if (heading !== null) {
        // Chỉ cập nhật nếu hướng thay đổi lớn hơn 2 độ để giảm tải vẽ lại
        if (lastHeading === null || Math.abs(heading - lastHeading) > 2) {
          lastHeading = heading;
          setDeviceOrientationHeading(heading);
        }
      }
    };

    // Đăng ký cả hai loại sự kiện để hỗ trợ tối đa các dòng điện thoại
    window.addEventListener('deviceorientation', handleOrientation, true);
    window.addEventListener('deviceorientationabsolute', handleOrientation, true);

    return () => {
      window.removeEventListener('deviceorientation', handleOrientation, true);
      window.removeEventListener('deviceorientationabsolute', handleOrientation, true);
    };
  }, []);

  // Logic kết hợp để xác định hướng xoay bản đồ
  useEffect(() => {
    if (!isHeadingMode) {
      setMapRotation(0); // Đặt lại hướng Bắc nếu chế độ xoay tắt
      return;
    }

    let newRotation: number | null = null;
    // Ưu tiên hướng GPS nếu có và người dùng đang di chuyển (tốc độ > 0.5 m/s)
    if (gpsHeading !== null && userSpeed !== null && userSpeed > 0.5) {
      newRotation = -gpsHeading;
    } else if (deviceOrientationHeading !== null) {
      // Nếu không di chuyển hoặc không có hướng GPS, dùng hướng thiết bị
      newRotation = -deviceOrientationHeading;
    }

    if (newRotation !== null) {
      // Cập nhật ngay lập tức để tăng độ nhạy, CSS transition sẽ lo phần mượt mà
      setMapRotation(newRotation);
    }
  }, [isHeadingMode, gpsHeading, userSpeed, deviceOrientationHeading]);

  const [isStartPointAction, setIsStartPointAction] = useState(false);
  const [isEndPointAction, setIsEndPointAction] = useState(false);
  const [targetLegId, setTargetLegId] = useState<string | null>(null);
  const [editingLocation, setEditingLocation] = useState<any>(null);
  const [selectedMember, setSelectedMember] = useState<any>(null);
  const [isMemberDetailOpen, setIsMemberDetailOpen] = useState(false);
  const [selectedPhotoForDisplay, setSelectedPhotoForDisplay] = useState<any | null>(null); // New state for large photo display
  const currentUserId = useMemo(() => {
    const token = localStorage.getItem('token') || localStorage.getItem('guest_token');
    if (!token) return null;
    try {
      return JSON.parse(atob(token.split('.')[1])).sub;
    } catch (e) {
      return null;
    }
  }, []);

  const currentUser = useMemo(() => {
    const userStr = localStorage.getItem('user') || localStorage.getItem('guest_user');
    if (!userStr) return null;
    try {
      return JSON.parse(userStr);
    } catch (e) {
      return null;
    }
  }, []);

  const [isEditingPhoto, setIsEditingPhoto] = useState(false);
  const [editPhotoTitle, setEditPhotoTitle] = useState('');
  const [editPhotoDescription, setEditPhotoDescription] = useState('');
  const [editPhotoLat, setEditPhotoLat] = useState<number | ''>('');
  const [editPhotoLng, setEditPhotoLng] = useState<number | ''>('');
  const [isSavingPhotoEdit, setIsSavingPhotoEdit] = useState(false);
  const [isMapOpen, setIsMapOpen] = useState(false);
  const [resolvedAddress, setResolvedAddress] = useState<string>('');
  const [isFullscreen, setIsFullscreen] = useState(false);

  const likedUserIds = selectedPhotoForDisplay && selectedPhotoForDisplay.metadata && Array.isArray(selectedPhotoForDisplay.metadata.likedUserIds)
    ? selectedPhotoForDisplay.metadata.likedUserIds
    : [];
  const isPhotoLiked = currentUser && likedUserIds.includes(currentUser.id);
  const photoLikeCount = likedUserIds.length;

  const handleToggleLikePhoto = async () => {
    if (!selectedPhotoForDisplay) return;
    try {
      const response = await fetch(`/api/v1/photos/${selectedPhotoForDisplay.id}/toggle-like`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token') || localStorage.getItem('guest_token')}`
        }
      });
      if (response.ok) {
        const data = await response.json();
        setSelectedPhotoForDisplay((prev: any) => {
          if (!prev) return null;
          return {
            ...prev,
            metadata: {
              ...prev.metadata,
              likedUserIds: data.likedUserIds
            }
          };
        });
        if (currentTour) {
          fetchTour(currentTour.id);
        }
      }
    } catch (error) {
      console.error('Error toggling like:', error);
    }
  };

  useEffect(() => {
    const lat = selectedPhotoForDisplay?.metadata?.lat;
    const lng = selectedPhotoForDisplay?.metadata?.lng;
    if (typeof lat === 'number' && typeof lng === 'number') {
      setResolvedAddress('Đang xác định địa điểm...');
      fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&accept-language=vi`)
        .then(res => {
          if (!res.ok) throw new Error();
          return res.json();
        })
        .then(data => {
          if (data && data.display_name) {
            const shortAddress = data.display_name.split(',').slice(0, 3).join(',').trim();
            setResolvedAddress(shortAddress || data.display_name);
          } else {
            setResolvedAddress(`${lat.toFixed(4)}, ${lng.toFixed(4)}`);
          }
        })
        .catch(() => {
          setResolvedAddress(`${lat.toFixed(4)}, ${lng.toFixed(4)}`);
        });
    } else {
      setResolvedAddress('Chưa xác định tọa độ');
    }
  }, [selectedPhotoForDisplay?.id, selectedPhotoForDisplay?.metadata?.lat, selectedPhotoForDisplay?.metadata?.lng]);

  useEffect(() => {
    if (selectedPhotoForDisplay) {
      setEditPhotoTitle(selectedPhotoForDisplay.metadata?.title || '');
      setEditPhotoDescription(selectedPhotoForDisplay.metadata?.description || '');
      setEditPhotoLat(selectedPhotoForDisplay.metadata?.lat ?? '');
      setEditPhotoLng(selectedPhotoForDisplay.metadata?.lng ?? '');
      setIsEditingPhoto(false);
    }
  }, [selectedPhotoForDisplay]);

  const handleSavePhotoEdit = async () => {
    if (!selectedPhotoForDisplay) return;
    if (editPhotoLat !== '' && (isNaN(editPhotoLat) || editPhotoLat < -90 || editPhotoLat > 90)) {
      notify({ title: 'Lỗi', message: 'Vĩ độ không hợp lệ (-90 đến 90).', type: 'error' });
      return;
    }
    if (editPhotoLng !== '' && (isNaN(editPhotoLng) || editPhotoLng < -180 || editPhotoLng > 180)) {
      notify({ title: 'Lỗi', message: 'Kinh độ không hợp lệ (-180 đến 180).', type: 'error' });
      return;
    }

    setIsSavingPhotoEdit(true);
    try {
      const response = await fetch(`/api/v1/photos/${selectedPhotoForDisplay.id}`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${localStorage.getItem('token') || localStorage.getItem('guest_token')}`
        },
        body: JSON.stringify({
          title: editPhotoTitle,
          description: editPhotoDescription,
          latitude: editPhotoLat === '' ? undefined : editPhotoLat,
          longitude: editPhotoLng === '' ? undefined : editPhotoLng
        })
      });

      if (!response.ok) throw new Error('Failed to update photo info');

      const updatedPhoto = await response.json();
      notify({ title: 'Thành công', message: 'Thông tin ảnh đã được cập nhật.', type: 'success' });
      
      setSelectedPhotoForDisplay((prev: any) => prev ? ({ ...prev, metadata: updatedPhoto.metadata }) : null);

      if (currentTour) {
        fetchTour(currentTour.id);
      }
      setIsEditingPhoto(false);
    } catch (error) {
      notify({ title: 'Lỗi', message: 'Không thể cập nhật thông tin ảnh. Vui lòng thử lại.', type: 'error' });
    } finally {
      setIsSavingPhotoEdit(false);
    }
  };
  const [joinRequests, setJoinRequests] = useState<any[]>([]);
  const [titleInput, setTitleInput] = useState(currentTour?.title ?? '');
  const [descriptionInput, setDescriptionInput] = useState(currentTour?.description ?? '');
  // State cho input số lượng người tham gia
  const [adultCountInput, setAdultCountInput] = useState(currentTour?.adultCount ?? 0);
  const [childCountInput, setChildCountInput] = useState(currentTour?.childCount ?? 0);
  const [childDiscountInput, setChildDiscountInput] = useState(currentTour?.childDiscount ?? 0);
  const [tagsInput, setTagsInput] = useState<string[]>(currentTour?.tags ?? []);
  const [customTag, setCustomTag] = useState('');
  const availableTags = ['Văn hóa', 'Mạo hiểm', 'Nghỉ dưỡng', 'Thư giãn', 'Ẩm thực', 'Khám phá', 'Gia đình'];
  const [selectedLegIdForPhoto, setSelectedLegIdForPhoto] = useState<string | 'all'>('all'); // Keep this state

  // Memoized filtered photos based on selectedLegIdForPhoto
  const filteredPhotos = useMemo(() => {
    if (!currentTour?.photos) return [];
    let photosToFilter = currentTour.photos;

    if (selectedLegIdForPhoto !== 'all') {
      const targetLeg = legs.find(l => l.id === selectedLegIdForPhoto);
      if (targetLeg) {
        const locationIdsInLeg = targetLeg.locations.map((loc: any) => loc.id);
        // Filter photos that have a locationId and that locationId is in the current leg
        photosToFilter = photosToFilter.filter((p: any) => p.locationId && locationIdsInLeg.includes(p.locationId));
      } else {
        photosToFilter = []; // If leg not found, no photos
      }
    }
    return photosToFilter;
  }, [currentTour?.photos, selectedLegIdForPhoto, legs]);

  // Effect to set initial selected photo for display or reset if current one is no longer in filtered list
  useEffect(() => {
    if (filteredPhotos.length > 0 && !selectedPhotoForDisplay) {
      setSelectedPhotoForDisplay(getMostLikedPhoto(filteredPhotos));
    } else if (selectedPhotoForDisplay && !filteredPhotos.some((p: any) => p.id === selectedPhotoForDisplay.id)) {
      setSelectedPhotoForDisplay(filteredPhotos.length > 0 ? getMostLikedPhoto(filteredPhotos) : null);
    }
  }, [filteredPhotos, selectedPhotoForDisplay]);
  const [isCommentModalOpen, setIsCommentModalOpen] = useState(false);
  const [commentLocationId, setCommentLocationId] = useState('');
  const [commentLocationName, setCommentLocationName] = useState('');
  const [joinRequestActionId, setJoinRequestActionId] = useState<string | null>(null);

  // State cho Modal ghi chú nhanh
  const [quickNoteLocName, setQuickNoteLocName] = useState<string | null>(null);
  const [quickNoteLegId, setQuickNoteLegId] = useState<string | null>(null);
  const [quickNoteLocation, setQuickNoteLocation] = useState<any>(null);
  const [quickNoteInput, setQuickNoteInput] = useState('');

  // Đồng bộ hóa các ô nhập dữ liệu cài đặt với currentTour khi tour tải/cập nhật
  useEffect(() => {
    if (currentTour) {
      setTitleInput(currentTour.title ?? '');
      setDescriptionInput(currentTour.description ?? '');
      setAdultCountInput(currentTour.adultCount ?? 0);
      setChildCountInput(currentTour.childCount ?? 0);
      setChildDiscountInput(currentTour.childDiscount ?? 0);
      setTagsInput(currentTour.tags ?? []);
    }
  }, [currentTour]);

  // State tìm kiếm cho chế độ Bản đồ trong Tab Lộ trình
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState<any[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const [locateTrigger, setLocateTrigger] = useState(0);
  const [isMapControlsOpen, setIsMapControlsOpen] = useState(false);
  const [isRoutingLoading, setIsRoutingLoading] = useState(false);
  const [travelMode, setTravelMode] = useState<'driving' | 'bike' | 'foot'>('driving');
  const [routes, setRoutes] = useState<any[]>([]);
  const [selectedRouteIndex, setSelectedRouteIndex] = useState(0);
  const [routeMenu, setRouteMenu] = useState<{ x: number, y: number, index: number } | null>(null);
  const [drivingRoute, setDrivingRoute] = useState<[number, number][]>([]);
  const [segmentDistances, setSegmentDistances] = useState<number[]>([]);

  const handleSearchLocation = async (query: string) => {
    setSearchQuery(query);
    if (query.trim().length < 2) {
      setSearchResults([]);
      return;
    }
    setIsSearching(true);
    try {
      const res = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=5&addressdetails=1&namedetails=1&accept-language=vi`);
      const data = await res.json();
      setSearchResults(data);
    } catch (e) {
      console.error("Lỗi tìm kiếm:", e);
    } finally {
      setIsSearching(false);
    }
  };

  const handleDeletePhoto = async (photoId: string) => {
    const isConfirmed = await confirm({
      title: 'Xóa ảnh này?',
      message: 'Bạn có chắc chắn muốn xóa ảnh này khỏi chuyến đi? Hành động này không thể hoàn tác.'
    });

    if (!isConfirmed) return;

    try {
      const response = await fetch(`/api/v1/photos/${photoId}`, {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('token') || localStorage.getItem('guest_token')}`
        }
      });

      if (!response.ok) throw new Error('Không thể xóa ảnh');

      notify({ title: 'Thành công', message: 'Đã xóa ảnh.', type: 'success' });
      fetchTour(tourId); // Re-fetch tour to update photo list
      setSelectedPhotoForDisplay(null); // Reset selected photo after deletion
    } catch (error) {
      notify({ title: 'Lỗi', message: 'Không thể xóa ảnh. Vui lòng thử lại.', type: 'error' });
    }
  };

  const fetchTour = useTourStore(state => state.fetchTour);
  const fetchPublicTourDetails = useTourStore(state => state.fetchPublicTourDetails); // New action
  
  useEffect(() => {
    if (currentTour) {
      setTagsInput(currentTour.tags || []);
    }
  }, [currentTour]);

  // Hàm tối ưu để cập nhật số lượng bình luận mà không cần fetch lại toàn bộ Tour
  const handleCommentIncrement = (locationId: string) => {
    const currentLegs = useTourStore.getState().legs;
    const updatedLegs = currentLegs.map((leg: any) => ({
      ...leg,
      locations: leg.locations.map((loc: any) => 
        loc.id === locationId 
          ? { ...loc, _count: { ...loc._count, comments: (loc._count?.comments || 0) + 1 } }
          : loc
      )
    }));
    // Cập nhật trực tiếp vào Store
    useTourStore.setState({ legs: updatedLegs });
  };

  const handleCommentDecrement = (locationId: string) => {
    const currentLegs = useTourStore.getState().legs;
    const updatedLegs = currentLegs.map((leg: any) => ({
      ...leg,
      locations: leg.locations.map((loc: any) => 
        loc.id === locationId 
          ? { ...loc, _count: { ...loc._count, comments: Math.max(0, (loc._count?.comments || 1) - 1) } }
          : loc
      )
    }));
    useTourStore.setState({ legs: updatedLegs });
  };

  const setMapCenter = useTourStore(state => state.setMapCenter);
  const updateTourStartPoint = useTourStore(state => state.updateTourStartPoint);
  const updateTourEndPoint = useTourStore(state => state.updateTourEndPoint);
  const updateTourDetails = useTourStore(state => state.updateTourDetails); // Thêm action này
  const addLocation = useTourStore(state => state.addLocation);
  const removeMember = useTourStore(state => state.removeMember);
  const fetchJoinRequests = useTourStore(state => state.fetchJoinRequests);
  const acceptJoinRequest = useTourStore(state => state.acceptJoinRequest);
  const rejectJoinRequest = useTourStore(state => state.rejectJoinRequest);
  const deleteTour = useTourStore(state => state.deleteTour);

  const toggleCompassMode = async () => {
    if (!isHeadingMode) {
      if (
        typeof DeviceOrientationEvent !== 'undefined' &&
        typeof (DeviceOrientationEvent as any).requestPermission === 'function'
      ) {
        try {
          const permissionState = await (DeviceOrientationEvent as any).requestPermission();
          if (permissionState === 'granted') {
            setIsHeadingMode(true);
          } else {
            alert("Để xoay bản đồ theo hướng di chuyển, vui lòng cấp quyền truy cập cảm biến hướng (La bàn).");
          }
        } catch (error) {
          console.error("Error requesting compass permission:", error);
          setIsHeadingMode(true);
        }
      } else {
        setIsHeadingMode(true);
      }
    } else {
      setIsHeadingMode(false);
      setMapRotation(0);
    }
  };

  // Khôi phục vị trí và mức zoom từ localStorage
  const [initialViewState] = useState(() => {
    const saved = localStorage.getItem('map_view_state');
    if (saved) {
      try { return JSON.parse(saved); } catch (e) { return null; }
    }
    return null;
  });

  // SỬA LỖI: Sử dụng các selectors riêng lẻ để tránh re-render trang khi mapCenter trong store thay đổi
  // Nếu là public view, không có quyền chỉnh sửa
  const canEdit = isPublicView ? false : ['OWNER', 'MANAGER'].includes(userRole || '');
  const canInvite = isPublicView ? false : ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '');
  const canUploadPhoto = isPublicView ? false : ['OWNER', 'MANAGER', 'MEMBER', 'MEMBER_NO_FINANCE'].includes(userRole || '');
  const isOwner = isPublicView ? false : userRole === 'OWNER';
  const canShare = isPublicView || ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '');
  const canManage = isOwner || (!isPublicView && userRole === 'MANAGER');

  const duplicateMatches = useMemo(() => {
    if (!canManage || !currentTour?.participants) return [];
    
    const manualMembers = currentTour.participants.filter((p: any) => !p.userId && p.displayName);
    const systemMembers = currentTour.participants.filter((p: any) => p.userId && p.user?.name);
    
    const matches: Array<{ manual: any; system: any }> = [];
    
    manualMembers.forEach((m: any) => {
      const match = systemMembers.find((s: any) => {
        return s.user.name.trim().toLowerCase() === m.displayName.trim().toLowerCase();
      });
      if (match) {
        matches.push({ manual: m, system: match });
      }
    });
    
    return matches;
  }, [canManage, currentTour?.participants]);

  useEffect(() => {
    if (isPublicView) {
      fetchPublicTourDetails(tourId);
    } else if (currentTour && ['OWNER', 'MANAGER'].includes(userRole || '')) {
      fetchJoinRequests(currentTour.id).then(setJoinRequests).catch(() => setJoinRequests([]));
    }
    // Fetch tour details when tourId changes or public view status changes
    if (tourId) { isPublicView ? fetchPublicTourDetails(tourId) : fetchTour(tourId); }
  }, [tourId, isPublicView, userRole]); // Add tourId to dependencies

  // New useEffect to manage initial photo display when currentTour or legs change
  useEffect(() => {
    if (currentTour && currentTour.photos && currentTour.photos.length > 0) {
      // If there are photos, and no leg is selected, default to 'all' and first photo
      if (selectedLegIdForPhoto === 'all' && !selectedPhotoForDisplay) {
        setSelectedPhotoForDisplay(getMostLikedPhoto(currentTour.photos));
      } else if (selectedLegIdForPhoto !== 'all') {
        // If a specific leg is selected, try to find a photo for that leg
        const targetLeg = legs.find(l => l.id === selectedLegIdForPhoto);
        if (targetLeg) {
          const locationIdsInLeg = targetLeg.locations.map((loc: any) => loc.id);
          const photosInLeg = currentTour.photos.filter((p: any) => p.locationId && locationIdsInLeg.includes(p.locationId));
          if (photosInLeg.length > 0 && !selectedPhotoForDisplay) {
            setSelectedPhotoForDisplay(getMostLikedPhoto(photosInLeg));
          } else if (selectedPhotoForDisplay && !photosInLeg.some((p: any) => p.id === selectedPhotoForDisplay.id)) {
            setSelectedPhotoForDisplay(photosInLeg.length > 0 ? getMostLikedPhoto(photosInLeg) : null);
          }
        }
      }
    }
  }, [currentTour, legs, selectedLegIdForPhoto, selectedPhotoForDisplay]);
  const [mapZoom] = useState(initialViewState?.zoom || 13);

  // Memoize danh sách tọa độ để MapTourBounds không bị trigger thừa
  const allLocations = useMemo(() => legs.flatMap(l => l.locations), [legs]);

  // Tạo key định danh cho lộ trình để buộc bản đồ vẽ lại khi dữ liệu thay đổi
  const routeKey = useMemo(() => JSON.stringify({
    locations: allLocations.map(l => ({ id: l.id, lat: l.latitude, lon: l.longitude })),
    user: userLocation ? { lat: userLocation[0].toFixed(5), lon: userLocation[1].toFixed(5) } : null,
    travelMode: travelMode,
    selectedRouteIndex: selectedRouteIndex // Include selectedRouteIndex to force re-render when alternative is chosen
  }), [allLocations, userLocation, travelMode, selectedRouteIndex]);

  // Tự động tìm các quãng đường di chuyển thực tế theo phương tiện và vẽ lên bản đồ
  useEffect(() => {
    const fetchRoutes = async () => {
       // Prepare points: userLocation + allLocations
      const currentPoints: LocationPoint[] = [...allLocations];
      if (userLocation) {
        currentPoints.unshift({
          latitude: userLocation[0],
          longitude: userLocation[1],
          id: 'user-location', // Dummy ID
          name: 'Vị trí hiện tại', // Dummy name
          type: 'MOVE', // Dummy type
          legId: '', // Dummy legId
        });
      }

      if (currentPoints.length < 2) {
        setRoutes([]);
        setSelectedRouteIndex(0);
        setDrivingRoute([]);
        setSegmentDistances([]);
        return;
      }

      // Chèn vị trí người dùng vào đầu danh sách tọa độ nếu có
      const coordsArray = allLocations.map(loc => `${loc.longitude},${loc.latitude}`);
      
      if (userLocation) {
        coordsArray.unshift(`${userLocation[1]},${userLocation[0]}`);
      }

      setIsRoutingLoading(true);
      try {
        const segmentPromises: Promise<OSRMRoute[] | null>[] = [];
        for (let i = 0; i < currentPoints.length - 1; i++) {
          const p1 = currentPoints[i];
          const p2 = currentPoints[i + 1];
          const coordsString = `${p1.longitude},${p1.latitude};${p2.longitude},${p2.latitude}`;
          
          segmentPromises.push(
            fetch(`https://router.project-osrm.org/route/v1/${travelMode}/${coordsString}?overview=full&geometries=geojson&alternatives=3`) // Yêu cầu tối đa 5 phương án thay thế cho mỗi phân đoạn
              .then(res => {
                if (!res.ok) throw new Error(`OSRM API error: ${res.status}`);
                return res.json();
              })
              .then(data => {
                if (data.code === 'Ok' && data.routes.length > 0) {
                  return data.routes; // Array of OSRMRoute for this segment
                }
                return null; // No routes for this segment
              })
              .catch(error => {
                console.error(`Lỗi lấy lộ trình cho phân đoạn ${i}-${i+1}:`, error);
                return null;
              })
          );
        }

        const allSegmentAlternativesRaw = await Promise.all(segmentPromises);
        const allSegmentAlternatives: OSRMRoute[][] = allSegmentAlternativesRaw.filter((seg): seg is OSRMRoute[] => seg !== null);

        if (allSegmentAlternatives.length === 0) {
          setRoutes([]);
          setSelectedRouteIndex(0);
          return;
        }
        
        // Now, construct overall alternative routes from segment alternatives
        // Heuristic: Take the first alternative of each segment to form the primary route.
        // Then, for subsequent overall alternatives, try different alternatives for the first segment,
        // keeping other segments at their primary alternative.
        
        const overallAlternativeRoutes: OSRMRoute[] = [];
        // Limit overall alternatives based on the number of alternatives for the first segment, up to 3
        const maxOverallAlternativesToGenerate = 3; // Số lượng lộ trình tổng thể muốn tạo

        // Heuristic để tạo các lộ trình tổng thể đa dạng hơn:
        // 1. Lộ trình chính (fastest/default cho tất cả các phân đoạn)
        const primarySegmentIndices = allSegmentAlternatives.map(() => 0);
        const primaryCombinedRoute = combineSegmentRoutes(allSegmentAlternatives, primarySegmentIndices);
        if (primaryCombinedRoute) {
          overallAlternativeRoutes.push(primaryCombinedRoute);
        }

        // 2. Các lộ trình thay thế: Thử kết hợp các phương án thay thế từ các phân đoạn
        // Ví dụ: Lấy phương án thứ N của mỗi phân đoạn (nếu có), hoặc phương án 0 nếu không có
        for (let altChoice = 1; altChoice < maxOverallAlternativesToGenerate; altChoice++) {
          const selectedSegmentIndices: number[] = allSegmentAlternatives.map(segmentAlts => 
            Math.min(altChoice, segmentAlts.length - 1) // Chọn phương án thứ 'altChoice', hoặc phương án cuối cùng nếu không đủ
          );
          const combinedRoute = combineSegmentRoutes(allSegmentAlternatives, selectedSegmentIndices);
          if (combinedRoute && !overallAlternativeRoutes.some(r => JSON.stringify(r.geometry.coordinates) === JSON.stringify(combinedRoute.geometry.coordinates))) {
            overallAlternativeRoutes.push(combinedRoute);
          }
        }
      setRoutes(overallAlternativeRoutes);
        setSelectedRouteIndex(0); // Always select the first overall alternative by default

      } catch (error) {
        console.error(`Lỗi lấy lộ trình ${travelMode}:`, error);
        setRoutes([]);
      } finally {
        setIsRoutingLoading(false);
      }
    };

    fetchRoutes();
  }, [allLocations, travelMode, userLocation]);

  // Cập nhật dữ liệu lộ trình hiển thị khi người dùng chọn phương án khác
  useEffect(() => {
    if (routes.length > 0 && routes[selectedRouteIndex]) {
      const route = routes[selectedRouteIndex];
      // OSRM trả về [lng, lat], cần đổi sang [lat, lng] cho Leaflet
      const mappedCoords: [number, number][] = route.geometry.coordinates.map((c: any) => [c[1], c[0]]);
      setDrivingRoute(mappedCoords);
      // Lưu quãng đường từng chặng của lộ trình được chọn
      setSegmentDistances(route.legs.map((leg: any) => leg.distance / 1000));
    }
  }, [selectedRouteIndex, routes]);

  // Tính toán thông tin hiển thị cho lộ trình đang chọn để đề xuất cho người dùng
  const selectedRouteInfo = useMemo(() => {
    if (!routes || routes.length === 0 || !routes[selectedRouteIndex]) return null;
    const r = routes[selectedRouteIndex];
    
    // Định dạng thời gian di chuyển
    const duration = r.duration;
    const hours = Math.floor(duration / 3600);
    const minutes = Math.round((duration % 3600) / 60);
    const durationStr = hours > 0 ? `${hours}h${minutes}p` : `${minutes}p`;

    // Xác định nhãn đề xuất: Index 0 thường là lộ trình tối ưu nhất của OSRM (thông dụng nhất)
    // Kiểm tra thêm nếu đây là lộ trình ngắn nhất trong các phương án
    const isShortest = routes.length > 1 && r.distance === Math.min(...routes.map(rt => rt.distance));
    
    let label = "Lộ trình";
    if (selectedRouteIndex === 0) label = "Đề xuất";
    else if (isShortest) label = "Ngắn nhất";
    else label = `Lựa chọn ${selectedRouteIndex + 1}`;
    
    return {
      distance: (r.distance / 1000).toFixed(1),
      duration: durationStr,
      label
    };
  }, [routes, selectedRouteIndex]);

  const handleNavigateToLocation = (location: any) => {
    setMapCenter([location.latitude, location.longitude]);
    setViewMode('map');
    setLocateTrigger(prev => prev + 1);
    
    notify({
      title: 'Bắt đầu chỉ đường',
      message: `Đang hiển thị lộ trình từ vị trí của bạn đến ${location.name}`,
      type: 'info'
    });
  };

  useEffect(() => {
    if (initialViewState) {
      setMapCenter(initialViewState.center);
    }
    // This useEffect is for initial load, but we now have tourId prop
    // The fetching logic is moved to the useEffect above that depends on tourId and isPublicView
    // So this useEffect can be simplified or removed if its only purpose was initial data load.
    // if (publicTours.length === 0 && !isPublicView) { // Only fetch public tours if not in public view and not already loaded
    //   fetchPublicTours();
    // }
  }, [initialViewState]); // Removed publicTours, currentTour, fetchPublicTours, fetchTour from dependencies


  const handleShare = () => {
    if (!currentTour) return;
    // Tạo link với query param ?viewTour=...
    const shareUrl = `${window.location.origin}?viewTour=${currentTour.id}`;
    if (navigator.share) {
      navigator.share({
        title: currentTour.title,
        url: shareUrl,
      }).catch(() => {});
    } else if (navigator.clipboard && window.isSecureContext) {
      navigator.clipboard.writeText(shareUrl).then(() => {
        notify({
          title: 'Thành công',
          message: 'Đã sao chép liên kết chia sẻ chuyến đi!',
          type: 'success'
        });
      });
    } else {
      // Giải pháp dự phòng cho môi trường không có HTTPS (truy cập qua IP)
      const textArea = document.createElement("textarea");
      textArea.value = shareUrl;
      document.body.appendChild(textArea);
      textArea.select();
      try {
        document.execCommand('copy');
        notify({
          title: 'Thành công',
          message: 'Đã sao chép liên kết chia sẻ chuyến đi!',
          type: 'success'
        });
      } catch (err) {}
      document.body.removeChild(textArea);
    }
  };

  // Thiết lập kết nối WebSocket Real-time
  useEffect(() => {
    if (!currentTour) return;

    const socket = Capacitor.isNativePlatform()
      ? io(BACKEND_URL)
      : io(); // Kết nối qua Proxy của Vite (cùng origin)

    socket.on('connect', () => {
      socket.emit('joinTour', currentTour.id);
    });

    socket.on('commentAdded', (data: any) => {
      // Cập nhật UI ngay lập tức khi bất kỳ ai bình luận
      handleCommentIncrement(data.locationId);
    });

    socket.on('tourMessageReceived', (data: any) => {
      if (data.tourId === currentTour.id && activeTab !== 'chat') {
        setUnreadChatCount(prev => prev + 1);
      }
    });

    return () => { socket.disconnect(); };
  }, [currentTour?.id, activeTab]);

  // This useEffect is for initial demo loading, might not be needed if tourId is always passed
  // useEffect(() => {
  //   if (publicTours.length > 0 && !currentTour && !isPublicView) {
  //     fetchTour(publicTours[0].id);
  //   }
  // }, [publicTours, currentTour, fetchTour, isPublicView]);

  

  // Hàm xử lý các hành động từ Context Menu của bản đồ
  const handleMapAction = async (action: string, latlng: L.LatLng) => {
    // Bước 1: Lấy tọa độ (lat, lng) tại vị trí click (đã nhận qua tham số latlng)
    console.log(`[FRONTEND] Triggered ${action} at:`, { lat: latlng.lat, lng: latlng.lng });

    // Đảm bảo có tour và ít nhất một chặng để ghim
    const currentLegs = useTourStore.getState().legs;
    if (!currentTour || currentLegs.length === 0) {
      alert("Tour chưa có chặng nào. Vui lòng tạo chặng (Leg) trước khi thực hiện.");
      return;
    }

    let targetLegId = currentLegs[0].id; // Mặc định là chặng đầu
    let defaultName = "Địa điểm mới";
    let locationType: LocationType = 'VISIT'; // Mặc định là tham quan

    if (action === 'START') {
      defaultName = "Điểm bắt đầu";
      locationType = 'MOVE'; // Điểm bắt đầu thường liên quan đến di chuyển
    }
    if (action === 'END') {
      targetLegId = currentLegs[currentLegs.length - 1].id;
      defaultName = "Điểm kết thúc";
      locationType = 'MOVE'; // Điểm kết thúc cũng liên quan đến di chuyển
    }
    if (action.startsWith('ADD_TO_LEG_')) {
      targetLegId = action.replace('ADD_TO_LEG_', '');
      // Loại địa điểm mặc định vẫn là VISIT nếu thêm vào chặng cụ thể
    }

    // Bước 2: Gửi request đến dịch vụ bản đồ để phân tích tọa độ thành tên địa điểm cụ thể
    let detectedName = "";
    try {
      const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latlng.lat}&lon=${latlng.lng}`);
      const data = await res.json();
      const addr = data.address;
      // Ưu tiên lấy tên Location/Tòa nhà/Tên đường, bỏ qua Tỉnh/Thành phố nếu có thông tin chi tiết hơn
      detectedName = addr.amenity || addr.building || addr.historic || addr.tourist || 
                    addr.shop || addr.office || addr.leisure || addr.attraction ||
                    addr.road || addr.neighbourhood || addr.suburb || 
                    data.display_name?.split(',')[0] || "";
      console.log(`[FRONTEND] Geocoding Result: "${detectedName}"`);
    } catch (e) {
      console.warn("[FRONTEND] Reverse Geocoding failed:", e);
    }

    try {
      if (action === 'START') {
        // Bước 3: Mutate State & UI - Đặt startLocationName = resolvedPlaceName
        const resolvedPlaceName = detectedName || "Điểm xuất phát";
        console.log(`[FRONTEND] Updating START point to: ${resolvedPlaceName} at`, latlng);
        await updateTourStartPoint(currentTour.id, {
          name: resolvedPlaceName,
          latitude: latlng.lat,
          longitude: latlng.lng,
        });
        console.log("[FRONTEND] START point updated successfully.");
        // Giao diện Top Banner và Ghim màu xanh sẽ tự động cập nhật 
        // khi store fetch lại dữ liệu tour và re-render.
      } else if (action === 'END') {
        // Bước 2: Thiết lập Điểm kết thúc
        const finalName = detectedName || "Điểm kết thúc";
        await updateTourEndPoint(currentTour.id, {
          name: finalName,
          latitude: latlng.lat,
          longitude: latlng.lng,
        });
      } else {
        // Đối với việc thêm địa điểm vào chặng, vẫn sử dụng Prompt để người dùng đặt tên theo ý muốn
        const name = window.prompt("Xác nhận tên địa điểm tham quan:", detectedName || defaultName);
        if (!name) return;

        await addLocation(currentTour.id, {
          name,
          address: '',
          latitude: latlng.lat,
          longitude: latlng.lng,
          legId: targetLegId,
          type: locationType as any,
        });
      }
    } catch (error: any) {
      // Xử lý lỗi từ API (Ví dụ: Tour chưa có chặng nào)
      if (error.message.includes('Không tìm thấy chặng')) {
        alert("Lỗi: Bạn cần tạo ít nhất một Chặng (Leg) trước khi xác định điểm Bắt đầu/Kết thúc.");
      } else {
        alert("Đã xảy ra lỗi: " + error.message);
      }
    }
  };

  // Đồng bộ tiêu đề ghi chú khi đổi tên chuyến đi
  const syncTourNoteTitle = (tourId: string, newTitle: string) => {
    const savedNotes = localStorage.getItem('my_journey_notes');
    if (!savedNotes) return;
    try {
      let notes = JSON.parse(savedNotes);
      if (Array.isArray(notes)) {
        let updated = false;
        const oldTitle = currentTour?.title || '';
        notes = notes.map((n: any) => {
          if (n.tourId === tourId || n.title === `Ghi chú của hành trình: ${oldTitle}`) {
            n.tourId = tourId;
            n.title = `Ghi chú của hành trình: ${newTitle}`;
            if (oldTitle && n.content) {
              n.content = n.content.split(`<strong>${oldTitle}</strong>`).join(`<strong>${newTitle}</strong>`);
            }
            updated = true;
          }
          return n;
        });
        if (updated) {
          localStorage.setItem('my_journey_notes', JSON.stringify(notes));
        }
      }
    } catch (e) {
      console.error("Error syncing tour note title:", e);
    }
  };

  // Hàm xử lý cập nhật số lượng người tham gia
  const handleUpdateTourInfo = async () => {
    if (!currentTour) return;
    try {
      await updateTourDetails(currentTour.id, {
        title: titleInput,
        description: descriptionInput,
        adultCount: adultCountInput,
        childCount: childCountInput,
        childDiscount: childDiscountInput,
        tags: tagsInput
      });
      notify({
        title: 'Thành công',
        message: 'Đã cập nhật thông tin chuyến đi.',
        type: 'success'
      });
      if (titleInput !== currentTour.title) {
        syncTourNoteTitle(currentTour.id, titleInput);
      }
      fetchTour(currentTour.id); // Re-fetch tour để cập nhật lại các tính toán liên quan
    } catch (error: any) {
      notify({ title: 'Lỗi', message: error.message || 'Không thể cập nhật thông tin.', type: 'error' });
    }
  };

  const reverseGeocode = async (lat: number, lng: number): Promise<string> => {
    try {
      const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`, {
        headers: { 'Accept': 'application/json' }
      });
      if (res.ok) {
        const data = await res.json();
        return data.display_name || '';
      }
    } catch (e) {
      console.warn('Reverse geocode failed:', e);
    }
    return '';
  };

  const handleQuickNote = async (data: { legId: string; location: any; leg: any }) => {
    if (isPublicView || !currentTour) return;
    setQuickNoteLocName(data.location.name);
    setQuickNoteLegId(data.legId);
    setQuickNoteLocation(data.location);
    setQuickNoteInput('');
  };

  const submitQuickNote = async () => {
    if (!quickNoteLocName || !quickNoteInput.trim() || !currentTour || !quickNoteLegId || !quickNoteLocation) return;

    const content = quickNoteInput;

    let resolvedAddress = quickNoteLocation.address || '';
    const hasCoords = quickNoteLocation.latitude && quickNoteLocation.longitude;
    if ((!resolvedAddress || resolvedAddress.trim() === '') && hasCoords) {
      const geo = await reverseGeocode(+quickNoteLocation.latitude, +quickNoteLocation.longitude);
      resolvedAddress = geo || `${quickNoteLocation.latitude}, ${quickNoteLocation.longitude}`;
    }

    const formattedTime = quickNoteLocation.plannedStart
      ? new Date(quickNoteLocation.plannedStart).toLocaleString('vi-VN')
      : "Thời gian tùy hứng";

    const userInputText = content;
    const noteSnippet = `<h4>📅 ${formattedTime} | 📍 ${resolvedAddress}</h4><ul><li><strong>Nhật ký:</strong> ${userInputText}</li></ul>`;

    try {
      const token = localStorage.getItem('token');
      const res = await fetch(`/api/v1/tours/${currentTour.id}/notes/insert`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        },
        body: JSON.stringify({
          legId: quickNoteLegId,
          noteSnippet
        })
      });
      if (res.ok) {
        notify({ title: 'Thành công', message: 'Đã lưu vào ghi chú chung!', type: 'success' });
      } else {
        const err = await res.json().catch(() => ({}));
        notify({ title: 'Lỗi', message: err.message || 'Lỗi khi lưu ghi chú nhanh.', type: 'error' });
      }
    } catch (error) {
      console.error('Lỗi khi lưu ghi chú nhanh:', error);
      notify({ title: 'Lỗi', message: 'Lỗi mạng khi lưu ghi chú nhanh.', type: 'error' });
    } finally {
      setQuickNoteLocName(null);
      setQuickNoteLegId(null);
      setQuickNoteLocation(null);
      setQuickNoteInput('');
    }
  };

  // Hàm xử lý xóa Tour vĩnh viễn
  const handleDeleteTour = async () => {
    if (!currentTour) return;
    const isConfirmed = await confirm({
      title: 'Xóa Tour vĩnh viễn?',
      message: 'Toàn bộ dữ liệu về lộ trình, chi phí và hình ảnh của chuyến đi này sẽ bị xóa bỏ hoàn toàn. Bạn có chắc chắn muốn thực hiện?'
    });

    if (isConfirmed) {
      try {
        await deleteTour(currentTour.id);
        notify({ title: 'Thành công', message: 'Hành trình đã được xóa.', type: 'success' });
        onBack(); // Quay về trang khám phá sau khi xóa thành công
      } catch (error: any) {
        notify({ title: 'Lỗi', message: error.message || 'Không thể xóa hành trình.', type: 'error' });
      }
    }
  };

  // Ngăn chặn sự kiện click trên menu lộ trình làm ảnh hưởng bản đồ
  const routeMenuRef = React.useRef<HTMLDivElement>(null);
  useEffect(() => {
    if (routeMenu && routeMenuRef.current) {
      L.DomEvent.disableClickPropagation(routeMenuRef.current);
    }
  }, [routeMenu]);

  // Đóng menu lộ trình khi chuyển tab hoặc thay đổi chế độ xem
  useEffect(() => {
    setRouteMenu(null);
  }, [activeTab, viewMode]);

  // Xác định Điểm xuất phát và Điểm kết thúc hiển thị dưới widget tài chính
  const startPoint = useMemo(() => 
    legs.flatMap(l => l.locations).find(loc => loc.plannedStart && new Date(loc.plannedStart).getTime() === 0),
    [legs]
  );
  const endPoint = useMemo(() => 
    legs.flatMap(l => l.locations).find(loc => loc.plannedEnd && new Date(loc.plannedEnd).getTime() === 0),
    [legs]
  );

  // Định nghĩa các tab dựa trên quyền hạn (RBAC) từ store
  const tabs = [
    { id: 'plan', label: 'Lộ trình', icon: MapIcon, visible: true },
    { id: 'expense', label: 'Chi phí', icon: Wallet, visible: ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '') },
    { id: 'photo', label: 'Ảnh', icon: ImageIcon, visible: true },
    { id: 'chat', label: 'Trò chuyện', icon: MessageSquare, visible: !!userRole, hasBadge: unreadChatCount > 0, badgeCount: unreadChatCount },
    { id: 'members', label: 'Thành viên', icon: Users, visible: canManage },
    { id: 'settings', label: 'Cài đặt', icon: Settings, visible: userRole === 'OWNER' },
  ].filter(t => t.visible);

  const hasFinanceAccess = ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '');

  // Logic tính toán ngày hiển thị: Ưu tiên ngày của Tour, sau đó đến ngày của các Chặng
  const tourDateDisplay = useMemo(() => {
    if (currentTour?.startDate && currentTour?.endDate) {
      return `${new Date(currentTour.startDate).toLocaleDateString('vi-VN')} - ${new Date(currentTour.endDate).toLocaleDateString('vi-VN')}`;
    }
    const firstLeg = legs[0];
    const lastLeg = legs[legs.length - 1];
    const start = firstLeg?.startDate;
    const end = lastLeg?.endDate || lastLeg?.startDate;
    if (start && end) {
      return `${new Date(start).toLocaleDateString('vi-VN')} - ${new Date(end).toLocaleDateString('vi-VN')}`;
    } else if (start) {
      return `Từ ${new Date(start).toLocaleDateString('vi-VN')}`;
    }
    return "Chưa xác định ngày";
  }, [currentTour, legs]);

  const travelQuotes = [
    "Đừng nghe họ nói, hãy tự mình đi xem.",
    "Thế giới là một cuốn sách, và ai không đi du lịch thì chỉ mới đọc được một trang.",
    "Hành trình ngàn dặm bắt đầu từ một bước chân.",
    "Đi là để trở về, nhưng với một tâm hồn mới."
  ];

  const randomQuote = useMemo(() => travelQuotes[Math.floor(Math.random() * travelQuotes.length)], []);

  const tourInfo = {
    title: currentTour?.title || "Hành trình khám phá TP.HCM",
    date: tourDateDisplay,
    membersCount: currentTour?.participants?.filter((p: any) => p.user || p.displayName)?.length || 0,
    budget: currentTour?.totalCost ? `${Number(currentTour.totalCost).toLocaleString()} VND` : "0 VND",
    coverImage: getMostLikedPhoto(currentTour?.photos || [])?.imageUrl || "https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?q=80&w=2070&auto=format&fit=crop"
  };

  return (
    <div className="min-h-dvh bg-[var(--background)] pb-20 overflow-x-hidden">
      {/* Top Navigation Bar */}
      <div className="sticky top-0 z-30 bg-[var(--surface)]/80 backdrop-blur-md border-b border-[var(--border)] px-4 py-3 flex items-center justify-between">
        <button onClick={activeTab === 'chat' ? () => setActiveTab('plan') : onBack} className="p-2 hover:bg-[var(--background)] rounded-full transition-colors">
          <ChevronLeft className="w-5 h-5 sm:w-6 sm:h-6 text-[var(--text-secondary)]" />
        </button>
        <h1 className="text-base sm:text-lg font-bold text-[var(--text-primary)] truncate px-4 flex-1 text-center">
          {tourInfo.title}
        </h1>
        <div className="flex items-center gap-1">
          {/* Nút Ghi chú: Chỉ hiển thị cho người dùng đã đăng nhập và không phải view công khai */}
          {!isPublicView && onOpenNotes && (
            <button 
              onClick={onOpenNotes}
              className="p-2 hover:bg-amber-50 text-amber-600 rounded-full transition-colors"
              title="Ghi chú của tôi"
            >
              <FileText className="w-5 h-5" />
            </button>
          )}
          {/* Nút chia sẻ: Chỉ dành cho OWNER, MANAGER, MEMBER */}
          {canShare && (
            <button 
              onClick={handleShare}
              className="p-2 hover:bg-blue-50 text-blue-600 rounded-full transition-colors"
              title="Chia sẻ tour"
            >
              <Share2 className="w-5 h-5" />
            </button>
          )}
        </div>
      </div>
{!(activeTab === 'plan' && viewMode === 'map') && (
        <>
          {/* Tour Header Info */}
      <div className="relative min-h-[300px] sm:min-h-[400px] md:min-h-[480px] w-full bg-blue-900 flex flex-col justify-end">
        <img 
          src={tourInfo.coverImage} 
          className="absolute inset-0 w-full h-full object-cover opacity-60" 
          alt="Tour Cover" 
        />
        <div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent" />
        
        <div className="relative z-10 p-4 sm:p-6 pt-16 sm:pt-28 pb-8 sm:pb-20">
          <div className="max-w-2xl mx-auto space-y-3 sm:space-y-4">
            <h2 className="text-xl sm:text-2xl md:text-3xl font-black tracking-tight drop-shadow-md">{tourInfo.title}</h2>
            
            {/* Nhãn hiển thị ngay dưới Tiêu đề */}
            {currentTour?.tags && currentTour.tags.length > 0 && (
              <div className="flex flex-wrap gap-2 pt-1">
                {currentTour.tags.map((tag: string) => (
                  <span key={tag} className="px-2.5 py-1 bg-white/20 backdrop-blur-md border border-white/30 rounded-lg text-[10px] font-black uppercase tracking-wider">
                    {tag}
                  </span>
                ))}
              </div>
            )}
            
            {/* Mô tả hiển thị dưới Nhãn */}
            {currentTour?.description && (
              <p className="text-sm md:text-base text-white/90 max-w-xl line-clamp-3 md:line-clamp-none bg-black/20 backdrop-blur-sm p-4 rounded-2xl border border-white/10 italic leading-relaxed">
                <Quote className="w-4 h-4 inline-block mr-2 opacity-50" />
                {currentTour.description}
              </p>
            )}

                        {/* Dòng tóm tắt Lộ trình */}
            <div className="mt-3 text-[11px] sm:text-sm font-bold text-white bg-black/40 backdrop-blur-md px-4 py-2 rounded-xl border border-white/10 inline-flex items-center max-w-full">
              <span className="text-white/60 mr-1">Lộ trình:</span>
              <span className="text-blue-300">Điểm xuất phát:</span>
              <span className="ml-1 text-white banner-location-text" title={startPoint?.name}>{startPoint?.name || '...'}</span>
              <span className="mx-2 text-white/30">-</span>
              <span className="text-green-300">Điểm kết thúc:</span>
              <span className="ml-1 text-white banner-location-text" title={endPoint?.name}>{endPoint?.name || '...'}</span>
            </div>
            
            <div className="flex flex-wrap gap-4 text-sm font-medium opacity-90">
              <div className="flex items-center bg-black/20 backdrop-blur-sm px-3 py-1 rounded-full border border-white/10">
                <Calendar className="w-4 h-4 mr-1.5" />
                {tourInfo.date}
              </div>
              <div className="flex items-center bg-black/20 backdrop-blur-sm px-3 py-1 rounded-full border border-white/10">
                <Users className="w-4 h-4 mr-1.5" />
                {tourInfo.membersCount} thành viên
              </div>
            </div>



            {/* Member Avatars Stack */}
            <div className="flex items-center gap-2 mt-4">
              <div className="flex flex-wrap gap-2"> {/* Always show participants */}
                {currentTour?.participants?.filter((p: any) => p.user || p.displayName)?.slice(0, 5).map((p: any) => {
                  const memberName = p.user?.name || p.displayName || 'Thành viên';
                  return (
                    <button
                      key={p.id}
                      onClick={() => {
                        setSelectedMember(p);
                        setIsMemberDetailOpen(true);
                      }}
                      className="w-10 h-10 rounded-full border-2 border-white bg-blue-100 flex items-center justify-center text-blue-600 font-bold overflow-hidden shadow-lg hover:scale-110 transition-transform"
                      title={memberName}
                    >
                      {p.user ? (
                        <img src={`https://i.pravatar.cc/100?u=${p.userId}`} alt="Avatar" />
                      ) : (
                        <span>{memberName.charAt(0)}</span>
                      )}
                    </button>
                  );
                })}
                {isOwner && !isPublicView && joinRequests.slice(0, 3).map((req: any) => ( // Hide join requests in public view
                  <div key={req.id} className="relative group">
                    <div className="w-10 h-10 rounded-full border-2 border-amber-400 bg-amber-50 flex items-center justify-center text-amber-700 font-bold overflow-hidden shadow-lg">
                      {req.user?.name?.charAt(0) || '?'}
                    </div>
                      <div className="absolute -top-1 -right-1 flex">
                        <button
                          type="button"
                          disabled={joinRequestActionId === req.id}
                          onClick={async (e) => {
                            e.stopPropagation();
                            if (!currentTour) return;
                            const isConfirmed = await confirm({
                              title: 'Chấp nhận yêu cầu',
                              message: `Chấp nhận ${req.user?.name || req.userId} vào tour?`
                            });
                            if (isConfirmed) {
                              setJoinRequestActionId(req.id);
                              try {
                                await acceptJoinRequest(currentTour.id, req.id);
                                setJoinRequests((prev) => prev.filter((r) => r.id !== req.id));
                              } catch (e: any) {
                                notify({ title: 'Thông báo', message: e.message || 'Không thể chấp nhận yêu cầu', type: 'error' });
                              } finally {
                                setJoinRequestActionId(null);
                              }
                            }
                          }}
                          className="w-4 h-4 bg-green-500 hover:bg-green-600 rounded-full flex items-center justify-center text-white text-[10px] leading-none disabled:opacity-50"
                          aria-label="Accept"
                        >
                          +
                        </button>
                        <button
                          type="button"
                          disabled={joinRequestActionId === req.id}
                          onClick={async (e) => {
                            e.stopPropagation();
                            if (!currentTour) return;
                            const isConfirmed = await confirm({
                              title: 'Từ chối yêu cầu',
                              message: `Từ chối ${req.user?.name || req.userId} tham gia tour?`
                            });
                            if (isConfirmed) {
                              setJoinRequestActionId(req.id);
                              try {
                                await rejectJoinRequest(currentTour.id, req.id);
                                setJoinRequests((prev) => prev.filter((r) => r.id !== req.id));
                              } catch (e: any) {
                                notify({ title: 'Thông báo', message: e.message || 'Không thể từ chối yêu cầu', type: 'error' });
                              } finally {
                                setJoinRequestActionId(null);
                              }
                            }
                          }}
                          className="w-4 h-4 bg-red-500 hover:bg-red-600 rounded-full flex items-center justify-center text-white text-[10px] leading-none disabled:opacity-50 -ml-1"
                          aria-label="Reject"
                        >
                          x
                        </button>
                      </div>
                  </div>
                ))}
                {tourInfo.membersCount > 5 && (
                  <div className="w-10 h-10 rounded-full border-2 border-white bg-gray-800 flex items-center justify-center text-[10px] font-bold text-white shadow-lg">
                    +{tourInfo.membersCount - 5}
                  </div>
                )}
              </div>
              {!isPublicView && canInvite && (
                <button
                  onClick={() => {
                    if (!currentTour) return;
                    setIsAddMemberOpen(true);
                  }}
                  className="flex items-center gap-1.5 px-3 py-2 rounded-full border border-white/20 bg-white/10 hover:bg-white/20 text-white font-bold text-xs transition-all ml-2 shadow-md hover:scale-105 active:scale-95"
                >
                  <Plus className="w-3.5 h-3.5" />
                  Thêm thành viên
                </button>
              )}
            </div>

            {duplicateMatches.map((match) => (
              <div key={match.manual.id} className="mt-3 p-3 bg-amber-500/20 backdrop-blur-md border border-amber-500/30 rounded-2xl flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 text-xs text-amber-100 animate-in fade-in slide-in-from-top-1 shadow-lg">
                <div className="flex items-center gap-2">
                  <span className="w-2.5 h-2.5 rounded-full bg-amber-400 animate-pulse shrink-0"></span>
                  <span>
                    Phát hiện thành viên ngoài hệ thống <strong>"{match.manual.displayName}"</strong> trùng tên với tài khoản <strong>"{match.system.user.name}"</strong> vừa tham gia.
                  </span>
                </div>
                <button
                  disabled={mergingId === match.manual.id}
                  onClick={async () => {
                    const isConfirmed = await confirm({
                      title: 'Hợp nhất thành viên',
                      message: `Gán tài khoản "${match.system.user.name}" thay thế cho thành viên thủ công "${match.manual.displayName}"? Thao tác này không thể hoàn tác.`
                    });
                    if (!isConfirmed) return;
                    
                    setMergingId(match.manual.id);
                    try {
                      const res = await fetch(`/api/v1/tours/${currentTour.id}/members/merge`, {
                        method: 'POST',
                        headers: {
                          'Content-Type': 'application/json',
                          'Authorization': `Bearer ${localStorage.getItem('token')}`
                        },
                        body: JSON.stringify({
                          manualParticipantId: match.manual.id,
                          systemUserId: match.system.userId
                        })
                      });
                      const data = await res.json();
                      if (!res.ok) {
                        throw new Error(data.message || 'Hợp nhất thất bại.');
                      }
                      notify({ title: 'Thành công', message: 'Đã gán thành viên ngoài hệ thống thành công!', type: 'success' });
                      fetchTour(currentTour.id);
                    } catch (e: any) {
                      notify({ title: 'Lỗi', message: e.message || 'Không thể hợp nhất', type: 'error' });
                    } finally {
                      setMergingId(null);
                    }
                  }}
                  className={`px-3.5 py-2 bg-amber-500 hover:bg-amber-600 active:scale-95 text-white font-black rounded-xl transition-all shrink-0 shadow-md text-[11px] ${mergingId === match.manual.id ? 'opacity-50 cursor-not-allowed' : ''}`}
                >
                  {mergingId === match.manual.id ? 'Đang xử lý...' : 'Gán & Hợp nhất'}
                </button>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Financial Quick-View Widget or Quote */}
      <div className="max-w-2xl mx-auto -mt-10 px-4 relative z-10">
        <div // Always show quote if public view, otherwise show financial widget if has access
          onClick={() => hasFinanceAccess && setActiveTab('expense')}
          className={`rounded-3xl p-6 shadow-2xl transition-all duration-500 ${hasFinanceAccess ? 'bg-indigo-600 text-white shadow-indigo-200 cursor-pointer hover:scale-[1.02] active:scale-95' : 'bg-white text-gray-600 border border-gray-100'}`}
        >
          <div className="flex justify-between items-center">
            {hasFinanceAccess ? (
              <>
                <div>
                  <p className="text-indigo-100 text-[10px] font-black uppercase tracking-widest mb-1">Tổng chi tiêu hiện tại (Nhấn để xem chi tiết)</p>
                  <h3 className="text-3xl font-black">{tourInfo.budget}</h3>
                </div>
                <div className="p-4 bg-white/10 rounded-2xl backdrop-blur-md"><Wallet className="w-8 h-8" /></div>
              </>
            ) : ( // If no finance access or is public view, show quote
              <div className="flex items-start gap-4 py-2">
                <Quote className="w-8 h-8 text-blue-500 opacity-30 flex-shrink-0" />
                <p className="italic text-lg font-medium leading-relaxed">"{randomQuote}"</p>
              </div>
            )}
          </div>
        </div>
      </div>

      {/* Khối hiển thị Điểm đầu & Điểm cuối (Dưới Financial Quick-View) */}
      <div className="max-w-2xl mx-auto mt-4 px-4 grid grid-cols-1 sm:grid-cols-2 gap-3 animate-in fade-in slide-in-from-top-2 duration-500">
        {startPoint && (
          <div className="bg-white p-4 rounded-2xl border border-blue-50 flex items-center gap-3 shadow-sm hover:shadow-md transition-shadow">
            <div className="w-10 h-10 rounded-xl bg-blue-100 flex items-center justify-center text-blue-600 shadow-inner">
              <MapPin className="w-5 h-5" />
            </div>
            <div className="overflow-hidden">
              <p className="text-[10px] font-black text-blue-400 uppercase tracking-widest mb-0.5">Điểm xuất phát</p>
              <p className="text-sm font-bold text-gray-800 truncate">{startPoint.name}</p>
            </div>
          </div>
        )}
        {endPoint && (
          <div className="bg-white p-4 rounded-2xl border border-green-50 flex items-center gap-3 shadow-sm hover:shadow-md transition-shadow">
            <div className="w-10 h-10 rounded-xl bg-green-100 flex items-center justify-center text-green-600 shadow-inner">
              <Flag className="w-5 h-5" />
            </div>
            <div className="overflow-hidden">
              <p className="text-[10px] font-black text-green-400 uppercase tracking-widest mb-0.5">Điểm kết thúc</p>
              <p className="text-sm font-bold text-gray-800 truncate">{endPoint.name}</p>
            </div>
          </div>
        )}
      </div>
        </>
      )}

      {/* Main Content Area - Điều chỉnh max-width khi ở chế độ bản đồ */}
      <div className={`${activeTab === 'plan' && viewMode === 'map' ? 'w-full !px-0 !pb-0' : 'max-w-2xl mx-auto px-4 pb-24'}`}>
        {/* Tab Switcher */}
        {!(activeTab === 'plan' && viewMode === 'map') && activeTab !== 'chat' && (
          <div className="bg-white rounded-2xl shadow-lg border border-gray-100 p-1 flex mb-6 sticky top-[60px] z-40">
          {tabs.map((tab) => (
            <button
              key={tab.id}
              onClick={() => {
                setActiveTab(tab.id as any);
                if (tab.id === 'chat') setUnreadChatCount(0);
              }}
              className={`flex-1 flex items-center justify-center py-2 rounded-xl text-xs font-semibold transition-all relative ${tab.id === 'settings' && isPublicView ? 'hidden' : ''} ${ // Hide settings tab in public view
                activeTab === tab.id 
                  ? 'bg-blue-50 text-blue-600 shadow-sm' 
                  : 'text-gray-400 hover:text-gray-500 hover:bg-gray-50'
              }`}
            >
              <tab.icon className={`w-4 h-4 mr-2 ${activeTab === tab.id ? 'scale-110' : ''}`} />
              {tab.label}
              {tab.hasBadge && tab.badgeCount !== undefined && tab.badgeCount > 0 && (
                <span className="absolute -top-1 -right-1.5 bg-red-500 text-white text-[9px] font-black rounded-full px-1.5 py-0.5 animate-bounce shadow-md">
                  {tab.badgeCount}
                </span>
              )}
            </button>
          ))}
        </div>
        )}

        {/* Tab Panels */}
        <div className="transition-opacity duration-300">
          {activeTab === 'plan' && (
            <div className="animate-in fade-in slide-in-from-bottom-2">
              {/* View Mode Toggle */}
              {viewMode !== 'map' && (
                <div className="flex justify-center items-center mb-3">
                  <div className="bg-gray-100 dark:bg-slate-800 p-1 rounded-2xl flex gap-1">
                    <button 
                      onClick={() => setViewMode('timeline')}
                      className={`flex items-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all ${viewMode === 'timeline' ? 'bg-white dark:bg-slate-900 shadow-sm text-blue-600 dark:text-blue-400' : 'text-gray-500'}`}
                    >
                      <List className="w-3.5 h-3.5" /> Danh sách
                    </button>
                    <button 
                      onClick={() => setViewMode('map')}
                      className={`flex items-center gap-2 px-4 py-2 rounded-xl text-xs font-bold transition-all ${viewMode === 'map' ? 'bg-white dark:bg-slate-900 shadow-sm text-blue-600 dark:text-blue-400' : 'text-gray-500'}`}
                    >
                      <MapIconLucide className="w-3.5 h-3.5" /> Bản đồ
                    </button>
                  </div>
                </div>
              )}

              {/* Export Buttons */}
              {viewMode !== 'map' && (
                <div className="flex justify-center gap-2 mb-6">
                  <button 
                    onClick={handleExportCSV}
                    className="flex items-center gap-1 px-3 py-1.5 bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg text-[11px] font-bold shadow-md transition-all active:scale-95 whitespace-nowrap"
                  >
                    📊 Google Sheets
                  </button>
                  <button 
                    onClick={handleExportPDF}
                    className="flex items-center gap-1 px-3 py-1.5 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg text-[11px] font-bold shadow-md transition-all active:scale-95 whitespace-nowrap"
                  >
                    📥 {t('exportPDF') || 'Xuất PDF'}
                  </button>
                </div>
              )}

              {viewMode === 'timeline' ? (
                <ItineraryTimeline onAddLocation={(legId, isStart, isEnd) => {
                  setTargetLegId(legId);
                  setEditingLocation(null);
                  setIsStartPointAction(!!isStart);
                  setIsEndPointAction(!!isEnd);
                  setIsAddLocationOpen(true);
                }} onEditLocation={(loc) => {
                  setEditingLocation(loc);
                  setTargetLegId(loc.legId);
                  setMapCenter([loc.latitude, loc.longitude]);
                  const isStart = loc.plannedStart && new Date(loc.plannedStart).getTime() === 0;
                  const isEnd = loc.plannedEnd && new Date(loc.plannedEnd).getTime() === 0;
                  setIsStartPointAction(!!isStart);
                  setIsEndPointAction(!!isEnd);
                  setIsAddLocationOpen(true);
                }} 
                onQuickNote={(data) => handleQuickNote(data)}
                onSuccess={() => fetchTour(tourId)}
                isPublicView={isPublicView} 
                onNavigate={handleNavigateToLocation}
                onOpenNavigationPage={onOpenNavigationPage}
              />
              ) : (
                <div className="h-auto min-h-[calc(100vh-100px)] sm:min-h-[calc(100vh-140px)] md:h-[calc(100vh-53px)] w-full md:rounded-3xl overflow-hidden md:shadow-xl md:border-4 md:border-white relative animate-in fade-in duration-500">
                  {/* Search Bar Overlay - Thanh tìm kiếm địa điểm trên bản đồ lộ trình */}
                  {!isPublicView && (
                    <div className="absolute top-2 sm:top-3 right-2 sm:right-3 z-[1001] w-40 sm:w-48 md:w-64">
                      <div className="relative group">
                        <input 
                          type="text"
                          placeholder="Tìm địa điểm..."
                          className="w-full pl-8 pr-8 py-2 bg-white/95 backdrop-blur-md border border-white/20 rounded-xl shadow-xl outline-none focus:ring-2 focus:ring-blue-500 transition-all text-xs font-bold"
                          value={searchQuery}
                          onChange={e => handleSearchLocation(e.target.value)}
                        />
                        <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-blue-500" />
                        {isSearching ? (
                          <Loader2 className="absolute right-2.5 top-1/2 -translate-y-1/2 w-3.5 h-3.5 animate-spin text-blue-500" />
                        ) : searchQuery && (
                          <button onClick={() => { setSearchQuery(''); setSearchResults([]); }} className="absolute right-3 top-1/2 -translate-y-1/2 p-1 text-gray-400 hover:text-red-500 transition-colors">
                            <X className="w-4 h-4" />
                          </button>
                        )}

                        {/* Kết quả tìm kiếm */}
                        {searchResults.length > 0 && (
                          <div className="absolute left-0 right-0 mt-2 bg-white/95 backdrop-blur-md border border-gray-100 rounded-2xl shadow-2xl overflow-hidden max-h-48 overflow-y-auto animate-in slide-in-from-top-2 duration-200">
                            {searchResults.map((result, idx) => (
                              <button
                                key={idx}
                                onClick={() => {
                                  setMapCenter([parseFloat(result.lat), parseFloat(result.lon)]);
                                  setSearchResults([]);
                                  setSearchQuery('');
                                  notify({
                                    title: 'Tìm thấy địa điểm',
                                    message: `Đã di chuyển bản đồ tới: ${result.namedetails?.name || result.display_name.split(',')[0]}`,
                                    type: 'success'
                                  });
                                }}
                                className="w-full text-left px-4 py-3 hover:bg-blue-50 border-b border-gray-50 last:border-0 transition-colors"
                              >
                                <div className="font-bold text-xs text-gray-900 truncate">{result.namedetails?.name || result.display_name.split(',')[0]}</div>
                                <div className="text-[10px] text-gray-500 truncate leading-tight">{result.display_name}</div>
                              </button>
                            ))}
                          </div>
                        )}
                      </div>
                    </div>
                  )}

                  {/* Overlay thông tin lộ trình đề xuất (Lộ trình thông dụng nhất) */}
                  {selectedRouteInfo && drivingRoute.length > 0 && (
                    <div className="absolute top-3 left-1/2 -translate-x-1/2 z-[1001] bg-white/80 backdrop-blur-md px-4 py-2 rounded-2xl shadow-xl border border-white flex items-center gap-3 animate-in fade-in slide-in-from-top-2 duration-500">
                      <div className="flex items-center gap-2">
                        <Navigation className="w-3.5 h-3.5 text-blue-600 rotate-45" />
                        <span className="text-[10px] font-black text-gray-400 uppercase tracking-tighter">{selectedRouteInfo.label}</span>
                      </div>
                      <div className="flex items-center gap-2 text-xs font-bold text-blue-700 whitespace-nowrap">
                        <span>{selectedRouteInfo.distance} km</span>
                        <span className="text-gray-300">•</span>
                        <span>{selectedRouteInfo.duration}</span>
                      </div>
                    </div>
                  )}

                  <MapContainer 
                    center={initialViewState?.center || mapCenter} 
                    zoom={mapZoom} 
                    className="h-full w-full"
                    preferCanvas={true}
                    attributionControl={false}
                  >
                    <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="" />
                    {canEdit && !isPublicView && (
                      <>
                        <MapHoverTip canEdit={canEdit} />
                        <MapContextMenu onAction={handleMapAction} onOpen={() => setRouteMenu(null)} />
                      </>
                    )}
                    
                    {/* Tự động đóng khung Start và End khi dữ liệu thay đổi */}
                    <MapTourBounds locations={allLocations} />

                    {/* Xử lý xoay bản đồ theo Heading */}
                    <MapRotationHandler rotation={mapRotation} />

                    {/* Xử lý di chuyển tâm bản đồ về phía người dùng */}
                    <RecenterUser position={userLocation} trigger={locateTrigger} />

                    {/* Hiển thị vị trí hiện tại của người dùng */}
                    {userLocation && (
                      <Marker position={userLocation} icon={mapIcons.user} zIndexOffset={1000}>
                        <Popup>
                          <div className="text-xs font-bold text-blue-600">Bạn đang ở đây</div>
                        </Popup>
                      </Marker>
                    )}

                    {/* Vẽ tất cả lộ trình: Vẽ các đường phụ trước, đường chính sau để hiển thị đè lên trên */}
                    {routes.length > 0 ? (
                      [...routes]
                        .map((r, i) => ({ data: r, index: i }))
                        .sort((a, b) => {
                          if (a.index === selectedRouteIndex) return 1;
                          if (b.index === selectedRouteIndex) return -1;
                          return 0;
                        })
                        .map(({ data, index }) => (
                        <Polyline 
                          key={`polyline-${index}-${index === selectedRouteIndex ? 'active' : 'alt'}-${routeKey}`}
                          positions={data.geometry.coordinates.map((c: any) => [c[1], c[0]])} 
                          color={index === selectedRouteIndex ? "#2563eb" : "#94a3b8"} 
                          weight={index === selectedRouteIndex ? 6 : 12} 
                          opacity={index === selectedRouteIndex ? 1 : 0.35}
                          dashArray={index === selectedRouteIndex ? undefined : "15, 15"}
                          smoothFactor={1}
                          eventHandlers={{ 
                            click: (e) => {
                              const originalEvent = (e as any).originalEvent;
                              if (originalEvent) L.DomEvent.stopPropagation(originalEvent);
                              setRouteMenu(null);
                              setSelectedRouteIndex(index);
                            },
                            contextmenu: (e) => {
                              const originalEvent = (e as any).originalEvent;
                              if (originalEvent) {
                                L.DomEvent.stopPropagation(originalEvent);
                                L.DomEvent.preventDefault(originalEvent);
                                // Đánh dấu để MapContextMenu biết đã có Layer xử lý
                                (originalEvent as any)._routeTriggered = true;
                              }
                              
                              setRouteMenu({ x: (e as any).containerPoint.x, y: (e as any).containerPoint.y, index });
                            },
                            mouseover: (e) => {
                              if (index !== selectedRouteIndex) {
                                (e.target as L.Polyline).setStyle({ opacity: 0.7, weight: 14, color: '#64748b' });
                              }
                            },
                            mouseout: (e) => {
                              if (index !== selectedRouteIndex) {
                                (e.target as L.Polyline).setStyle({ opacity: 0.35, weight: 12, color: '#94a3b8' });
                              }
                            }
                          }}
                        />
                      ))
                    ) : allLocations.length > 1 && (
                      /* Vẽ đường thẳng nét đứt nếu không lấy được dữ liệu lộ trình thực tế */
                      <Polyline 
                        positions={allLocations.map(l => [l.latitude, l.longitude]) as any} 
                        color="#3b82f6" 
                        weight={3} 
                        dashArray="5, 10" 
                        smoothFactor={1.5}
                      />
                    )}

                    <MarkerClusterGroup key={`cluster-group-${allLocations.length}`} chunkedLoading>
                      {allLocations.map((loc: any, index: number) => {
                        const isStart = startPoint && startPoint.id === loc.id;
                        const isEnd = endPoint && endPoint.id === loc.id;
                        
                        // Lấy icon tương ứng từ mapIcons memoized
                        const icon = isStart ? mapIcons.start : isEnd ? mapIcons.end : mapIcons.visit;

                        // Tính quãng đường từ điểm trước đó (A -> B) để hiển thị tại điểm B
                        const prevLoc = index > 0 ? allLocations[index - 1] : null;
                        const distanceToPrev = prevLoc 
                          ? calculateDistance(prevLoc.latitude, prevLoc.longitude, loc.latitude, loc.longitude).toFixed(1)
                          : null;
                        const drivingDist = index > 0 ? segmentDistances[index - 1] : null;

                        return (
                          <Marker key={`marker-${loc.id}-${isStart ? 'start' : isEnd ? 'end' : 'visit'}`} position={[loc.latitude, loc.longitude]} icon={icon}>
                            <Popup>
                              <div className="p-1">
                                <div className="font-bold text-gray-900 leading-tight mb-0.5">{loc.name}</div>
                                <div className="text-[10px] text-gray-400 mb-2 uppercase tracking-widest">{loc.type}</div>

                                <div className="flex flex-col gap-1">
                                <button
                                  onClick={() => {
                                    const leg = legs.find((l: any) => l.locations.some((lo: any) => lo.id === loc.id));
                                    handleQuickNote({ legId: loc.legId || leg?.id || '', location: loc, leg: leg || {} });
                                  }}
                                  className="flex items-center justify-center gap-1.5 py-1.5 text-yotripLight-steel hover:text-yotripLight-text dark:text-yotripDark-muted dark:hover:text-yotripDark-lime rounded-lg hover:bg-gray-100 dark:hover:bg-yotripDark-surface-muted transition-colors duration-200 border border-gray-100"
                                >
                                  <FileText className="w-3 h-3" />
                                  GHI CHÚ NHANH
                                </button>
                                  <button
                                    onClick={() => {
                                      setCommentLocationId(loc.id);
                                      setCommentLocationName(loc.name);
                                      setIsCommentModalOpen(true);
                                    }}
                                    className="w-full flex items-center justify-center gap-1.5 py-1.5 bg-blue-50 hover:bg-blue-100 text-blue-600 rounded-lg text-[10px] font-black transition-all border border-blue-100"
                                  >
                                    <MessageSquare className="w-3 h-3" />
                                    BÌNH LUẬN {loc._count?.comments > 0 && `(${loc._count.comments})`}
                                  </button>
                                </div>

                                {(drivingDist || (distanceToPrev && distanceToPrev !== "0.0")) && (
                                  <div className="mt-3 pt-3 border-t border-gray-100 flex items-center gap-2 animate-in fade-in slide-in-from-bottom-1">
                                    <div className="p-1.5 bg-blue-50 rounded-lg">
                                      <Navigation className="w-3 h-3 text-blue-600 rotate-45" />
                                    </div>
                                    <div className="flex flex-col">
                                      <span className="text-[9px] font-black text-blue-400 uppercase leading-none tracking-tighter mb-0.5">
                                        {drivingDist 
                                          ? `${travelMode === 'driving' ? 'Đường ô tô' : travelMode === 'bike' ? 'Đường xe máy' : 'Đường đi bộ'} từ điểm trước` 
                                          : 'Khoảng cách chim bay'}
                                      </span>
                                      <span className="text-xs font-black text-blue-700">{drivingDist ? drivingDist.toFixed(1) : distanceToPrev} km</span>
                                    </div>
                                  </div>
                                )}
                              </div>
                            </Popup>
                          </Marker>
                        );
                      })}
                    </MarkerClusterGroup>
                  </MapContainer>

                  {/* Floating Compass Button */}
                  <button 
                    onClick={toggleCompassMode}
                    className={`absolute bottom-16 right-4 z-[1001] w-10 h-10 rounded-xl border flex items-center justify-center shadow-xl transition-all active:scale-95 ${
                      isHeadingMode 
                        ? 'bg-blue-600 border-blue-400 text-white shadow-md' 
                        : 'bg-white/90 backdrop-blur-md border-white text-gray-500 hover:bg-gray-100'
                    }`}
                    title={isHeadingMode ? "Khóa hướng Bắc" : "Xoay theo hướng nhìn"}
                  >
                    <Compass className="w-5 h-5 transition-transform duration-300" style={{ transform: `rotate(${mapRotation}deg)` }} />
                  </button>

                  {/* Floating Locate User Button */}
                  <button 
                    onClick={() => setLocateTrigger(prev => prev + 1)}
                    disabled={!userLocation}
                    className={`absolute bottom-4 right-4 z-[1001] w-10 h-10 bg-white/90 backdrop-blur-md rounded-xl border border-white shadow-xl text-blue-600 hover:bg-blue-50 transition-all active:scale-95 flex items-center justify-center disabled:opacity-30 disabled:cursor-not-allowed`}
                    title="Vị trí của tôi"
                  >
                    <LocateFixed className="w-5 h-5" />
                  </button>

                  {/* Floating Back to Timeline Button */}
                  <button 
                    onClick={() => setViewMode('timeline')}
                    className="absolute top-3 left-14 z-[1001] h-9 px-3 bg-white/90 backdrop-blur-md rounded-xl shadow-xl border border-white text-gray-700 hover:bg-gray-50 hover:text-blue-600 transition-all active:scale-95 flex items-center gap-1.5 text-xs font-bold"
                    title="Quay lại danh sách chặng"
                  >
                    <List className="w-4 h-4" /> Danh sách
                  </button>
                  
                  {/* Menu ngữ cảnh khi click chuột phải vào con đường */}
                  {routeMenu && (
                    <div 
                      ref={routeMenuRef}
                      className="absolute z-[2001] bg-white rounded-2xl shadow-2xl border border-gray-100 py-1 w-44 animate-in zoom-in-95 duration-200"
                      style={{ top: routeMenu.y, left: routeMenu.x }}
                      onClick={(e) => e.stopPropagation()}
                    >
                      <button 
                        onClick={() => {
                          setSelectedRouteIndex(routeMenu.index);
                          setRouteMenu(null);
                          notify({
                            title: 'Đã chọn đường đi',
                            message: `Hệ thống đã chuyển sang Lựa chọn ${routeMenu.index + 1}`,
                            type: 'success'
                          });
                        }}
                        className="w-full text-left px-4 py-3 hover:bg-blue-50 text-sm font-bold text-blue-600 flex items-center gap-2 transition-colors rounded-xl"
                      >
                        <Navigation className="w-4 h-4 rotate-45" /> Đi đường này
                      </button>
                    </div>
                  )}
                  
                  {/* Overlay điều khiển trên bản đồ */}
                  <div className="absolute top-3 left-3 z-[1001] flex flex-col gap-1.5">
                    <button
                      onClick={() => setIsMapControlsOpen(!isMapControlsOpen)}
                      className="w-9 h-9 bg-white/90 backdrop-blur-md rounded-xl shadow-xl border border-white text-blue-600 hover:bg-blue-50 transition-all active:scale-95 flex items-center justify-center shrink-0"
                    >
                      {isMapControlsOpen ? (
                        <X className="w-4 h-4 text-gray-400" />
                      ) : (
                        travelMode === 'driving' ? <Car className="w-4 h-4" /> : 
                        travelMode === 'bike' ? <Bike className="w-4 h-4" /> : 
                        <Footprints className="w-4 h-4" />
                      )}
                    </button>

                    {isMapControlsOpen && (
                      <div className="bg-white/90 backdrop-blur-md p-1 rounded-xl shadow-xl border border-white flex flex-col gap-1 animate-in slide-in-from-top-2 duration-300 items-center">
                        <button 
                          onClick={() => { setTravelMode('driving'); setIsMapControlsOpen(false); }}
                          className={`w-8 h-8 flex items-center justify-center rounded-lg transition-all ${travelMode === 'driving' ? 'bg-blue-600 text-white shadow-md' : 'text-gray-500 hover:bg-gray-100'}`}
                          title="Ô tô"
                        >
                          <Car className="w-3.5 h-3.5" />
                        </button>
                        <button 
                          onClick={() => { setTravelMode('bike'); setIsMapControlsOpen(false); }}
                          className={`w-8 h-8 flex items-center justify-center rounded-lg transition-all ${travelMode === 'bike' ? 'bg-blue-600 text-white shadow-md' : 'text-gray-500 hover:bg-gray-100'}`}
                          title="Xe máy / Xe đạp"
                        >
                          <Bike className="w-3.5 h-3.5" />
                        </button>
                        <button 
                          onClick={() => { setTravelMode('foot'); setIsMapControlsOpen(false); }}
                          className={`w-8 h-8 flex items-center justify-center rounded-lg transition-all ${travelMode === 'foot' ? 'bg-blue-600 text-white shadow-md' : 'text-gray-500 hover:bg-gray-100'}`}
                          title="Đi bộ"
                        >
                          <Footprints className="w-3.5 h-3.5" />
                        </button>

                        {/* Nút La bàn / Xoay bản đồ */}
                        <button 
                          onClick={() => {
                            const newMode = !isHeadingMode;
                            setIsHeadingMode(newMode);
                            if (!newMode) setMapRotation(0);
                            setIsMapControlsOpen(false);
                          }}
                          className={`w-8 h-8 flex items-center justify-center rounded-lg transition-all border-t border-gray-100 mt-0.5 ${isHeadingMode ? 'bg-blue-600 text-white shadow-md' : 'text-gray-500 hover:bg-gray-100'}`}
                          title={isHeadingMode ? "Khóa hướng Bắc" : "Xoay theo hướng nhìn"}
                        >
                          <Compass className="w-3.5 h-3.5 transition-transform duration-300" style={{ transform: `rotate(${mapRotation}deg)` }} />
                        </button>

                        {/* Nút Tìm tôi */}
                        <button 
                          onClick={() => { setLocateTrigger(prev => prev + 1); setIsMapControlsOpen(false); }}
                          disabled={!userLocation}
                          className={`w-8 h-8 flex items-center justify-center rounded-lg transition-all border-t border-gray-100 mt-0.5 ${!userLocation ? 'opacity-30 cursor-not-allowed' : 'text-blue-600 hover:bg-blue-50'}`}
                          title="Vị trí của tôi"
                        >
                          <LocateFixed className="w-3.5 h-3.5" />
                        </button>

                        {/* Danh sách lộ trình rút gọn */}
                        {routes.length > 0 && (
                          <div className="pt-1 border-t border-gray-100 flex flex-col gap-1">
                            <div className="flex flex-col gap-1 max-h-[160px] overflow-y-auto pr-1 custom-scrollbar">
                              {routes.map((route, idx) => (
                                <button
                                  key={idx}
                                  onClick={() => { setSelectedRouteIndex(idx); setIsMapControlsOpen(false); }}
                                  title={`${(route.distance / 1000).toFixed(1)} km - ${Math.round(route.duration / 60)}p`}
                                  className={`w-8 h-8 flex items-center justify-center rounded-lg transition-all border ${
                                    selectedRouteIndex === idx 
                                      ? 'bg-blue-600 text-white border-blue-600 shadow-sm' 
                                      : 'bg-gray-50 text-gray-600 border-gray-100'
                                  }`}
                                >
                                  <span className="text-[10px] font-bold">{idx + 1}</span>
                                </button>
                              ))}
                            </div>
                          </div>
                        )}
                      </div>
                    )}
                    
                    
                    
                  </div>
                </div>
              )}
            </div>
          )}

          {activeTab === 'expense' && (
            <div className="animate-in fade-in slide-in-from-bottom-4">
              <ExpenseManager />
            </div>
          )}

          {activeTab === 'photo' && (
            <div className="animate-in fade-in">
              {/* Main container for the new layout */}
              <div className="flex flex-col md:flex-row gap-4">
                {/* Left Column: Leg List */}
                <div className="md:w-1/4 bg-white rounded-2xl shadow-lg border border-gray-100 p-4 flex-shrink-0">
                  <h3 className="text-sm font-bold text-gray-800 mb-3">Chặng của Tour</h3>
                  <div className="space-y-2">
                    <button
                      onClick={() => {
                        setSelectedLegIdForPhoto('all');
                        setSelectedPhotoForDisplay(null); // Reset selected photo when changing leg
                      }}
                      className={`w-full text-left px-3 py-2 rounded-xl text-xs font-bold transition-all ${
                        selectedLegIdForPhoto === 'all' ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
                      }`}
                    >
                      Tất cả ảnh
                    </button>
                    {legs.map(leg => (
                      <button
                        key={leg.id}
                        onClick={() => {
                          setSelectedLegIdForPhoto(leg.id);
                          setSelectedPhotoForDisplay(null); // Reset selected photo when changing leg
                        }}
                        className={`w-full text-left px-3 py-2 rounded-xl text-xs font-bold transition-all ${
                          selectedLegIdForPhoto === leg.id ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
                        }`}
                      >
                        Chặng {leg.sequence}: {leg.note || 'Không ghi chú'}
                      </button>
                    ))}
                  </div>
                </div>

                {/* Right Column: Large Photo Display */}
                <div className="md:flex-1 bg-white rounded-2xl shadow-lg border border-gray-100 p-4 flex flex-col items-center justify-center min-h-[300px]">
                  {selectedPhotoForDisplay ? (
                    <div className="relative w-full h-full flex flex-col items-center justify-center">
                      <div className="relative overflow-hidden rounded-xl shadow-md max-w-full max-h-[calc(100vh-350px)] group">
                        <img
                          src={selectedPhotoForDisplay.imageUrl}
                          alt="Selected Tour Photo"
                          className="max-w-full max-h-[calc(100vh-350px)] object-contain cursor-zoom-in"
                          onClick={() => setIsFullscreen(true)}
                        />
                        
                        {/* Overlays (Only show when not editing) */}
                        {!isEditingPhoto && (
                          <>
                            {/* Like (Heart) button overlay */}
                            <button
                              onClick={handleToggleLikePhoto}
                              className="absolute top-4 left-4 z-10 flex items-center gap-1.5 bg-black/60 hover:bg-black/75 border border-white/10 text-white font-bold py-1.5 px-3 rounded-full transition-all active:scale-95 text-[11px] backdrop-blur-md"
                              title={isPhotoLiked ? "Bỏ thích" : "Thích"}
                            >
                              <Heart className={`w-4 h-4 transition-colors ${
                                isPhotoLiked ? 'text-rose-500 fill-rose-500 animate-in zoom-in-75' : 'text-gray-300 hover:text-rose-450'
                              }`} />
                              <span>{photoLikeCount}</span>
                            </button>

                            {/* Delete button overlay (if owner) */}
                            {currentUserId === selectedPhotoForDisplay.uploaderId && (
                              <button
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleDeletePhoto(selectedPhotoForDisplay.id);
                                }}
                                className="absolute top-4 right-4 z-10 p-2 bg-black/60 hover:bg-red-650 border border-white/10 text-white rounded-full transition-all active:scale-95 backdrop-blur-md"
                                title="Xóa ảnh này"
                              >
                                <Trash2 className="w-4 h-4" />
                              </button>
                            )}

                            {/* Bottom metadata details gradient panel overlay */}
                            <div className="absolute bottom-0 inset-x-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent p-6 text-white flex flex-col gap-2 text-left">
                              <div className="flex justify-between items-start gap-4">
                                <div className="flex-1 min-w-0">
                                  {selectedPhotoForDisplay.metadata?.title ? (
                                    <h3 className="text-base font-extrabold text-white break-words drop-shadow-md">
                                      {selectedPhotoForDisplay.metadata.title}
                                    </h3>
                                  ) : (
                                    <span className="text-xs text-gray-350 italic block mb-1 drop-shadow-md">Chưa có tiêu đề</span>
                                  )}
                                  {selectedPhotoForDisplay.metadata?.description ? (
                                    <p className="text-xs text-gray-250 leading-relaxed mt-1 break-words drop-shadow-sm max-h-16 overflow-y-auto no-scrollbar">
                                      {selectedPhotoForDisplay.metadata.description}
                                    </p>
                                  ) : (
                                    <span className="text-[11px] text-gray-350 italic block mt-1 drop-shadow-sm">Chưa có mô tả</span>
                                  )}
                                </div>
                                
                                {/* Edit Button Overlay */}
                                {((!isPublicView && currentUser?.isAdmin) || (currentUserId && currentUserId === selectedPhotoForDisplay.uploaderId)) && (
                                  <button
                                    onClick={() => setIsEditingPhoto(true)}
                                    className="p-2 bg-white/10 hover:bg-white/20 border border-white/15 rounded-xl text-white hover:text-gray-200 transition-all shrink-0 backdrop-blur-sm"
                                    title="Chỉnh sửa thông tin"
                                  >
                                    <Edit className="w-4 h-4" />
                                  </button>
                                )}
                              </div>

                              {/* Additional metadata info inside bottom overlay */}
                              <div className="flex flex-wrap items-center justify-between gap-4 border-t border-white/10 pt-3 text-xs text-gray-200">
                                <div className="space-y-1">
                                  <div className="flex items-center gap-2 text-gray-300 text-[10px] font-bold uppercase tracking-wider">
                                    <Calendar className="w-3.5 h-3.5" />
                                    Ngày chụp: {new Date(selectedPhotoForDisplay.capturedAt).toLocaleDateString('vi-VN', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}
                                  </div>
                                  <div className="flex items-center gap-2 font-bold" title={selectedPhotoForDisplay.metadata?.lat && selectedPhotoForDisplay.metadata?.lng ? `${selectedPhotoForDisplay.metadata.lat.toFixed(6)}, ${selectedPhotoForDisplay.metadata.lng.toFixed(6)}` : ''}>
                                    <MapPin className="w-3.5 h-3.5 text-rose-500" />
                                    Địa điểm: {resolvedAddress}
                                  </div>
                                  <div className="text-[10px] text-gray-400">
                                    Tải lên bởi: {selectedPhotoForDisplay.uploader?.name || 'Thành viên'}
                                  </div>
                                </div>
                                
                                {(currentUser?.isAdmin || currentUserId === selectedPhotoForDisplay.uploaderId) && selectedPhotoForDisplay.originalUrl && (
                                  <a 
                                    href={selectedPhotoForDisplay.originalUrl} 
                                    download 
                                    className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-xl font-bold uppercase tracking-widest text-[9px] transition-all shadow-md active:scale-95 shrink-0"
                                  >
                                    <Download className="w-3.5 h-3.5 animate-pulse" /> Tải ảnh gốc
                                  </a>
                                )}
                              </div>
                            </div>
                          </>
                        )}
                      </div>

                      {isEditingPhoto && (
                        <div className="mt-6 w-full flex flex-col gap-4 px-2">
                          <div className="space-y-3 bg-gray-50 border border-gray-150 p-4 rounded-2xl w-full text-left">
                            <h4 className="text-xs font-black uppercase tracking-wider text-blue-600">Chỉnh sửa thông tin ảnh</h4>
                            
                            <div className="space-y-2">
                              <div>
                                <label className="block text-[10px] uppercase font-bold tracking-wider text-gray-500 mb-1">Tiêu đề</label>
                                <input
                                  type="text"
                                  value={editPhotoTitle}
                                  onChange={(e) => setEditPhotoTitle(e.target.value)}
                                  placeholder="Nhập tiêu đề..."
                                  className="w-full bg-white border border-gray-200 text-gray-800 rounded-xl px-3 py-2 text-xs focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent"
                                />
                              </div>

                              <div>
                                <label className="block text-[10px] uppercase font-bold tracking-wider text-gray-500 mb-1">Mô tả</label>
                                <textarea
                                  value={editPhotoDescription}
                                  onChange={(e) => setEditPhotoDescription(e.target.value)}
                                  placeholder="Nhập mô tả..."
                                  rows={2}
                                  className="w-full bg-white border border-gray-200 text-gray-800 rounded-xl px-3 py-2 text-xs focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent resize-none"
                                />
                              </div>

                              <div className="grid grid-cols-2 gap-2">
                                <div>
                                  <label className="block text-[10px] uppercase font-bold tracking-wider text-gray-500 mb-1">Vĩ độ</label>
                                  <input
                                    type="number"
                                    step="any"
                                    value={editPhotoLat}
                                    onChange={(e) => setEditPhotoLat(e.target.value === '' ? '' : parseFloat(e.target.value))}
                                    placeholder="Vĩ độ..."
                                    className="w-full bg-white border border-gray-200 text-gray-800 rounded-xl px-3 py-2 text-xs focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent"
                                  />
                                </div>
                                <div>
                                  <label className="block text-[10px] uppercase font-bold tracking-wider text-gray-500 mb-1">Kinh độ</label>
                                  <input
                                    type="number"
                                    step="any"
                                    value={editPhotoLng}
                                    onChange={(e) => setEditPhotoLng(e.target.value === '' ? '' : parseFloat(e.target.value))}
                                    placeholder="Kinh độ..."
                                    className="w-full bg-white border border-gray-200 text-gray-800 rounded-xl px-3 py-2 text-xs focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent"
                                  />
                                </div>
                              </div>
                            </div>

                            <div className="flex justify-start">
                              <button
                                type="button"
                                onClick={() => setIsMapOpen(true)}
                                className="flex items-center gap-1.5 px-3 py-1.5 bg-gray-100 hover:bg-gray-200 border border-gray-200 text-gray-700 hover:text-gray-900 rounded-xl text-[10px] font-bold transition-all"
                              >
                                <MapPin className="w-3.5 h-3.5 text-rose-500" />
                                Chọn trên bản đồ
                              </button>
                            </div>

                            <div className="flex justify-end gap-2 mt-2">
                              <button
                                onClick={() => setIsEditingPhoto(false)}
                                disabled={isSavingPhotoEdit}
                                className="px-3 py-1.5 bg-gray-200 hover:bg-gray-300 text-gray-700 rounded-lg text-xs font-bold transition-all"
                              >
                                Hủy
                              </button>
                              <button
                                onClick={handleSavePhotoEdit}
                                disabled={isSavingPhotoEdit}
                                className="flex items-center gap-1 px-4 py-1.5 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white rounded-lg text-xs font-bold transition-all"
                              >
                                {isSavingPhotoEdit ? (
                                  <>
                                    <Loader2 className="w-3.5 h-3.5 animate-spin" />
                                    Đang lưu...
                                  </>
                                ) : (
                                  'Lưu lại'
                                )}
                              </button>
                            </div>
                          </div>
                        </div>
                      )}
                    </div>
                  ) : (
                    <div className="text-center text-gray-400">
                      <ImageIcon className="w-16 h-16 mx-auto mb-4" />
                      <p className="text-lg font-medium">Chọn một ảnh để xem chi tiết</p>
                    </div>
                  )}
                </div>
              </div>

              {/* Bottom Row: Thumbnails */}
              <div className="mt-4 bg-white rounded-2xl shadow-lg border border-gray-100 p-4">
                <h3 className="text-sm font-bold text-gray-800 mb-3">
                  {selectedLegIdForPhoto === 'all' ? 'Tất cả ảnh' : `Ảnh của Chặng ${legs.find(l => l.id === selectedLegIdForPhoto)?.sequence || ''}`}
                </h3>
                {filteredPhotos.length > 0 ? (
                  <div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-3 overflow-x-auto pb-2">
                    {filteredPhotos.map((photo: any) => (
                      <div
                        key={photo.id}
                        onClick={() => setSelectedPhotoForDisplay(photo)}
                        className={`aspect-square bg-gray-200 rounded-xl overflow-hidden relative group border-2 ${
                          selectedPhotoForDisplay?.id === photo.id ? 'border-blue-500' : 'border-transparent'
                        } hover:border-blue-300 transition-all cursor-pointer`}
                      >
                        <img
                          src={photo.imageUrl}
                          alt="Thumbnail"
                          className="w-full h-full object-cover"
                        />
                      </div>
                    ))}
                  </div>
                ) : (
                  <div className="py-10 text-center text-gray-400">
                    <ImageIcon className="w-12 h-12 mx-auto mb-3" />
                    <p className="text-md font-medium">Chưa có ảnh nào cho chặng này.</p>
                  </div>
                )}
              </div>
            </div>
          )}

          {activeTab === 'settings' && !isPublicView && ( // Hide settings tab in public view
            <div className="space-y-4">
              <div className="p-6 bg-white rounded-3xl border border-dashed border-gray-200 animate-in zoom-in-95">
                <div className="flex items-center gap-3 mb-4">
                  <Clock className="w-6 h-6 text-blue-500" />
                  <h3 className="text-lg font-bold text-gray-900">Yêu cầu tham gia</h3>
                  <span className="text-xs font-bold text-gray-500 bg-gray-100 px-2 py-1 rounded-full">{joinRequests.length} đang chờ</span>
                </div>
                <div className="space-y-2">
                  {joinRequests.map((req: any) => (
                    <div key={req.id} className="flex items-center justify-between gap-3 p-3 rounded-2xl border border-gray-100 bg-white">
                      <div className="flex items-center gap-3">
                        <div className="w-9 h-9 rounded-full bg-amber-50 border border-amber-200 flex items-center justify-center text-amber-700 font-bold text-sm">
                          {req.user?.name?.charAt(0) || '?'}
                        </div>
                        <div>
                          <div className="text-sm font-bold text-gray-800">{req.user?.name || req.userId}</div>
                          <div className="text-[11px] text-gray-500">
                            Được mời bởi {req.requestedBy?.name} • {new Date(req.createdAt).toLocaleString('vi-VN')}
                          </div>
                        </div>
                      </div>
                      {isOwner && <div className="flex gap-2">
                        <button
                          disabled={joinRequestActionId === req.id}
                          onClick={async () => {
                            if (!currentTour) return;
                            const isConfirmed = await confirm({
                              title: 'Chấp nhận yêu cầu',
                              message: `Chấp nhận ${req.user?.name || req.userId} vào tour?`
                            });
                            if (isConfirmed) {
                              setJoinRequestActionId(req.id);
                              try {
                                await acceptJoinRequest(currentTour.id, req.id);
                                setJoinRequests((prev) => prev.filter((r) => r.id !== req.id));
                              } catch (e: any) {
                                notify({ title: 'Thông báo', message: e.message || 'Không thể chấp nhận yêu cầu', type: 'error' });
                              } finally {
                                setJoinRequestActionId(null);
                              }
                            }
                          }}
                          className="p-2 rounded-xl bg-green-50 text-green-700 hover:bg-green-100 disabled:opacity-50"
                          aria-label="Accept"
                        >
                          <Check className="w-4 h-4" />
                        </button>
                        <button
                          disabled={joinRequestActionId === req.id}
                          onClick={async () => {
                            if (!currentTour) return;
                            const isConfirmed = await confirm({
                              title: 'Từ chối yêu cầu',
                              message: `Từ chối ${req.user?.name || req.userId} tham gia tour?`
                            });
                            if (isConfirmed) {
                              setJoinRequestActionId(req.id);
                              try {
                                await rejectJoinRequest(currentTour.id, req.id);
                                setJoinRequests((prev) => prev.filter((r) => r.id !== req.id));
                              } catch (e: any) {
                                notify({ title: 'Thông báo', message: e.message || 'Không thể từ chối yêu cầu', type: 'error' });
                              } finally {
                                setJoinRequestActionId(null);
                              }
                            }
                          }}
                          className="p-2 rounded-xl bg-red-50 text-red-700 hover:bg-red-100 disabled:opacity-50"
                          aria-label="Reject"
                        >
                          <X className="w-4 h-4" />
                        </button>
                      </div>}
                    </div>
                  ))}
                  {joinRequests.length === 0 && (
                    <div className="text-center py-8 text-sm text-gray-500">Không có yêu cầu tham gia nào đang chờ phê duyệt.</div>
                  )}
                </div>
              </div>

              {/* Emergency Sharing Settings */}
              <div className="p-6 bg-white dark:bg-slate-900 rounded-3xl border border-dashed border-rose-200 dark:border-rose-950/40 shadow-sm animate-in zoom-in-95">
                <div className="flex items-center justify-between mb-4">
                  <div className="flex items-center gap-3">
                    <span className="text-xl">🚨</span>
                    <div>
                      <h3 className="text-lg font-bold text-gray-900 dark:text-white">{t('emergencyShare')}</h3>
                      <p className="text-xs text-gray-500 dark:text-slate-400">{t('emergencyShareTooltip')}</p>
                    </div>
                  </div>
                  {shareStatus && (
                    <label className="relative inline-flex items-center cursor-pointer">
                      <input
                        type="checkbox"
                        checked={shareStatus.isEnabled}
                        onChange={(e) => handleToggleShare(e.target.checked)}
                        className="sr-only peer"
                      />
                      <div className="w-11 h-6 bg-gray-200 dark:bg-slate-800 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-rose-500"></div>
                    </label>
                  )}
                </div>

                {shareStatus?.isEnabled && (
                  <div className="mt-4 bg-rose-50 dark:bg-rose-950/20 p-4 rounded-2xl border border-rose-100 dark:border-rose-950/30 flex flex-col gap-2">
                    <div className="text-xs font-bold text-rose-700 dark:text-rose-400 uppercase tracking-widest">Đường dẫn chia sẻ khẩn cấp:</div>
                    <div className="flex items-center gap-2">
                      <input
                        type="text"
                        readOnly
                        value={`${window.location.origin}/journey/${shareStatus.token}`}
                        className="flex-1 bg-white dark:bg-slate-800 border dark:border-slate-700 rounded-xl px-3 py-2 text-xs text-slate-800 dark:text-slate-100 select-all"
                      />
                      <button
                        type="button"
                        onClick={() => {
                          navigator.clipboard.writeText(`${window.location.origin}/journey/${shareStatus.token}`);
                          notify({ title: 'Thành công', message: 'Đã sao chép liên kết!', type: 'success' });
                        }}
                        className="bg-rose-600 hover:bg-rose-700 text-white font-bold px-3 py-2 rounded-xl text-xs transition-all active:scale-95 shrink-0"
                      >
                        {t('copyShareLink')}
                      </button>
                    </div>
                  </div>
                )}
              </div>

              {canEdit && (
                <div className="p-6 bg-white rounded-3xl border border-gray-100 shadow-sm animate-in zoom-in-95">
                  <div className="flex items-center gap-3 mb-6">
                    <Settings className="w-6 h-6 text-blue-500" />
                    <h3 className="text-lg font-bold text-gray-900">Thông tin cơ bản</h3>
                  </div>
                  
                  <div className="space-y-4 mb-8">
                    {isOwner && (
                      <>
                        <div>
                          <label className="block text-xs font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Tiêu đề Tour</label>
                          <input
                            type="text"
                            value={titleInput}
                            onChange={(e) => setTitleInput(e.target.value)}
                            className="w-full px-4 py-3 bg-gray-50 border border-gray-100 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm font-bold"
                            placeholder="Nhập tên chuyến đi..."
                          />
                        </div>
                        <div>
                          <label className="block text-xs font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Mô tả chuyến đi</label>
                          <textarea
                            value={descriptionInput}
                            onChange={(e) => setDescriptionInput(e.target.value)}
                            className="w-full px-4 py-3 bg-gray-50 border border-gray-100 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm min-h-[100px] resize-none"
                            placeholder="Viết vài dòng giới thiệu về hành trình này..."
                          />
                        </div>
                      </>
                    )}

                  <div className="flex items-center gap-3 mb-4">
                    <Users className="w-6 h-6 text-purple-500" />
                    <h3 className="text-md font-bold text-gray-800">Số lượng người tham gia</h3>
                  </div>
                  <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
                    <div>
                      <label htmlFor="adultCount" className="block text-sm font-medium text-gray-700 mb-1">Số lượng người lớn</label>
                      <input
                        type="number"
                        id="adultCount"
                        value={adultCountInput}
                        onChange={(e) => setAdultCountInput(Number(e.target.value))}
                        min="0"
                        className="w-full px-4 py-2 border border-yotripLight-khaki rounded-xl focus:ring-yotripLight-text focus:border-yotripLight-text bg-white text-yotripLight-text dark:bg-yotripDark-surface dark:text-white dark:border-yotripDark-surface-muted dark:focus:ring-yotripDark-lime dark:focus:border-yotripDark-lime transition-colors duration-200"
                      />
                    </div>
                    <div>
                      <label htmlFor="childCount" className="block text-sm font-medium text-gray-700 mb-1">Số lượng trẻ em</label>
                      <input
                        type="number"
                        id="childCount"
                        value={childCountInput}
                        onChange={(e) => setChildCountInput(Number(e.target.value))}
                        min="0"
                        className="w-full px-4 py-2 border border-yotripLight-khaki rounded-xl focus:ring-yotripLight-text focus:border-yotripLight-text bg-white text-yotripLight-text dark:bg-yotripDark-surface dark:text-white dark:border-yotripDark-surface-muted dark:focus:ring-yotripDark-lime dark:focus:border-yotripDark-lime transition-colors duration-200"
                      />
                    </div>
                    <div>
                      <label htmlFor="childDiscount" className="block text-sm font-medium text-gray-700 mb-1">Giảm giá trẻ em (%)</label>
                      <input
                        type="number"
                        id="childDiscount"
                        value={childDiscountInput}
                        onChange={(e) => setChildDiscountInput(Number(e.target.value))}
                        min="0"
                        max="100"
                        className="w-full px-4 py-2 border border-yotripLight-khaki rounded-xl focus:ring-yotripLight-text focus:border-yotripLight-text bg-white text-yotripLight-text dark:bg-yotripDark-surface dark:text-white dark:border-yotripDark-surface-muted dark:focus:ring-yotripDark-lime dark:focus:border-yotripDark-lime transition-colors duration-200"
                      />
                    </div>
                  </div>

                  <div>
                    <label className="block text-xs font-black text-gray-400 uppercase tracking-widest mb-2 ml-1 flex items-center gap-2">
                      <TagIcon className="w-3 h-3" /> Phân loại Tour
                    </label>
                    <div className="flex flex-wrap gap-2">
                      {availableTags.map(tag => (
                        <button
                          key={tag}
                          type="button"
                          onClick={() => setTagsInput(prev => prev.includes(tag) ? prev.filter(t => t !== tag) : [...prev, tag])}
                          className={`px-3 py-1.5 rounded-xl text-xs font-bold transition-all border ${
                            tagsInput.includes(tag) 
                              ? 'bg-blue-600 text-white border-blue-600' 
                              : 'bg-white text-gray-500 border-gray-200 hover:border-blue-300'
                          }`}
                        >
                          {tag}
                        </button>
                      ))}
                    </div>
                    <div className="flex gap-2 mt-3">
                      <input
                        type="text"
                        value={customTag}
                        onChange={(e) => setCustomTag(e.target.value)}
                        onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), setTagsInput(prev => customTag.trim() && !prev.includes(customTag.trim()) ? [...prev, customTag.trim()] : prev), setCustomTag(''))}
                        placeholder="Thêm nhãn tùy chỉnh..."
                        className="flex-1 px-4 py-2.5 bg-gray-50 border border-gray-100 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500"
                      />
                      <button
                        type="button"
                        onClick={() => { if (customTag.trim() && !tagsInput.includes(customTag.trim())) { setTagsInput([...tagsInput, customTag.trim()]); setCustomTag(''); } }}
                        className="px-4 py-2 bg-blue-50 text-blue-600 rounded-xl text-xs font-bold hover:bg-blue-100 transition-all border border-blue-100"
                      >
                        Thêm
                      </button>
                    </div>
                  </div>

                    <button
                      onClick={handleUpdateTourInfo}
                      className="w-full mt-6 px-4 py-4 bg-blue-600 hover:bg-blue-700 text-white font-black uppercase tracking-widest rounded-2xl transition-all shadow-lg shadow-blue-100 active:scale-95"
                    >
                      Lưu thay đổi
                    </button>
                  </div>
                </div>
              )}

              {/* Danger Zone - Khu vực dành cho các hành động quan trọng */}
              <div className="p-6 bg-red-50 rounded-3xl border border-red-100 animate-in zoom-in-95">
                <div className="flex items-center gap-3 mb-4 text-red-600">
                  <Trash2 className="w-6 h-6" />
                  <h3 className="text-lg font-bold">Vùng nguy hiểm</h3>
                </div>
                <p className="text-sm text-red-500 mb-6 font-medium">Một khi đã xóa, bạn sẽ không thể khôi phục lại dữ liệu của hành trình này.</p>
                <button
                  onClick={handleDeleteTour}
                  className="w-full py-4 bg-red-600 hover:bg-red-700 text-white font-black uppercase tracking-widest rounded-2xl transition-all shadow-lg shadow-red-100 active:scale-95"
                >
                  Xóa Tour vĩnh viễn
                </button>
              </div>
            </div>
          )}
          {activeTab === 'members' && canManage && currentTour && (
            <MembersTab
              tourId={currentTour.id}
              participants={currentTour.participants || []}
              joinRequests={joinRequests}
              userRole={userRole}
              canManage={canManage}
              isOwner={isOwner}
              onRemoveMember={(memberIdOrUserId: string) => removeMember(currentTour.id, memberIdOrUserId)}
              onRefresh={() => fetchTour(currentTour.id)}
              onOpenAddMember={() => setIsAddMemberOpen(true)}
            />
          )}
          {activeTab === 'chat' && currentTour && (
            <div className="fixed left-0 right-0 bottom-0 flex flex-col bg-white z-[15]" style={{top: 'calc(60px + 5px)'}}>
              {/* Chat Group Header Banner - Fixed below nav + tabs, sticky to title */}
              <div className="flex-shrink-0 p-3 border-b border-gray-200 bg-white flex items-center gap-2">
                <MessageSquare className="w-5 h-5 text-blue-500" />
                <div>
                  <h3 className="text-sm font-bold text-gray-800">Trò chuyện trong nhóm</h3>
                  <p className="text-[10px] text-gray-400 font-medium">Nơi trao đổi thông tin, hình ảnh và định vị giữa các thành viên</p>
                </div>
              </div>
              {/* TourChat with proper scrollable area */}
              <TourChat tourId={currentTour.id} embedded={true} />
            </div>
          )}
        </div>
      </div>

      {/* Floating Action Button (Mobile) */}
      {((activeTab === 'plan' && viewMode === 'timeline' && canEdit) || (activeTab === 'photo' && canUploadPhoto)) && !isPublicView && (
        <div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-40">
          <button 
            onClick={() => {
              setTargetLegId(null); // Reset khi nhấn nút floating tổng quát
              setEditingLocation(null);
              setIsStartPointAction(false);
              setIsEndPointAction(false);
              if (activeTab === 'plan') setIsAddLocationOpen(true);
              if (activeTab === 'photo' && canUploadPhoto) setIsAddPhotoOpen(true);
            }}
            className="bg-blue-600 text-white px-4 py-2.5 rounded-full shadow-lg hover:bg-blue-700 transition-all flex items-center font-bold text-sm">
            {activeTab === 'plan' ? 'Thêm địa điểm' : 'Đăng ảnh'}
          </button>
        </div>
      )}

      {/* Fullscreen Map Overlay - Hiển thị khi click vào nút trạng thái/chỉ đường */}
      {isMapFullscreen && (
        <div className="fixed inset-0 z-[5000] bg-white animate-in fade-in slide-in-from-bottom-16 duration-500 overflow-hidden">
          {/* Nút X để quay lại */}
          <button 
            onClick={() => setIsMapFullscreen(false)}
            className="absolute top-[calc(1rem+env(safe-area-inset-top,0px))] left-4 z-[1002] w-11 h-11 bg-white/90 backdrop-blur-md rounded-full shadow-2xl flex items-center justify-center border border-white/20 hover:bg-white transition-all active:scale-95 group"
            title="Đóng bản đồ"
          >
            <X className="w-6 h-6 text-gray-800 group-hover:rotate-90 transition-transform duration-300" />
          </button>

          {/* Transparent Top Bar Label - Glassmorphism style */}
          {selectedRouteInfo && drivingRoute.length > 0 && (
            <div className="absolute top-[calc(1rem+env(safe-area-inset-top,0px))] left-1/2 -translate-x-1/2 z-[1001] bg-white/20 backdrop-blur-lg px-6 py-2.5 rounded-full border border-white/30 flex items-center gap-4 animate-in fade-in slide-in-from-top-2 duration-500 shadow-xl">
              <div className="flex items-center gap-2">
                <Navigation className="w-4 h-4 text-blue-600 rotate-45 fill-blue-600" />
                <span className="text-[11px] font-black text-gray-700 uppercase tracking-widest">{selectedRouteInfo.label}</span>
              </div>
              <div className="flex items-center gap-3 text-sm font-black text-blue-700 whitespace-nowrap">
                <span>{selectedRouteInfo.distance} km</span>
                <span className="text-gray-400 opacity-40">•</span>
                <span>{selectedRouteInfo.duration}</span>
              </div>
            </div>
          )}

          <MapContainer 
            center={mapCenter} 
            zoom={mapZoom} 
            className="h-full w-full"
            preferCanvas={true}
            attributionControl={false}
          >
            <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="" />
            <MapTourBounds locations={allLocations} />
            <MapRotationHandler rotation={mapRotation} />
            <RecenterUser position={userLocation} trigger={locateTrigger} />

            {userLocation && (
              <Marker position={userLocation} icon={mapIcons.user} />
            )}

            {routes.length > 0 ? (
              routes.map((r, i) => (
                <Polyline 
                  key={`fs-poly-${i}`}
                  positions={r.geometry.coordinates.map((c: any) => [c[1], c[0]])} 
                  color={i === selectedRouteIndex ? "#2563eb" : "#94a3b8"} 
                  weight={i === selectedRouteIndex ? 6 : 4} 
                  opacity={i === selectedRouteIndex ? 1 : 0.4}
                />
              ))
            ) : allLocations.length > 1 && (
              <Polyline positions={allLocations.map(l => [l.latitude, l.longitude]) as any} color="#3b82f6" weight={3} dashArray="5, 10" />
            )}

            {allLocations.map((loc: any) => {
              const isStart = startPoint && startPoint.id === loc.id;
              const isEnd = endPoint && endPoint.id === loc.id;
              return (
                <Marker key={`fs-marker-${loc.id}`} position={[loc.latitude, loc.longitude]} icon={isStart ? mapIcons.start : isEnd ? mapIcons.end : mapIcons.visit}>
                  <Popup>
                    <div className="font-bold">{loc.name}</div>
                  </Popup>
                </Marker>
              );
            })}
          </MapContainer>

          {/* Floating Compass Button (Fullscreen) */}
          <button 
            onClick={toggleCompassMode}
            className={`absolute bottom-22 right-6 z-[1001] w-12 h-12 rounded-2xl border flex items-center justify-center shadow-xl transition-all active:scale-95 ${
              isHeadingMode 
                ? 'bg-blue-600 border-blue-400 text-white shadow-md' 
                : 'bg-white/90 backdrop-blur-md border-white text-gray-500 hover:bg-gray-100'
            }`}
            title={isHeadingMode ? "Khóa hướng Bắc" : "Xoay theo hướng nhìn"}
          >
            <Compass className="w-6 h-6 transition-transform duration-300" style={{ transform: `rotate(${mapRotation}deg)` }} />
          </button>

          {/* Floating Locate User Button (Fullscreen) */}
          <button 
            onClick={() => setLocateTrigger(prev => prev + 1)}
            disabled={!userLocation}
            className={`absolute bottom-8 right-6 z-[1001] w-12 h-12 bg-white/90 backdrop-blur-md rounded-2xl border border-white shadow-xl text-blue-600 hover:bg-blue-50 transition-all active:scale-95 flex items-center justify-center disabled:opacity-30 disabled:cursor-not-allowed`}
            title="Vị trí của tôi"
          >
            <LocateFixed className="w-6 h-6" />
          </button>

          {/* Overlay điều khiển trên bản đồ toàn màn hình */}
          <div className="absolute top-[calc(1rem+env(safe-area-inset-top,0px))] right-4 z-[1001] flex flex-col gap-2">
             <button
                onClick={() => setIsMapControlsOpen(!isMapControlsOpen)}
                className="w-11 h-11 bg-white/90 backdrop-blur-md rounded-2xl shadow-xl border border-white text-blue-600 flex items-center justify-center transition-all active:scale-95"
              >
                {travelMode === 'driving' ? <Car className="w-5 h-5" /> : travelMode === 'bike' ? <Bike className="w-5 h-5" /> : <Footprints className="w-5 h-5" />}
              </button>

              {isMapControlsOpen && (
                <div className="bg-white/90 backdrop-blur-md p-1.5 rounded-2xl shadow-xl border border-white flex flex-col gap-1.5 animate-in slide-in-from-top-2">
                  <button onClick={() => { setTravelMode('driving'); setIsMapControlsOpen(false); }} className={`w-9 h-9 flex items-center justify-center rounded-xl ${travelMode === 'driving' ? 'bg-blue-600 text-white' : 'text-gray-500'}`}><Car className="w-4 h-4" /></button>
                  <button onClick={() => { setTravelMode('bike'); setIsMapControlsOpen(false); }} className={`w-9 h-9 flex items-center justify-center rounded-xl ${travelMode === 'bike' ? 'bg-blue-600 text-white' : 'text-gray-500'}`}><Bike className="w-4 h-4" /></button>
                  <button onClick={() => { setTravelMode('foot'); setIsMapControlsOpen(false); }} className={`w-9 h-9 flex items-center justify-center rounded-xl ${travelMode === 'foot' ? 'bg-blue-600 text-white' : 'text-gray-500'}`}><Footprints className="w-4 h-4" /></button>
                  <button 
                    onClick={() => {
                      toggleCompassMode();
                      setIsMapControlsOpen(false);
                    }}
                    className={`w-9 h-9 flex items-center justify-center rounded-xl border-t border-gray-100 transition-all ${isHeadingMode ? 'bg-blue-600 text-white' : 'text-gray-500'}`}
                  >
                    <Compass className="w-4 h-4" style={{ transform: `rotate(${mapRotation}deg)` }} />
                  </button>
                </div>
              )}
          </div>
        </div>
      )}

      {/* Add Member Modal */}
      {currentTour && (
        <AddMemberModal
          isOpen={isAddMemberOpen}
          onClose={() => setIsAddMemberOpen(false)}
          tourId={currentTour.id}
          participants={currentTour.participants || []}
          joinRequests={joinRequests}
          onRemoveMember={(userId) => removeMember(currentTour.id, userId)}
          onMemberAdded={() => fetchTour(currentTour.id)}
          userRole={userRole || undefined}
          isPublicView={isPublicView} // Pass isPublicView
        />
      )}

      {/* Add Location Modal */}
      {currentTour && (
        <AddLocationModal 
          isOpen={isAddLocationOpen} 
          onClose={() => setIsAddLocationOpen(false)} 
          initialLegId={targetLegId || undefined}
          isStartPoint={isStartPointAction}
          isEndPoint={isEndPointAction}
          editingLocation={editingLocation}
          tourId={currentTour.id} 
          isPublicView={isPublicView} // Pass isPublicView
          onSuccess={() => {
            console.log("TourDetailPage: AddLocationModal onSuccess -> Re-fetching tour data.");
            fetchTour(tourId); // Re-fetch tour data after adding/editing location
          }}
        />
      )}

      {/* Add Photo Modal */}
      {currentTour && (
        <AddPhotoModal
          isOpen={isAddPhotoOpen}
          onClose={() => setIsAddPhotoOpen(false)}
          tourId={currentTour.id}
          onSuccess={() => fetchTour(currentTour.id)}
          isPublicView={isPublicView}
        />
      )}

      {/* Quick Note Modal */}
      {quickNoteLocName && (
        <div className="fixed inset-0 z-[4000] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={() => setQuickNoteLocName(null)} />
          <div className="relative w-full max-w-md bg-white rounded-[32px] shadow-2xl p-8 animate-in zoom-in-95 duration-200">
            <div className="flex justify-between items-center mb-6">
              <h3 className="text-xl font-black text-gray-900">Ghi chú nhanh</h3>
              <button onClick={() => setQuickNoteLocName(null)} className="p-2 hover:bg-gray-100 rounded-full transition-colors">
                <X className="w-5 h-5 text-gray-400" />
              </button>
            </div>
            
            <div className="space-y-4">
              <p className="text-sm font-bold text-gray-700">
                📍 Địa điểm: <span className="text-blue-600">{quickNoteLocName}</span>
              </p>
              
              <div>
                <label className="block text-xs font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Nội dung ghi chú</label>
                <textarea
                  value={quickNoteInput}
                  onChange={(e) => setQuickNoteInput(e.target.value)}
                  placeholder="Nhập nội dung ghi chú nhanh..."
                  className="w-full px-5 py-4 bg-gray-50 border border-gray-100 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-sm min-h-[120px] resize-none"
                  autoFocus
                />
              </div>
            </div>

            <div className="grid grid-cols-2 gap-3 mt-8">
              <button
                onClick={() => setQuickNoteLocName(null)}
                className="py-4 bg-gray-100 hover:bg-gray-200 text-gray-600 font-bold rounded-2xl transition-all active:scale-95"
              >
                Hủy
              </button>
              <button
                onClick={submitQuickNote}
                disabled={!quickNoteInput.trim()}
                className="py-4 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none text-white font-bold rounded-2xl shadow-lg shadow-blue-100 transition-all active:scale-95"
              >
                Lưu
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Member Detail Popover */}
      {isMemberDetailOpen && selectedMember && (
        <div className="fixed inset-0 z-[2100] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm" onClick={() => setIsMemberDetailOpen(false)} />
          <div className="relative w-full max-w-sm bg-white rounded-2xl shadow-2xl p-5">
            <div className="flex items-center gap-3">
              <div className="w-12 h-12 rounded-full bg-blue-100 border border-blue-200 flex items-center justify-center text-blue-700 font-bold">
                {selectedMember.user?.name?.charAt(0) || selectedMember.displayName?.charAt(0) || '?'}
              </div>
              <div>
                <div className="text-base font-bold text-gray-900">{selectedMember.user?.name || selectedMember.displayName || 'Chưa đặt tên'}</div>
                <div className="text-xs text-gray-500">{selectedMember.user?.email || 'Thành viên ngoài hệ thống'}</div>
                <div className="text-[10px] font-semibold text-gray-500">{selectedMember.role}</div>
              </div>
            </div>
            {(selectedMember.user?.phone || selectedMember.user?.address) && (
              <div className="mt-3 text-xs text-gray-600 space-y-1">
                {selectedMember.user?.phone && <div>📞 {selectedMember.user.phone}</div>}
                {selectedMember.user?.address && <div>📍 {selectedMember.user.address}</div>}
              </div>
            )}
            <div className="mt-4 flex justify-end gap-2">
              <button onClick={() => setIsMemberDetailOpen(false)} className="px-3 py-2 rounded-xl text-sm font-bold text-gray-600 hover:bg-gray-100">Đóng</button>
              
              {!isPublicView && currentUser && selectedMember && (selectedMember.userId || selectedMember.user?.id) && currentUser.id !== (selectedMember.userId || selectedMember.user?.id) && (selectedMember.role === 'OWNER' || selectedMember.role === 'MANAGER') && (
                <button
                  onClick={() => {
                    setIsMemberDetailOpen(false);
                    setRatingTargetUser(selectedMember);
                    setIsRatingModalOpen(true);
                  }}
                  className="px-3 py-2 bg-amber-500 hover:bg-amber-600 text-white rounded-xl text-sm font-bold flex items-center gap-1 shadow-md transition-all active:scale-95"
                >
                  ⭐ {t('rateOrganizer') || 'Đánh giá'}
                </button>
              )}

              {canEdit && selectedMember.role !== 'OWNER' && (
                <button
                  onClick={async () => {
                    if (!currentTour || !selectedMember) return;
                    try {
                      await removeMember(currentTour.id, selectedMember.userId || selectedMember.id);
                      setIsMemberDetailOpen(false);
                    } catch (e) {
                        notify({ title: 'Thông báo', message: 'Không thể xóa thành viên', type: 'error' });
                    }
                  }}
                  className="px-3 py-2 bg-red-600 hover:bg-red-700 text-white rounded-xl text-sm font-bold"
                >
                  Xóa
                </button>
              )}
              {canEdit && selectedMember.role === 'OWNER' && (
                <button
                  onClick={() => {
                    setIsMemberDetailOpen(false);
                    setIsAddMemberOpen(true);
                  }}
                  className="px-3 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-xl text-sm font-bold"
                >
                  Mời thêm người
                </button>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Organizer Rating Modal */}
      {isRatingModalOpen && ratingTargetUser && (
        <div className="fixed inset-0 z-[2500] flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in" onClick={() => setIsRatingModalOpen(false)} />
          <div className="relative w-full max-w-lg bg-white dark:bg-slate-900 rounded-[32px] shadow-2xl p-8 max-h-[90vh] overflow-y-auto flex flex-col animate-in zoom-in-95 duration-250 text-slate-800 dark:text-slate-100 border dark:border-slate-800">
            <div className="flex justify-between items-center mb-6">
              <h3 className="text-xl font-black text-slate-950 dark:text-white flex items-center gap-2">
                ⭐ {t('rateTitle') || 'Đánh giá Người tạo Tour'}
              </h3>
              <button onClick={() => setIsRatingModalOpen(false)} className="p-2 hover:bg-gray-150 dark:hover:bg-slate-850 rounded-full transition-colors">
                <X className="w-5 h-5 text-gray-400" />
              </button>
            </div>

            <div className="flex items-center gap-3 mb-6 bg-slate-50 dark:bg-slate-850 p-4 rounded-2xl border border-slate-100 dark:border-slate-800">
              <div className="w-12 h-12 rounded-full bg-blue-100 border border-blue-200 flex items-center justify-center text-blue-700 font-bold overflow-hidden">
                {ratingTargetUser.avatar ? (
                  <img src={ratingTargetUser.avatar} alt="Avatar" className="w-full h-full object-cover" />
                ) : (
                  <span>{ratingTargetUser.user?.name?.charAt(0) || ratingTargetUser.displayName?.charAt(0) || '?'}</span>
                )}
              </div>
              <div>
                <div className="text-sm font-black dark:text-white">{ratingTargetUser.user?.name || ratingTargetUser.displayName}</div>
                <div className="text-xs text-gray-450 uppercase tracking-widest font-bold">{ratingTargetUser.role}</div>
              </div>
            </div>

            <div className="space-y-4 flex-1">
              {[
                { key: 'honesty', label: t('honesty') || 'Trung thực' },
                { key: 'transparency', label: t('transparency') || 'Minh bạch' },
                { key: 'enthusiasm', label: t('enthusiasm') || 'Nhiệt tình' },
                { key: 'cheerfulness', label: t('cheerfulness') || 'Vui vẻ' },
                { key: 'seriousness', label: t('seriousness') || 'Nghiêm túc' },
                { key: 'planning', label: t('planning') || 'Có kế hoạch' },
                { key: 'survival', label: t('survival') || 'Kỹ năng sinh tồn' }
              ].map((c) => (
                <div key={c.key} className="flex items-center justify-between border-b border-slate-100 dark:border-slate-850 pb-2">
                  <span className="text-xs font-bold text-slate-700 dark:text-slate-350">{c.label}</span>
                  <div className="flex gap-1">
                    {[1, 2, 3, 4, 5].map((star) => {
                      const currentVal = (ratingScores as any)[c.key];
                      return (
                        <button
                          key={star}
                          type="button"
                          onClick={() => setRatingScores(prev => ({ ...prev, [c.key]: star }))}
                          className={`w-6 h-6 text-xl transition-all active:scale-95 ${
                            star <= currentVal ? 'text-amber-450' : 'text-gray-300 dark:text-gray-700 hover:text-amber-300'
                          }`}
                        >
                          ★
                        </button>
                      );
                    })}
                  </div>
                </div>
              ))}

              <div className="mt-4">
                <label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Nhận xét khác</label>
                <textarea
                  value={ratingComment}
                  onChange={(e) => setRatingComment(e.target.value)}
                  placeholder={t('rateCommentPlaceholder') || 'Nhập ý kiến đánh giá khác...'}
                  rows={3}
                  className="w-full px-4 py-3 bg-gray-50 dark:bg-slate-850 border border-gray-200 dark:border-slate-800 rounded-2xl focus:ring-2 focus:ring-blue-500 outline-none transition-all text-xs resize-none text-slate-900 dark:text-white"
                />
              </div>
            </div>

            <div className="grid grid-cols-2 gap-3 mt-6">
              <button
                type="button"
                onClick={() => setIsRatingModalOpen(false)}
                className="py-3.5 bg-gray-100 dark:bg-slate-800 hover:bg-gray-250 dark:hover:bg-slate-700 text-gray-600 dark:text-slate-300 font-bold rounded-2xl transition-all active:scale-95 text-xs"
              >
                {t('cancel') || 'Hủy'}
              </button>
              <button
                type="button"
                onClick={handleSubmitRating}
                disabled={isSubmittingRating}
                className="py-3.5 bg-amber-500 hover:bg-amber-600 disabled:opacity-50 text-white font-bold rounded-2xl shadow-lg transition-all active:scale-95 text-xs flex items-center justify-center gap-1.5"
              >
                {isSubmittingRating ? (
                  <Loader2 className="w-4.5 h-4.5 animate-spin" />
                ) : (
                  <>
                    <span>{t('save') || 'Gửi đánh giá'}</span>
                  </>
                )}
              </button>
            </div>
          </div>
        </div>
      )}
      <CommentModal
        isOpen={isCommentModalOpen}
        onClose={() => setIsCommentModalOpen(false)}
        locationId={commentLocationId}
        locationName={commentLocationName}
        isPublicView={isPublicView} // Pass isPublicView
        onCommentAdded={() => handleCommentIncrement(commentLocationId)}
        onCommentDeleted={() => handleCommentDecrement(commentLocationId)}
      />
      <CoordinateSelectModal
        isOpen={isMapOpen}
        onClose={() => setIsMapOpen(false)}
        initialLat={typeof editPhotoLat === 'number' ? editPhotoLat : undefined}
        initialLng={typeof editPhotoLng === 'number' ? editPhotoLng : undefined}
        onSelect={(lat, lng) => {
          setEditPhotoLat(lat);
          setEditPhotoLng(lng);
        }}
      />

      {isFullscreen && selectedPhotoForDisplay && (
        <div
          className="fixed inset-0 z-[9999] bg-black/95 flex items-center justify-center cursor-zoom-out animate-in fade-in duration-200"
          onClick={() => setIsFullscreen(false)}
        >
          <button
            onClick={() => setIsFullscreen(false)}
            className="fixed top-6 right-6 p-3 bg-black/50 hover:bg-black/75 border border-white/10 rounded-full text-white transition-colors z-[10000]"
          >
            <X className="w-6 h-6" />
          </button>
          <img
            src={selectedPhotoForDisplay.imageUrl}
            alt="Fullscreen photo"
            className="max-w-full max-h-full object-contain select-none animate-in zoom-in-95 duration-200"
          />
        </div>
      )}
    </div>
  );
};