
// ProfessionalFlow.jsx — Search → Quick-Book → SIS Verification → Time Slot → Confirmation → MisReservas / CancelacionFlow

// ── Slot formatting helper ────────────────────────────────────────────────────
const fmtSlot = (slot) => {
  const h = parseInt(slot, 10);
  const start = h.toString().padStart(2, '0') + ':00';
  const end   = (h + 1).toString().padStart(2, '0') + ':00';
  return `${start} – ${end}`;
};

// ─── TEST MODE ────────────────────────────────────────────────────────────────
// Set to true to show "Simular pago exitoso" button in the payment step.
// Set to false (or remove) before deploying to production.
const TEST_MODE = true;

const MOCK_RESERVAS = [
  { id: 'LKT-A1B2C3', box: 'Box Dental Premium', address: 'Av. Apoquindo 4501, piso 3', fecha: new Date(Date.now() + 1000*60*60*2), slot: 10, monto: 9350, status: 'confirmed', medico: 'Dr. Carlos Muñoz' },
  { id: 'LKT-D4E5F6', box: 'Box Kinesiología', address: 'Av. Providencia 2124, of. 502', fecha: new Date(Date.now() + 1000*60*60*30), slot: 14, monto: 6600, status: 'confirmed', medico: 'Dra. Ana Torres' },
  { id: 'LKT-G7H8I9', box: 'Box Psicología', address: 'Av. Irarrázaval 1890, of. 201', fecha: new Date(Date.now() - 1000*60*60*48), slot: 9, monto: 4950, status: 'completed', medico: 'Dr. Pedro Soto' },
];

const BOXES = [
  {
    id: 1, name: 'Box Dental Premium', location: 'Las Condes', address: 'Av. Apoquindo 4501, piso 3',
    price: 8500, rating: 4.9, reviews: 124, available: true,
    equip: ['Unidad Dental', 'PC Clínico', 'Lavamanos', 'Compresor'],
    tags: ['Dental'], img: null,
    owner: 'Clínica Sonrisa',
  },
  {
    id: 2, name: 'Box Kinesiología', location: 'Providencia', address: 'Av. Providencia 2124, of. 502',
    price: 6000, rating: 4.7, reviews: 88, available: true,
    equip: ['Camilla Eléctrica', 'PC Clínico', 'Lavamanos'],
    tags: ['Kinesiología'], img: null,
    owner: 'Centro Rehabilita',
  },
  {
    id: 3, name: 'Box Psicología', location: 'Ñuñoa', address: 'Av. Irarrázaval 1890, of. 201',
    price: 4500, rating: 4.8, reviews: 56, available: false,
    equip: ['PC Clínico', 'Sillones', 'Climatización'],
    tags: ['Psicología'], img: null,
    owner: 'Espacio Mental',
  },
  {
    id: 4, name: 'Box Medicina General', location: 'Santiago Centro', address: 'Huérfanos 835, of. 310',
    price: 5500, rating: 4.6, reviews: 200, available: true,
    equip: ['Camilla', 'PC Clínico', 'Lavamanos', 'Estetoscopio'],
    tags: ['Medicina General'], img: null,
    owner: 'MedCenter SpA',
  },
];

const EQUIP_ICONS = {
  'Unidad Dental': '🦷',
  'PC Clínico': '💻',
  'Lavamanos': '🚿',
  'Compresor': '⚙️',
  'Camilla Eléctrica': '🛏️',
  'Camilla': '🛏️',
  'Sillones': '🪑',
  'Climatización': '❄️',
  'Estetoscopio': '🩺',
};

// ─── PROFESSIONAL HEADER (Reusable) ────────────────────────────────────────
const ProfessionalHeader = ({ screenName, onLogout, onBack }) => {
  const userJson = localStorage.getItem('lokat_user');
  const user = userJson ? JSON.parse(userJson) : null;
  const fullName = user?.fullName || user?.full_name || user?.email || 'Usuario';
  const userInitials = fullName.split(' ').map(n => n[0]).join('').toUpperCase().substring(0, 2);
  const firstName = fullName.split(' ')[0];
  const rnpiVerified = user?.rnpi_declared === true;

  return (
    <div style={{background: '#fff', borderBottom: '1px solid #f0f0f0', padding: '0 20px', height: 60, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, position: 'sticky', top: 0, zIndex: 50}}>
      {/* Left: Back Button + Logo */}
      <div style={{display: 'flex', alignItems: 'center', gap: 10, flexShrink: 0}}>
        {onBack && (
          <button
            onClick={onBack}
            title="Atrás"
            style={{background: 'none', border: '1px solid #e9ecef', color: '#636e72', padding: '6px 8px', borderRadius: 6, cursor: 'pointer', fontFamily: 'inherit', display: 'flex', alignItems: 'center', justifyContent: 'center', lineHeight: 1}}
          >
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg>
          </button>
        )}
        <div style={{fontSize: 15, fontWeight: 700, color: '#1a1d23', letterSpacing: '-0.3px'}}>LOKAT</div>
        <div style={{fontSize: 13, color: '#adb5bd', fontWeight: 400}}>/</div>
        <div style={{fontSize: 13, fontWeight: 500, color: '#636e72'}}>{screenName}</div>
      </div>

      {/* Right: User Avatar + Name + Logout */}
      <div style={{display: 'flex', alignItems: 'center', gap: 12, flexShrink: 0}}>
        <div style={{display: 'flex', alignItems: 'center', gap: 8}}>
          <div style={{width: 32, height: 32, background: '#1a1d23', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, fontWeight: 600, color: '#fff'}}>
            {userInitials}
          </div>
          <div>
            <div style={{fontSize: 13, fontWeight: 600, color: '#2D3436'}}>{firstName}</div>
            {rnpiVerified && (
              <div style={{fontSize: 10, fontWeight: 600, color: '#27ae60', letterSpacing: 0.3}}>Verificado RNPI ✓</div>
            )}
          </div>
        </div>
        <button
          onClick={onLogout}
          title="Cerrar sesión"
          style={{background: 'none', border: 'none', color: '#adb5bd', padding: '6px 4px', borderRadius: 6, fontSize: 12, fontWeight: 500, cursor: 'pointer', fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 4}}
        >
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/></svg>
          Salir
        </button>
      </div>
    </div>
  );
};

// ─── LEAFLET LOADER ──────────────────────────────────────────────────────────
const useLeaflet = () => {
  const [ready, setReady] = React.useState(!!window.L);
  React.useEffect(() => {
    if (window.L) { setReady(true); return; }
    if (!document.getElementById('leaflet-css')) {
      const link = document.createElement('link');
      link.id = 'leaflet-css';
      link.rel = 'stylesheet';
      link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
      document.head.appendChild(link);
    }
    if (!document.getElementById('leaflet-js')) {
      const script = document.createElement('script');
      script.id = 'leaflet-js';
      script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
      script.onload = () => setReady(true);
      document.head.appendChild(script);
    } else {
      // Script tag exists but may still be loading
      const existing = document.getElementById('leaflet-js');
      existing.addEventListener('load', () => setReady(true));
    }
  }, []);
  return ready;
};

// ─── BOX MAP helpers (module-level, no React deps) ───────────────────────────
const _mapBadgeHtml = (key, priceLabel, count, isActive) =>
  `<div data-key="${key}" style="
    display:inline-block;
    transform:translate(-50%,-100%);
    background:${isActive ? '#1a1d23' : '#fff'};
    color:${isActive ? '#fff' : '#1a1d23'};
    border:2px solid #1a1d23;
    border-radius:20px;
    padding:5px 11px;
    font-size:13px;
    font-weight:700;
    font-family:system-ui,-apple-system,sans-serif;
    white-space:nowrap;
    box-shadow:0 2px 10px rgba(0,0,0,${isActive ? '0.28' : '0.16'});
    cursor:pointer;
    line-height:1.2;
    transition:all 0.15s;
  ">${priceLabel}${count > 1 ? `<span style="font-size:10px;margin-left:4px;opacity:0.65">(${count})</span>` : ''}</div>`;

const _mapSinglePopup = (box) => {
  const ok = box.available !== false;
  return `<div style="min-width:220px;max-width:260px;font-family:system-ui,sans-serif;line-height:1.5;padding:2px 0">
    <div style="font-size:15px;font-weight:700;margin-bottom:3px;color:#1a1d23">${box.name}</div>
    ${box.tags?.[0] ? `<div style="font-size:11px;color:#636e72;margin-bottom:6px;text-transform:uppercase;letter-spacing:0.3px">${box.tags[0]}</div>` : ''}
    <div style="font-size:16px;font-weight:700;color:#1a1d23;margin-bottom:5px">$${box.price.toLocaleString('es-CL')}<span style="font-weight:400;font-size:12px;color:#adb5bd"> /hora</span></div>
    <div style="font-size:11px;color:#adb5bd;margin-bottom:9px">${box.address}</div>
    <div style="display:inline-block;font-size:11px;font-weight:600;margin-bottom:10px;padding:3px 8px;border-radius:5px;color:${ok ? '#155724' : '#721c24'};background:${ok ? '#d4edda' : '#f8d7da'}">${ok ? '● Disponible hoy' : '● No disponible'}</div>
    <button class="lokat-map-btn" data-id="${box.id}" data-available="${ok}"
      style="display:block;width:100%;background:${ok ? '#1a1d23' : '#f0f0f0'};color:${ok ? '#fff' : '#adb5bd'};border:none;border-radius:8px;padding:9px 0;font-size:13px;font-weight:700;cursor:${ok ? 'pointer' : 'default'};font-family:system-ui,sans-serif;margin-top:2px">
      ${ok ? 'Reservar →' : 'Ver agenda'}
    </button>
  </div>`;
};

const _mapMultiPopup = (items) => {
  const rows = items.map(({ box }) => {
    const ok = box.available !== false;
    return `<div style="display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid #f4f5f7">
      <div style="flex:1;min-width:0">
        <div style="font-size:13px;font-weight:700;color:#1a1d23;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${box.name}</div>
        ${box.tags?.[0] ? `<div style="font-size:11px;color:#adb5bd">${box.tags[0]}</div>` : ''}
        <div style="font-size:13px;font-weight:700;color:#1a1d23">$${box.price.toLocaleString('es-CL')}<span style="font-weight:400;font-size:11px;color:#adb5bd"> /h</span></div>
      </div>
      <button class="lokat-map-btn" data-id="${box.id}" data-available="${ok}"
        style="flex-shrink:0;background:${ok ? '#1a1d23' : '#f0f0f0'};color:${ok ? '#fff' : '#adb5bd'};border:none;border-radius:8px;padding:7px 12px;font-size:12px;font-weight:700;cursor:${ok ? 'pointer' : 'default'};font-family:system-ui,sans-serif;white-space:nowrap">
        Ver box →
      </button>
    </div>`;
  }).join('');
  return `<div style="min-width:260px;max-width:300px;font-family:system-ui,sans-serif;padding:2px 0">
    <div style="font-size:11px;font-weight:700;color:#adb5bd;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px">${items.length} boxes en esta ubicación</div>
    <div style="max-height:260px;overflow-y:auto">${rows}</div>
  </div>`;
};

// ─── BOX MAP ──────────────────────────────────────────────────────────────────
const BoxMap = ({ geocoded, onSelect, onHighlight }) => {
  const mapRef         = React.useRef(null);
  const instanceRef    = React.useRef(null);
  const markersRef     = React.useRef([]); // [{ key, marker, priceLabel, itemCount }]
  const [activeKey, setActiveKey] = React.useState(null);
  const activeKeyRef   = React.useRef(null);
  // Keep a stable ref to onHighlight so effects don't re-run when the callback identity changes
  const onHighlightRef = React.useRef(onHighlight);
  React.useEffect(() => { onHighlightRef.current = onHighlight; }, [onHighlight]);

  // Group geocoded items by rounded coordinates → one marker per location
  const groups = React.useMemo(() => {
    const map = new Map();
    geocoded.forEach(item => {
      const key = `${item.lat.toFixed(4)},${item.lng.toFixed(4)}`;
      if (!map.has(key)) map.set(key, { key, lat: item.lat, lng: item.lng, items: [] });
      map.get(key).items.push(item);
    });
    return [...map.values()];
  }, [geocoded]);

  // ── Init map once ──────────────────────────────────────────────────────────
  React.useEffect(() => {
    if (!mapRef.current || instanceRef.current) return;
    const L = window.L;
    // Custom popup CSS (injected once)
    if (!document.getElementById('lokat-map-css')) {
      const s = document.createElement('style');
      s.id = 'lokat-map-css';
      s.textContent = `
        .lokat-popup .leaflet-popup-content-wrapper{border-radius:14px;padding:0;box-shadow:0 6px 28px rgba(0,0,0,0.16);border:none}
        .lokat-popup .leaflet-popup-content{margin:14px 16px}
        .lokat-popup .leaflet-popup-tip-container{display:none}
        .lokat-popup .leaflet-popup-close-button{top:8px;right:10px;color:#adb5bd;font-size:18px;font-weight:400}
        .lokat-popup .leaflet-popup-close-button:hover{color:#1a1d23}
      `;
      document.head.appendChild(s);
    }
    const map = L.map(mapRef.current, { scrollWheelZoom: true, zoomControl: true })
                 .setView([-33.45, -70.65], 12);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
      maxZoom: 19,
    }).addTo(map);
    // Deselect active marker when clicking blank map
    map.on('click', () => { setActiveKey(null); activeKeyRef.current = null; onHighlightRef.current?.([]); });
    instanceRef.current = map;
    return () => { map.remove(); instanceRef.current = null; };
  }, []);

  // ── Create/replace markers when geocoded groups change ─────────────────────
  React.useEffect(() => {
    const map = instanceRef.current;
    if (!map || !window.L) return;
    const L = window.L;

    markersRef.current.forEach(({ marker }) => map.removeLayer(marker));
    markersRef.current = [];

    const bounds = [];
    groups.forEach(({ key, lat, lng, items }) => {
      const minPrice   = Math.min(...items.map(i => i.box.price));
      const priceLabel = `$${minPrice.toLocaleString('es-CL')}`;
      const isActive   = activeKeyRef.current === key;

      const makeIcon = (active) => L.divIcon({
        html:       _mapBadgeHtml(key, priceLabel, items.length, active),
        className:  '',
        iconSize:   [0, 0],
        iconAnchor: [0, 0],
      });

      const popup = L.popup({ minWidth: 240, maxWidth: 310, closeButton: true, className: 'lokat-popup' })
                     .setContent(items.length === 1 ? _mapSinglePopup(items[0].box) : _mapMultiPopup(items));

      const marker = L.marker([lat, lng], { icon: makeIcon(isActive) })
                      .bindPopup(popup)
                      .addTo(map);

      marker.on('click', () => {
        setActiveKey(key);
        activeKeyRef.current = key;
        onHighlightRef.current?.(items.map(i => i.box.id));
      });

      markersRef.current.push({ key, marker, priceLabel, itemCount: items.length });
      bounds.push([lat, lng]);
    });

    if (bounds.length > 1)      map.fitBounds(bounds, { padding: [60, 60], maxZoom: 14 });
    else if (bounds.length === 1) map.setView(bounds[0], 15);
  }, [groups]); // eslint-disable-line react-hooks/exhaustive-deps

  // ── Update badge style when active marker changes (no marker recreation) ──
  React.useEffect(() => {
    if (!window.L) return;
    const L = window.L;
    markersRef.current.forEach(({ key, marker, priceLabel, itemCount }) => {
      marker.setIcon(L.divIcon({
        html:       _mapBadgeHtml(key, priceLabel, itemCount, activeKey === key),
        className:  '',
        iconSize:   [0, 0],
        iconAnchor: [0, 0],
      }));
    });
  }, [activeKey]);

  // ── Wire up button clicks each time a popup opens ─────────────────────────
  React.useEffect(() => {
    const map = instanceRef.current;
    if (!map) return;
    const handler = (e) => {
      const el = e.popup.getElement();
      if (!el) return;
      el.querySelectorAll('.lokat-map-btn').forEach(btn => {
        btn.onclick = () => {
          if (btn.dataset.available === 'false') return;
          const found = geocoded.find(g => String(g.box.id) === btn.dataset.id);
          if (found) onSelect(found.box);
        };
      });
    };
    map.on('popupopen', handler);
    return () => map.off('popupopen', handler);
  }, [geocoded, onSelect]);

  return <div ref={mapRef} style={{ height: '100%', width: '100%' }} />;
};

// ─── SEARCH RESULTS ─────────────────────────────────────────────────────────
const SearchResults = ({ onSelect, onBack, isLoggedIn, onMisReservas }) => {
  const [boxes, setBoxes] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  const [filter, setFilter] = React.useState('Todos');
  const [filterResolution, setFilterResolution] = React.useState('Todas');
  const [sortBy, setSortBy] = React.useState('precio');
  const [search, setSearch] = React.useState('');
  const filters = ['Todos', 'Dental', 'Odontología', 'Kinesiología', 'Psicología', 'Medicina General', 'Dermatología'];
  const resolutionFilters = ['Todas', 'Solo consulta', 'Procedimientos invasivos', 'Dental/Radiología', 'Sin resolución sanitaria'];
  const isMobile = useWindowWidth() <= 768;

  // ── Map state ──────────────────────────────────────────────────────────────
  const leafletReady  = useLeaflet();
  const [mapView,     setMapView]   = React.useState(false);
  const [geocoded,    setGeocoded]  = React.useState([]);   // [{ box, lat, lng }]
  const [geocoding,   setGeocoding] = React.useState(false);
  const geocodedIds   = React.useRef(new Set());

  const geocodeBoxes = React.useCallback(async (toGeocode) => {
    if (!toGeocode.length) return;
    setGeocoding(true);
    const results = [];

    // Helper: strip apartment/office/floor details from an address string
    const simplifyAddress = (addr) =>
      addr
        .replace(/,?\s*(oficina|of\.|depto\.?|departamento|piso|local|suite|torre|block|bl\.?|bodega)\s*[\w\d-]+/gi, '')
        .replace(/,\s*,/g, ',')   // collapse double commas left by removal
        .replace(/,\s*$/,  '')    // trailing comma
        .trim();

    // Helper: fetch one Nominatim query, returns first result or null
    const nominatim = async (queryStr) => {
      const res  = await fetch(
        `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(queryStr)}&format=json&limit=1`,
        { headers: { 'Accept-Language': 'es' } }
      );
      const data = await res.json();
      return data[0] || null;
    };

    for (const box of toGeocode) {
      if (geocodedIds.current.has(box.id)) continue;
      geocodedIds.current.add(box.id);
      try {
        await new Promise(r => setTimeout(r, 250)); // respect Nominatim rate limit

        // First attempt: full address
        let hit = await nominatim(box.address + ', Chile');

        // Second attempt: simplified address (no office/floor/apt info)
        if (!hit) {
          const simplified = simplifyAddress(box.address);
          if (simplified !== box.address) {
            console.log('[MAP] Retrying with simplified address:', simplified);
            await new Promise(r => setTimeout(r, 250)); // rate-limit delay for retry
            hit = await nominatim(simplified + ', Chile');
          }
        }

        if (hit) {
          results.push({ box, lat: parseFloat(hit.lat), lng: parseFloat(hit.lon) });
        } else {
          console.warn('[MAP] No coordinates found for:', box.address);
        }
      } catch (err) {
        geocodedIds.current.delete(box.id); // allow retry
        console.error('[MAP] Geocode error:', box.address, err.message);
      }
    }

    // ── Post-process: offset any markers that share identical coordinates ──
    // Group results by rounded coord key, then shift duplicates so all are visible.
    const coordGroups = new Map(); // "lat,lng" -> [indices into results]
    results.forEach(({ lat, lng }, i) => {
      const key = `${lat.toFixed(5)},${lng.toFixed(5)}`;
      if (!coordGroups.has(key)) coordGroups.set(key, []);
      coordGroups.get(key).push(i);
    });
    coordGroups.forEach((indices) => {
      if (indices.length < 2) return; // no clash, nothing to do
      indices.forEach((idx, dupIndex) => {
        results[idx].lat += 0.0002 * dupIndex;
        results[idx].lng += 0.0002 * dupIndex;
      });
    });

    setGeocoded(prev => [...prev, ...results]);
    setGeocoding(false);
  }, []);

  const handleToggleMap = () => {
    if (!mapView) {
      // Only geocode boxes that pass the current filters
      const notYet = filtered.filter(b => !geocodedIds.current.has(b.id));
      geocodeBoxes(notYet);
    }
    setMapView(v => !v);
  };

  React.useEffect(() => {
    const fetchBoxes = async () => {
      try {
        setLoading(true);
        const response = await fetch('https://lokat.fly.dev/api/boxes');
        if (!response.ok) {
          throw new Error(`API error: ${response.status}`);
        }
        const data = await response.json();

        // Map API response to UI format
        const mappedBoxes = data.map(box => ({
          id: box.id,
          name: box.name,
          location: box.address.split(',')[0], // Extract first part of address
          address: box.address,
          price: box.price_per_slot,
          rating: 4.5 + Math.random() * 0.4, // Placeholder: 4.5-4.9
          reviews: Math.floor(50 + Math.random() * 200), // Placeholder: 50-250
          available: box.status === 'open',
          equip: ['PC Clínico', 'Lavamanos', 'Climatización'], // Placeholder
          tags: [box.specialty],
          resolution_type: box.resolution_type || null,
          images: Array.isArray(box.images) ? box.images : [],
          img: null,
          owner: box.owner_id,
          arrival_instructions: box.arrival_instructions || null,
          description:          box.description || null,
        }));

        setBoxes(mappedBoxes);
        setError(null);
      } catch (err) {
        console.error('Error fetching boxes:', err);
        setError(err.message);
        setBoxes([]);
      } finally {
        setLoading(false);
      }
    };

    fetchBoxes();
  }, []);

  // ── Detail view + map-highlight state ────────────────────────────────────
  // ⚠️ All hooks must appear before the early returns below
  const [highlightedIds, setHighlightedIds] = React.useState([]);
  const [detailBox,      setDetailBox]      = React.useState(null);
  const cardRefsMap = React.useRef({});

  // Called by BoxMap when a marker is clicked — highlights matching cards
  const handleHighlight = React.useCallback((ids) => {
    setHighlightedIds(ids);
  }, []);

  // Scroll the first highlighted card into view inside the left panel
  React.useEffect(() => {
    if (highlightedIds.length > 0) {
      const el = cardRefsMap.current[highlightedIds[0]];
      if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
    }
  }, [highlightedIds]);

  // Lock body scroll in desktop map mode so the split layout truly fills the viewport
  // ⚠️ Must be BEFORE any early returns so hooks are always called in the same order
  React.useEffect(() => {
    if (mapView && !isMobile) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }
    return () => { document.body.style.overflow = ''; };
  }, [mapView, isMobile]);

  // When filters change while map is open, geocode any newly-visible boxes
  // geocodeBoxes caches by id so already-geocoded boxes are skipped instantly
  React.useEffect(() => {
    if (!mapView) return;
    const notYet = filtered.filter(b => !geocodedIds.current.has(b.id));
    if (notYet.length > 0) geocodeBoxes(notYet);
  }, [filtered, mapView, geocodeBoxes]);

  const filtered = boxes.filter(b => {
    if (filter !== 'Todos' && !b.tags.includes(filter)) return false;
    if (filterResolution !== 'Todas' && b.resolution_type !== filterResolution) return false;
    if (search && !b.name.toLowerCase().includes(search.toLowerCase()) && !b.location.toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  }).sort((a, b) => sortBy === 'precio' ? a.price - b.price : b.rating - a.rating);

  // In map mode, float highlighted boxes to the top of the left panel
  const sortedPanel = highlightedIds.length === 0
    ? filtered
    : [...filtered.filter(b => highlightedIds.includes(b.id)), ...filtered.filter(b => !highlightedIds.includes(b.id))];

  // Only show map markers for boxes that match the current filters
  const filteredGeocoded = geocoded.filter(g => filtered.some(b => b.id === g.box.id));

  // Loading state
  if (loading) {
    return (
      <div style={pfStyles.page}>
        <div style={pfStyles.topBar}>
          <button style={pfStyles.backBtn} onClick={onBack}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg>
          </button>
          <div style={pfStyles.searchMini}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#636e72" strokeWidth="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
            <input style={pfStyles.searchMiniInput} placeholder="Buscar boxes..." disabled />
          </div>
          {isLoggedIn && (
            <>
              <button style={{...pfStyles.backBtn, fontSize: 13, fontWeight: 600, color: '#0984e3', background: '#e3f0fc', border: '1px solid #b8d8f5'}} onClick={onMisReservas} title="Ver mis reservas">📋 Mis Reservas</button>
              <button style={{...pfStyles.backBtn, fontSize: 13, fontWeight: 600, color: '#fff', background: '#c0392b', border: '1px solid #a93226'}} onClick={() => { localStorage.removeItem('lokat_token'); localStorage.removeItem('lokat_user'); onBack(); }} title="Cerrar sesión">🚪 Salir</button>
            </>
          )}
        </div>
        <div style={{textAlign: 'center', padding: '60px 24px', color: '#636e72'}}>
          <div style={{fontSize: 16, fontWeight: 600}}>Cargando boxes...</div>
          <div style={{fontSize: 13, marginTop: 8}}>Conectando con el servidor</div>
        </div>
      </div>
    );
  }

  // Error state
  if (error) {
    return (
      <div style={pfStyles.page}>
        <div style={pfStyles.topBar}>
          <button style={pfStyles.backBtn} onClick={onBack}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg>
          </button>
          <div style={pfStyles.topBarTitle}>Error al cargar</div>
          {isLoggedIn && (
            <>
              <button style={{...pfStyles.backBtn, fontSize: 13, fontWeight: 600, color: '#0984e3', background: '#e3f0fc', border: '1px solid #b8d8f5'}} onClick={onMisReservas} title="Ver mis reservas">📋 Mis Reservas</button>
              <button style={{...pfStyles.backBtn, fontSize: 13, fontWeight: 600, color: '#fff', background: '#c0392b', border: '1px solid #a93226'}} onClick={() => { localStorage.removeItem('lokat_token'); localStorage.removeItem('lokat_user'); onBack(); }} title="Cerrar sesión">🚪 Salir</button>
            </>
          )}
        </div>
        <div style={{textAlign: 'center', padding: '60px 24px', color: '#c0392b'}}>
          <div style={{fontSize: 48, marginBottom: 16}}>⚠️</div>
          <div style={{fontSize: 16, fontWeight: 600, marginBottom: 8}}>No se pudieron cargar los boxes</div>
          <div style={{fontSize: 13, color: '#636e72', marginBottom: 24}}>{error}</div>
          <button style={{...pfStyles.bookBtn, marginTop: 16}} onClick={() => window.location.reload()}>
            Intentar nuevamente
          </button>
        </div>
      </div>
    );
  }

  // Normal render with fetched boxes
  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onBack();
  };

  console.log('[LOKAT] SearchResults render — detailBox:', detailBox ? detailBox.id : null, '| mapView:', mapView);

  return (
    <React.Fragment>
    <div style={pfStyles.page}>
      {/* PROFESSIONAL HEADER */}
      <ProfessionalHeader screenName="Buscar Boxes" onLogout={handleLogout} onBack={onBack} />

      {/* SEARCH & SORT BAR */}
      <div style={{display:'flex', alignItems:'center', gap:'12px', padding:'12px 16px', background:'#fff', borderBottom:'1px solid #f0f0f0'}}>
        <input
          style={{flex:1, minWidth:0, padding:'8px 12px', border:'1px solid #e9ecef', borderRadius:8, fontSize:14, fontFamily:'inherit', color:'#2D3436', outline:'none', background:'#f8f9fa'}}
          placeholder="Buscar boxes..."
          value={search}
          onChange={e => setSearch(e.target.value)}
        />
        <button
          onClick={handleToggleMap}
          style={{whiteSpace:'nowrap', padding:'8px 14px', borderRadius:20, border:'1.5px solid', fontFamily:'inherit', fontSize:13, fontWeight:600, cursor:'pointer',
            background:  mapView ? '#1a1d23' : '#fff',
            color:       mapView ? '#fff'    : '#636e72',
            borderColor: mapView ? '#1a1d23' : '#dee2e6'}}
        >
          {mapView ? '☰ Ver lista' : '📍 Ver en mapa'}
        </button>
        <select style={pfStyles.sortSelect} value={sortBy} onChange={e => setSortBy(e.target.value)}>
          <option value="precio">Precio</option>
          <option value="rating">Rating</option>
        </select>
        {isLoggedIn && (
          <button style={{whiteSpace:'nowrap', padding:'8px 14px', borderRadius:8, border:'1px solid #b8d8f5', fontFamily:'inherit', fontSize:13, fontWeight:600, cursor:'pointer', background:'#e3f0fc', color:'#0984e3'}} onClick={onMisReservas}>
            Mis Reservas
          </button>
        )}
      </div>

      {/* FILTER PILLS — Specialty */}
      <div style={pfStyles.filterRow}>
        {filters.map(f => (
          <button key={f} style={{...pfStyles.filterPill, ...(filter === f ? pfStyles.filterPillActive : {})}} onClick={() => setFilter(f)}>{f}</button>
        ))}
      </div>

      {/* FILTER PILLS — Resolución sanitaria */}
      <div style={{...pfStyles.filterRow, paddingTop: 0}}>
        {resolutionFilters.map(f => (
          <button key={f} style={{...pfStyles.filterPill, ...(filterResolution === f ? pfStyles.filterPillActive : {}), fontSize: 11}} onClick={() => setFilterResolution(f)}>
            {f === 'Todas' ? '🏥 Todas las resoluciones' : f}
          </button>
        ))}
      </div>

      {/* RESULTS COUNT — list mode only */}
      {!mapView && (
        <div style={pfStyles.resultsCount}>
          {filtered.length} boxes encontrados
        </div>
      )}

      {/* SPLIT MAP VIEW — Airbnb style: list 40% left + map 60% right */}
      {mapView && (
        <div style={{display:'flex', height: isMobile ? 'auto' : 'calc(100vh - 240px)', overflow:'hidden', borderTop:'1px solid #ebebeb'}}>

          {/* Left panel: scrollable card list (hidden on mobile) */}
          {!isMobile && (
            <div style={{width:'40%', flexShrink:0, overflowY:'auto', background:'#f4f5f7', borderRight:'1px solid #ebebeb'}}>
              <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', padding:'10px 14px 6px', fontSize:12, color:'#adb5bd', borderBottom:'1px solid #f0f0f0', background:'#fff'}}>
                <span style={{fontWeight:600, color:'#636e72'}}>{filtered.length} boxes</span>
                {geocoding
                  ? <span>📍 Geocodificando…</span>
                  : <span>{filteredGeocoded.length} en el mapa</span>}
              </div>
              <div style={{padding:'12px 12px 32px', display:'flex', flexDirection:'column', gap:12}}>
                {sortedPanel.map(box => {
                  const isHighlighted = highlightedIds.includes(box.id);
                  return (
                    <div
                      key={box.id}
                      ref={el => { cardRefsMap.current[box.id] = el; }}
                      onClick={() => setDetailBox(box)}
                      style={{borderRadius:12, cursor:'pointer', outline: isHighlighted ? '2.5px solid #0984e3' : 'none', boxShadow: isHighlighted ? '0 4px 20px rgba(9,132,227,0.18)' : 'none', transition:'outline 0.15s, box-shadow 0.15s'}}
                    >
                      <QuickBookCard box={box} onSelect={onSelect} />
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* Right panel: map */}
          <div style={{flex:1, position:'relative', minHeight: isMobile ? 520 : 'auto'}}>
            {!leafletReady ? (
              <div style={{height:'100%', minHeight:400, display:'flex', alignItems:'center', justifyContent:'center', fontSize:14, color:'#636e72'}}>
                Cargando mapa…
              </div>
            ) : (
              <BoxMap geocoded={filteredGeocoded} onSelect={onSelect} onHighlight={handleHighlight} />
            )}
          </div>

        </div>
      )}

      {/* LIST VIEW */}
      {!mapView && (
        <div style={{...pfStyles.cardList, display:'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(2, 1fr)', gap:20}}>
          {filtered.map(box => (
            <div key={box.id} onClick={() => { console.log('[LOKAT] card clicked, id:', box.id); setDetailBox(box); }} style={{cursor:'pointer'}}>
              <QuickBookCard box={box} onSelect={() => setDetailBox(box)} />
            </div>
          ))}
        </div>
      )}

    </div>

    {/* BOX DETAIL MODAL — rendered as a sibling outside pfStyles.page so
        position:fixed is never clipped by the page's overflowX:hidden.
        Works in both list mode and map mode. */}
    {detailBox && (
      <BoxDetailModal
        box={detailBox}
        onClose={() => setDetailBox(null)}
        onBook={(b) => { setDetailBox(null); onSelect(b); }}
      />
    )}
  </React.Fragment>
  );
};

// ─── QUICK-BOOK CARD ─────────────────────────────────────────────────────────
const RESOLUTION_BADGE_STYLE = {
  'Solo consulta':            { background: '#e3f0fc', color: '#0984e3' },
  'Procedimientos invasivos': { background: '#fff3cd', color: '#856404' },
  'Dental/Radiología':        { background: '#f3e8ff', color: '#6f42c1' },
  'Sin resolución sanitaria': { background: '#f8f9fa', color: '#636e72' },
};

const QuickBookCard = ({ box, onSelect }) => {
  const [hovered, setHovered] = React.useState(false);

  return (
    <div
      style={{...pfStyles.card, ...(hovered ? pfStyles.cardHover : {})}}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
    >
      {/* COVER PHOTO */}
      <div style={pfStyles.cardImg}>
        {box.images && box.images.length > 0 ? (
          <img
            src={box.images[0]}
            alt={box.name}
            style={{width:'100%', height:'100%', objectFit:'cover', display:'block'}}
          />
        ) : (
          <div style={pfStyles.cardImgPlaceholder}>
            <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#adb5bd" strokeWidth="1.5"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
            <span style={pfStyles.cardImgLabel}>foto del box</span>
          </div>
        )}
        <div style={{...pfStyles.availBadge, background: box.available ? '#d4edda' : '#f8d7da', color: box.available ? '#155724' : '#721c24'}}>
          {box.available ? '● Disponible hoy' : '● No disponible'}
        </div>
        {box.images && box.images.length > 1 && (
          <div style={{position:'absolute', bottom:6, right:6, background:'rgba(0,0,0,0.55)', color:'#fff', fontSize:10, fontWeight:700, padding:'2px 7px', borderRadius:10}}>
            +{box.images.length - 1} fotos
          </div>
        )}
      </div>

      <div style={pfStyles.cardBody}>
        <div style={pfStyles.cardHeader}>
          <div>
            <div style={pfStyles.cardName}>{box.name}</div>
            <div style={pfStyles.cardLoc}>
              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#636e72" strokeWidth="2"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
              {box.location} · {box.address}
            </div>
          </div>
          <div style={pfStyles.cardPriceBlock}>
            <div style={pfStyles.cardPrice}>${box.price.toLocaleString()}</div>
            <div style={pfStyles.cardPriceLabel}>/hora</div>
          </div>
        </div>

        {/* EQUIPMENT ICONS */}
        <div style={pfStyles.equipRow}>
          {box.equip.map(e => (
            <span key={e} style={pfStyles.equipChip}>
              {EQUIP_ICONS[e] || '🔧'} {e}
            </span>
          ))}
        </div>

        {/* RESOLUTION BADGE */}
        {box.resolution_type && (
          <div style={{marginBottom: 8}}>
            <span style={{
              display: 'inline-block',
              fontSize: 11,
              fontWeight: 600,
              padding: '3px 8px',
              borderRadius: 6,
              ...(RESOLUTION_BADGE_STYLE[box.resolution_type] || { background: '#f8f9fa', color: '#636e72' }),
            }}>
              🏥 {box.resolution_type}
            </span>
          </div>
        )}

        {/* RATING + BOOK */}
        <div style={pfStyles.cardFooter}>
          <div style={pfStyles.ratingRow}>
            {(() => {
              const rounded = Math.round(box.rating * 2) / 2; // nearest 0.5
              return [1, 2, 3, 4, 5].map(i => (
                <span key={i} style={{fontSize: 15, color: i <= rounded ? '#f4b942' : '#dee2e6', lineHeight: 1}}>
                  {i <= rounded ? '★' : '☆'}
                </span>
              ));
            })()}
            <span style={{...pfStyles.ratingNum, marginLeft: 4}}>{Number(box.rating).toFixed(1)}</span>
            <span style={pfStyles.reviewCount}>({box.reviews} reseñas)</span>
          </div>
          <button
            style={{...pfStyles.bookBtn, ...(box.available ? {} : pfStyles.bookBtnDisabled)}}
            disabled={!box.available}
            onClick={e => { e.stopPropagation(); box.available && onSelect(box); }}
          >
            {box.available ? 'Reservar →' : 'Ver agenda'}
          </button>
        </div>
      </div>
    </div>
  );
};

// ─── BOX DETAIL MODAL (floating centered overlay) ────────────────────────────
const BoxDetailModal = ({ box, onClose, onBook }) => {
  const [imgIdx,      setImgIdx]      = React.useState(0);
  const [lightbox,    setLightbox]    = React.useState(false);
  console.log('BoxDetailModal box:', JSON.stringify(box));
  const hasImages = box.images && box.images.length > 0;
  const rounded   = Math.round((box.rating || 0) * 2) / 2;
  const available = box.available !== false;

  return (
    <React.Fragment>
    {/* ── Fullscreen lightbox ── */}
    {lightbox && hasImages && (
      <div
        onClick={() => setLightbox(false)}
        style={{position:'fixed', inset:0, zIndex:1600, background:'rgba(0,0,0,0.92)', display:'flex', alignItems:'center', justifyContent:'center', cursor:'zoom-out'}}
      >
        <img
          src={box.images[imgIdx]}
          alt={box.name}
          onClick={e => e.stopPropagation()}
          style={{maxWidth:'94vw', maxHeight:'90vh', objectFit:'contain', borderRadius:8, boxShadow:'0 8px 40px rgba(0,0,0,0.6)', cursor:'default'}}
        />
        <button
          onClick={() => setLightbox(false)}
          style={{position:'absolute', top:18, right:18, width:38, height:38, borderRadius:'50%', border:'none', background:'rgba(255,255,255,0.15)', color:'#fff', cursor:'pointer', fontSize:22, display:'flex', alignItems:'center', justifyContent:'center', lineHeight:1, fontFamily:'inherit', backdropFilter:'blur(4px)'}}
        >×</button>
        {box.images.length > 1 && (
          <>
            <button
              onClick={e => { e.stopPropagation(); setImgIdx(i => Math.max(0, i - 1)); }}
              style={{position:'absolute', left:16, top:'50%', transform:'translateY(-50%)', width:44, height:44, borderRadius:'50%', border:'none', background:'rgba(255,255,255,0.15)', color:'#fff', cursor:'pointer', fontSize:26, display:'flex', alignItems:'center', justifyContent:'center', backdropFilter:'blur(4px)', opacity: imgIdx === 0 ? 0.3 : 1}}
            >‹</button>
            <button
              onClick={e => { e.stopPropagation(); setImgIdx(i => Math.min(box.images.length - 1, i + 1)); }}
              style={{position:'absolute', right:16, top:'50%', transform:'translateY(-50%)', width:44, height:44, borderRadius:'50%', border:'none', background:'rgba(255,255,255,0.15)', color:'#fff', cursor:'pointer', fontSize:26, display:'flex', alignItems:'center', justifyContent:'center', backdropFilter:'blur(4px)', opacity: imgIdx === box.images.length - 1 ? 0.3 : 1}}
            >›</button>
            <div style={{position:'absolute', bottom:20, left:'50%', transform:'translateX(-50%)', background:'rgba(0,0,0,0.5)', color:'#fff', fontSize:13, fontWeight:600, padding:'4px 14px', borderRadius:20}}>
              {imgIdx + 1} / {box.images.length}
            </div>
          </>
        )}
      </div>
    )}

    {/* ── Modal backdrop ── */}
    <div
      onClick={e => { if (e.target === e.currentTarget) onClose(); }}
      style={{position:'fixed', inset:0, zIndex:1500, background:'rgba(0,0,0,0.48)', display:'flex', alignItems:'center', justifyContent:'center', padding:'20px', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif"}}
    >
      {/* Floating card */}
      <div style={{background:'#fff', borderRadius:16, width:'100%', maxWidth:560, maxHeight:'86vh', overflow:'hidden', display:'flex', flexDirection:'column', boxShadow:'0 24px 64px rgba(0,0,0,0.28)', position:'relative', zIndex:1501}}>

        {/* × close button over photo */}
        <button
          onClick={onClose}
          style={{position:'absolute', top:12, right:12, zIndex:10, width:30, height:30, borderRadius:'50%', border:'none', background:'rgba(0,0,0,0.42)', color:'#fff', cursor:'pointer', fontSize:20, display:'flex', alignItems:'center', justifyContent:'center', lineHeight:1, fontFamily:'inherit'}}
        >×</button>

        {/* Photo carousel */}
        <div style={{height:250, background:'#f0f4f8', position:'relative', flexShrink:0, overflow:'hidden'}}>
          {hasImages ? (
            <>
              {/* Clickable image → opens lightbox */}
              <img
                src={box.images[imgIdx]}
                alt={box.name}
                onClick={() => setLightbox(true)}
                style={{width:'100%', height:'100%', objectFit:'cover', display:'block', cursor:'zoom-in'}}
              />
              {/* Always-visible counter */}
              {box.images.length > 1 && (
                <div style={{position:'absolute', bottom:10, right:10, background:'rgba(0,0,0,0.55)', color:'#fff', fontSize:11, fontWeight:700, padding:'3px 9px', borderRadius:10, pointerEvents:'none'}}>
                  {imgIdx + 1} / {box.images.length}
                </div>
              )}
              {/* Carousel arrows — shown whenever there are multiple images */}
              {box.images.length > 1 && (
                <div style={{position:'absolute', inset:0, display:'flex', alignItems:'center', justifyContent:'space-between', padding:'0 10px', pointerEvents:'none'}}>
                  <button
                    onClick={e => { e.stopPropagation(); setImgIdx(i => Math.max(0, i - 1)); }}
                    style={{pointerEvents:'all', background:'rgba(255,255,255,0.92)', border:'none', borderRadius:'50%', width:34, height:34, cursor:'pointer', fontSize:22, display:'flex', alignItems:'center', justifyContent:'center', boxShadow:'0 2px 8px rgba(0,0,0,0.18)', opacity: imgIdx === 0 ? 0.35 : 1, transition:'opacity 0.15s'}}
                  >‹</button>
                  <button
                    onClick={e => { e.stopPropagation(); setImgIdx(i => Math.min(box.images.length - 1, i + 1)); }}
                    style={{pointerEvents:'all', background:'rgba(255,255,255,0.92)', border:'none', borderRadius:'50%', width:34, height:34, cursor:'pointer', fontSize:22, display:'flex', alignItems:'center', justifyContent:'center', boxShadow:'0 2px 8px rgba(0,0,0,0.18)', opacity: imgIdx === box.images.length - 1 ? 0.35 : 1, transition:'opacity 0.15s'}}
                  >›</button>
                </div>
              )}
            </>
          ) : (
            <div style={{height:'100%', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', opacity:0.4, gap:8}}>
              <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#adb5bd" strokeWidth="1.5"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
              <span style={{fontSize:12, color:'#adb5bd', textTransform:'uppercase', letterSpacing:1}}>sin fotos</span>
            </div>
          )}
          <div style={{position:'absolute', top:10, left:10, background: available ? '#d4edda' : '#f8d7da', color: available ? '#155724' : '#721c24', fontSize:12, fontWeight:600, padding:'4px 10px', borderRadius:20, pointerEvents:'none'}}>
            {available ? '● Disponible hoy' : '● No disponible'}
          </div>
        </div>

        {/* Scrollable content */}
        <div style={{flex:1, overflowY:'auto', padding:'18px 20px 20px', color:'#2D3436'}}>

          {/* Name + price */}
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:12, marginBottom:12}}>
            <div style={{flex:1}}>
              <div style={{fontSize:18, fontWeight:700, color:'#1a1d23', marginBottom:4, lineHeight:1.2}}>{box.name}</div>
              <div style={{display:'flex', alignItems:'center', gap:5, fontSize:13, color:'#adb5bd'}}>
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#adb5bd" strokeWidth="2"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
                {box.address}
              </div>
            </div>
            <div style={{textAlign:'right', flexShrink:0}}>
              <div style={{fontSize:24, fontWeight:700, color:'#1a1d23', lineHeight:1}}>${(box.price || 0).toLocaleString('es-CL')}</div>
              <div style={{fontSize:12, color:'#adb5bd'}}>/hora</div>
            </div>
          </div>

          {/* Description */}
          {box.description && (
            <div style={{fontSize:14, color:'#636e72', lineHeight:1.6, marginBottom:14}}>
              {box.description}
            </div>
          )}

          {/* Tags */}
          <div style={{display:'flex', gap:7, flexWrap:'wrap', marginBottom:14}}>
            {box.tags?.map(t => (
              <span key={t} style={{background:'#f0f4f8', color:'#2D3436', fontSize:12, fontWeight:600, padding:'4px 11px', borderRadius:20}}>{t}</span>
            ))}
            {box.resolution_type && (
              <span style={{fontSize:12, fontWeight:600, padding:'4px 11px', borderRadius:20, ...(RESOLUTION_BADGE_STYLE[box.resolution_type] || {background:'#f8f9fa', color:'#636e72'})}}>
                🏥 {box.resolution_type}
              </span>
            )}
          </div>

          {/* Rating */}
          <div style={{display:'flex', alignItems:'center', gap:7, padding:'12px 0', borderTop:'1px solid #f0f0f0', borderBottom:'1px solid #f0f0f0', marginBottom:16}}>
            <div style={{display:'flex', gap:2}}>
              {[1,2,3,4,5].map(i => (
                <span key={i} style={{fontSize:16, color: i <= rounded ? '#f4b942' : '#dee2e6'}}>{i <= rounded ? '★' : '☆'}</span>
              ))}
            </div>
            <span style={{fontSize:15, fontWeight:700, color:'#1a1d23'}}>{Number(box.rating || 0).toFixed(1)}</span>
            <span style={{fontSize:13, color:'#adb5bd'}}>({box.reviews || 0} reseñas)</span>
          </div>

          {/* Equipment */}
          {box.equip && box.equip.length > 0 && (
            <div style={{marginBottom:16}}>
              <div style={{fontSize:14, fontWeight:700, color:'#1a1d23', marginBottom:9}}>Equipamiento incluido</div>
              <div style={{display:'flex', gap:7, flexWrap:'wrap'}}>
                {box.equip.map(e => (
                  <span key={e} style={{background:'#f4f5f7', borderRadius:8, padding:'6px 12px', fontSize:13, color:'#2D3436', display:'flex', alignItems:'center', gap:6}}>
                    {EQUIP_ICONS[e] || '🔧'} {e}
                  </span>
                ))}
              </div>
            </div>
          )}

          {/* Arrival instructions — API always sends arrival_instructions (snake_case) */}
          {box.arrival_instructions && (
            <div style={{background:'#f8f9fa', borderRadius:10, border:'1px solid #ebebeb', padding:'12px 14px', marginBottom:16}}>
              <div style={{fontSize:12, fontWeight:700, color:'#adb5bd', marginBottom:5, textTransform:'uppercase', letterSpacing:0.4}}>📍 Indicaciones de llegada</div>
              <div style={{fontSize:13, color:'#2D3436', lineHeight:1.6, whiteSpace:'pre-wrap'}}>
                {box.arrival_instructions}
              </div>
            </div>
          )}

        </div>

        {/* Bottom action bar */}
        <div style={{padding:'14px 20px', borderTop:'1px solid #f0f0f0', flexShrink:0, background:'#fff', display:'flex', alignItems:'center', gap:14}}>
          <div style={{flexShrink:0}}>
            <div style={{fontSize:16, fontWeight:700, color:'#1a1d23', lineHeight:1}}>${(box.price || 0).toLocaleString('es-CL')}</div>
            <div style={{fontSize:11, color:'#adb5bd'}}>/hora</div>
          </div>
          <button
            onClick={() => available && onBook(box)}
            disabled={!available}
            style={{flex:1, background: available ? '#1a1d23' : '#e9ecef', color: available ? '#fff' : '#adb5bd', border:'none', borderRadius:10, padding:'13px 0', fontSize:14, fontWeight:700, cursor: available ? 'pointer' : 'not-allowed', fontFamily:'inherit'}}
          >
            {available ? 'Reservar este box →' : 'No disponible'}
          </button>
        </div>

      </div>
    </div>
    </React.Fragment>
  );
};

// ─── BOX DETAIL VIEW ─────────────────────────────────────────────────────────
const BoxDetail = ({ box, onBack, onBook }) => {
  const [imgIdx, setImgIdx] = React.useState(0);
  const hasImages = box.images && box.images.length > 0;
  const rounded   = Math.round((box.rating || 0) * 2) / 2;
  const available = box.available !== false;

  return (
    <div style={{minHeight:'100vh', background:'#fff', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", color:'#2D3436', paddingBottom:90}}>

      {/* ── Sticky header ── */}
      <div style={{position:'sticky', top:0, zIndex:50, background:'#fff', borderBottom:'1px solid #f0f0f0', height:56, display:'flex', alignItems:'center', padding:'0 16px', gap:12}}>
        <button onClick={onBack} style={{width:34, height:34, borderRadius:7, border:'1px solid #e9ecef', background:'#fff', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', color:'#636e72', flexShrink:0}}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg>
        </button>
        <div style={{fontSize:15, fontWeight:700, color:'#1a1d23', flex:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{box.name}</div>
      </div>

      {/* ── Photo gallery ── */}
      <div style={{height:260, background:'#f0f4f8', position:'relative', overflow:'hidden'}}>
        {hasImages ? (
          <>
            <img src={box.images[imgIdx]} alt={box.name} style={{width:'100%', height:'100%', objectFit:'cover', display:'block'}} />
            {box.images.length > 1 && (
              <>
                <div style={{position:'absolute', bottom:12, right:12, background:'rgba(0,0,0,0.55)', color:'#fff', fontSize:12, fontWeight:700, padding:'4px 10px', borderRadius:12}}>
                  {imgIdx + 1} / {box.images.length}
                </div>
                <div style={{position:'absolute', inset:0, display:'flex', alignItems:'center', justifyContent:'space-between', padding:'0 12px', pointerEvents:'none'}}>
                  <button onClick={e => { e.stopPropagation(); setImgIdx(i => Math.max(0, i - 1)); }}
                    style={{pointerEvents:'all', background:'rgba(255,255,255,0.9)', border:'none', borderRadius:'50%', width:34, height:34, cursor:'pointer', fontSize:20, display:'flex', alignItems:'center', justifyContent:'center', opacity: imgIdx === 0 ? 0.3 : 1}}>‹</button>
                  <button onClick={e => { e.stopPropagation(); setImgIdx(i => Math.min(box.images.length - 1, i + 1)); }}
                    style={{pointerEvents:'all', background:'rgba(255,255,255,0.9)', border:'none', borderRadius:'50%', width:34, height:34, cursor:'pointer', fontSize:20, display:'flex', alignItems:'center', justifyContent:'center', opacity: imgIdx === box.images.length - 1 ? 0.3 : 1}}>›</button>
                </div>
              </>
            )}
          </>
        ) : (
          <div style={{height:'100%', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', opacity:0.4, gap:8}}>
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#adb5bd" strokeWidth="1.5"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
            <span style={{fontSize:12, color:'#adb5bd', textTransform:'uppercase', letterSpacing:1}}>sin fotos</span>
          </div>
        )}
        {/* Availability badge overlaid on photo */}
        <div style={{position:'absolute', top:12, left:12, background: available ? '#d4edda' : '#f8d7da', color: available ? '#155724' : '#721c24', fontSize:12, fontWeight:600, padding:'4px 12px', borderRadius:20}}>
          {available ? '● Disponible hoy' : '● No disponible'}
        </div>
      </div>

      {/* ── Content ── */}
      <div style={{maxWidth:720, margin:'0 auto', padding:'20px 20px 0'}}>

        {/* Title + price */}
        <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:12, marginBottom:10}}>
          <div>
            <h1 style={{fontSize:22, fontWeight:700, margin:'0 0 5px', color:'#1a1d23', lineHeight:1.2}}>{box.name}</h1>
            <div style={{display:'flex', alignItems:'center', gap:5, color:'#636e72', fontSize:13}}>
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="#adb5bd" strokeWidth="2"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
              {box.address}
            </div>
          </div>
          <div style={{textAlign:'right', flexShrink:0}}>
            <div style={{fontSize:26, fontWeight:700, color:'#1a1d23', lineHeight:1}}>${(box.price || 0).toLocaleString('es-CL')}</div>
            <div style={{fontSize:12, color:'#adb5bd'}}>/hora</div>
          </div>
        </div>

        {/* Specialty + resolution tags */}
        <div style={{display:'flex', gap:8, flexWrap:'wrap', marginBottom:16}}>
          {box.tags?.map(t => (
            <span key={t} style={{background:'#f0f4f8', color:'#2D3436', fontSize:12, fontWeight:600, padding:'4px 12px', borderRadius:20}}>{t}</span>
          ))}
          {box.resolution_type && (
            <span style={{fontSize:12, fontWeight:600, padding:'4px 12px', borderRadius:20, ...(RESOLUTION_BADGE_STYLE[box.resolution_type] || {background:'#f8f9fa', color:'#636e72'})}}>
              🏥 {box.resolution_type}
            </span>
          )}
        </div>

        {/* Divider + rating */}
        <div style={{display:'flex', alignItems:'center', gap:8, padding:'14px 0', borderTop:'1px solid #f0f0f0', borderBottom:'1px solid #f0f0f0', marginBottom:20}}>
          <div style={{display:'flex', gap:2}}>
            {[1,2,3,4,5].map(i => (
              <span key={i} style={{fontSize:17, color: i <= rounded ? '#f4b942' : '#dee2e6'}}>{i <= rounded ? '★' : '☆'}</span>
            ))}
          </div>
          <span style={{fontSize:15, fontWeight:700, color:'#1a1d23'}}>{Number(box.rating || 0).toFixed(1)}</span>
          <span style={{fontSize:13, color:'#adb5bd'}}>({box.reviews || 0} reseñas)</span>
        </div>

        {/* Equipment */}
        {box.equip && box.equip.length > 0 && (
          <div style={{marginBottom:22}}>
            <div style={{fontSize:14, fontWeight:700, color:'#1a1d23', marginBottom:10}}>Equipamiento incluido</div>
            <div style={{display:'flex', gap:8, flexWrap:'wrap'}}>
              {box.equip.map(e => (
                <span key={e} style={{background:'#f4f5f7', borderRadius:8, padding:'7px 13px', fontSize:13, color:'#2D3436', display:'flex', alignItems:'center', gap:6}}>
                  {EQUIP_ICONS[e] || '🔧'} {e}
                </span>
              ))}
            </div>
          </div>
        )}

        {/* Location */}
        <div style={{background:'#f8f9fa', borderRadius:12, border:'1px solid #ebebeb', padding:'14px 16px', marginBottom:20, display:'flex', alignItems:'flex-start', gap:10}}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#adb5bd" strokeWidth="2" style={{flexShrink:0, marginTop:1}}><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
          <div>
            <div style={{fontSize:13, fontWeight:600, color:'#2D3436', marginBottom:2}}>{box.location || box.address.split(',')[0]}</div>
            <div style={{fontSize:12, color:'#adb5bd'}}>{box.address}</div>
          </div>
        </div>

      </div>

      {/* ── Fixed bottom bar ── */}
      <div style={{position:'fixed', bottom:0, left:0, right:0, background:'#fff', borderTop:'1px solid #f0f0f0', padding:'12px 20px', display:'flex', alignItems:'center', gap:14, zIndex:100, boxShadow:'0 -4px 20px rgba(0,0,0,0.06)'}}>
        <div style={{flexShrink:0}}>
          <div style={{fontSize:18, fontWeight:700, color:'#1a1d23', lineHeight:1}}>${(box.price || 0).toLocaleString('es-CL')}</div>
          <div style={{fontSize:11, color:'#adb5bd'}}>/hora</div>
        </div>
        <button
          onClick={() => available && onBook(box)}
          disabled={!available}
          style={{flex:1, background: available ? '#1a1d23' : '#e9ecef', color: available ? '#fff' : '#adb5bd', border:'none', borderRadius:10, padding:'13px 0', fontSize:15, fontWeight:700, cursor: available ? 'pointer' : 'not-allowed', fontFamily:'inherit'}}
        >
          {available ? 'Reservar este box →' : 'No disponible'}
        </button>
      </div>

    </div>
  );
};

// ─── SIS VERIFICATION ────────────────────────────────────────────────────────
const SISVerification = ({ box, onVerified, onBack }) => {
  const [rut, setRut] = React.useState('');
  const [status, setStatus] = React.useState('idle'); // idle | validating | success | error
  const [specialty, setSpecialty] = React.useState('');
  const specialties = ['Odontología', 'Kinesiología', 'Psicología', 'Medicina General', 'Dermatología', 'Nutrición'];

  const formatRut = (val) => {
    const clean = val.replace(/[^0-9kK]/g, '');
    if (clean.length <= 1) return clean;
    const body = clean.slice(0, -1).replace(/\B(?=(\d{3})+(?!\d))/g, '.');
    const dv = clean.slice(-1).toUpperCase();
    return `${body}-${dv}`;
  };

  const handleRutChange = (e) => {
    setRut(formatRut(e.target.value));
    setStatus('idle');
  };

  const validate = () => {
    if (!rut || rut.length < 9 || !specialty) return;
    setStatus('validating');
    setTimeout(() => setStatus('success'), 2200);
  };

  return (
    <div style={pfStyles.page}>
      <div style={pfStyles.topBar}>
        <button style={pfStyles.backBtn} onClick={onBack}>
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg>
        </button>
        <div style={pfStyles.topBarTitle}>Verificación SIS</div>
        <div style={pfStyles.stepIndicator}>Paso 2/3</div>
      </div>

      <div style={pfStyles.verifyContainer}>
        {/* BOX SUMMARY */}
        <div style={pfStyles.bookingSummary}>
          <div style={pfStyles.summaryIcon}>🏥</div>
          <div>
            <div style={pfStyles.summaryName}>{box.name}</div>
            <div style={pfStyles.summaryLoc}>{box.location} · ${box.price.toLocaleString()}/hr</div>
          </div>
        </div>

        <div style={pfStyles.verifyCard}>
          <div style={pfStyles.verifyHeader}>
            <div style={pfStyles.verifyIconBg}>
              <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#0984e3" strokeWidth="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
            </div>
            <div>
              <div style={pfStyles.verifyTitle}>Verificación SIS</div>
              <div style={pfStyles.verifySub}>Superintendencia de Salud</div>
            </div>
          </div>
          <p style={pfStyles.verifyDesc}>
            Verificamos tu habilitación profesional en tiempo real con el registro de la Superintendencia de Salud de Chile.
          </p>

          <div style={pfStyles.formGroup}>
            <label style={pfStyles.label}>RUT del profesional</label>
            <input
              style={pfStyles.input}
              placeholder="12.345.678-9"
              value={rut}
              onChange={handleRutChange}
              maxLength={12}
            />
          </div>

          <div style={pfStyles.formGroup}>
            <label style={pfStyles.label}>Especialidad</label>
            <select style={pfStyles.input} value={specialty} onChange={e => setSpecialty(e.target.value)}>
              <option value="">Selecciona tu especialidad</option>
              {specialties.map(s => <option key={s} value={s}>{s}</option>)}
            </select>
          </div>

          {/* STATUS DISPLAY */}
          {status === 'idle' && (
            <button
              style={{...pfStyles.verifyBtn, opacity: (!rut || rut.length < 9 || !specialty) ? 0.5 : 1}}
              onClick={validate}
              disabled={!rut || rut.length < 9 || !specialty}
            >
              Verificar con SIS →
            </button>
          )}

          {status === 'validating' && (
            <div style={pfStyles.validatingBox}>
              <div style={pfStyles.spinner}></div>
              <div>
                <div style={pfStyles.validatingTitle}>Validando con Superintendencia de Salud...</div>
                <div style={pfStyles.validatingSub}>Consultando registro RUT {rut}</div>
              </div>
            </div>
          )}

          {status === 'success' && (
            <div style={pfStyles.successBox}>
              <div style={pfStyles.successIcon}>✓</div>
              <div>
                <div style={pfStyles.successTitle}>¡Verificado exitosamente!</div>
                <div style={pfStyles.successSub}>Habilitado para {specialty} · SIS #2026-{rut.slice(-4)}</div>
              </div>
            </div>
          )}

          {status === 'success' && (
            <button style={pfStyles.continueBtn} onClick={onVerified}>
              Continuar → Seleccionar horario
            </button>
          )}
        </div>
      </div>
    </div>
  );
};

// ─── LIGHTBOX (PHOTO VIEWER) ─────────────────────────────────────────────────
const Lightbox = ({ images, index, onClose, onNext, onPrev }) => {
  React.useEffect(() => {
    const handle = (e) => {
      if (e.key === 'Escape')      onClose();
      if (e.key === 'ArrowRight')  onNext();
      if (e.key === 'ArrowLeft')   onPrev();
    };
    window.addEventListener('keydown', handle);
    return () => window.removeEventListener('keydown', handle);
  }, [index, images.length]);

  const hasMany = images.length > 1;

  return (
    <div
      style={{position:'fixed', inset:0, background:'rgba(0,0,0,0.92)', zIndex:3000, display:'flex', alignItems:'center', justifyContent:'center'}}
      onClick={onClose}
    >
      {/* Close button */}
      <button
        style={{position:'absolute', top:20, right:24, background:'rgba(255,255,255,0.14)', border:'none', borderRadius:'50%', width:42, height:42, color:'#fff', fontSize:20, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', lineHeight:1}}
        onClick={onClose}
        title="Cerrar (Esc)"
      >✕</button>

      {/* Counter */}
      {hasMany && (
        <div style={{position:'absolute', top:24, left:'50%', transform:'translateX(-50%)', color:'rgba(255,255,255,0.65)', fontSize:13, fontWeight:600, letterSpacing:0.5, pointerEvents:'none'}}>
          {index + 1} / {images.length}
        </div>
      )}

      {/* Prev arrow */}
      {hasMany && (
        <button
          style={{position:'absolute', left:16, top:'50%', transform:'translateY(-50%)', background:'rgba(255,255,255,0.14)', border:'none', borderRadius:'50%', width:48, height:48, color:'#fff', fontSize:28, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', lineHeight:1}}
          onClick={e => { e.stopPropagation(); onPrev(); }}
          title="Anterior (←)"
        >‹</button>
      )}

      {/* Image */}
      <img
        src={images[index]}
        alt={`foto ${index + 1}`}
        style={{maxWidth:'90vw', maxHeight:'85vh', objectFit:'contain', borderRadius:10, boxShadow:'0 12px 50px rgba(0,0,0,0.6)', userSelect:'none'}}
        onClick={e => e.stopPropagation()}
      />

      {/* Next arrow */}
      {hasMany && (
        <button
          style={{position:'absolute', right:16, top:'50%', transform:'translateY(-50%)', background:'rgba(255,255,255,0.14)', border:'none', borderRadius:'50%', width:48, height:48, color:'#fff', fontSize:28, cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', lineHeight:1}}
          onClick={e => { e.stopPropagation(); onNext(); }}
          title="Siguiente (→)"
        >›</button>
      )}
    </div>
  );
};

// ─── TIME SLOT GRID ──────────────────────────────────────────────────────────
const TimeSlotGrid = ({ box, onBooked, onBack }) => {
  const [selectedDate, setSelectedDate] = React.useState(0);
  const [selectedSlot, setSelectedSlot] = React.useState(null);
  const [confirming, setConfirming] = React.useState(false);
  const [lightbox, setLightbox] = React.useState(null);
  const isMobile = useWindowWidth() <= 768;

  // Recurrence state
  const [recurrenceEnabled, setRecurrenceEnabled] = React.useState(false);
  const [recurrenceType, setRecurrenceType] = React.useState('weekly'); // 'weekly' | 'biweekly'
  const [recurrenceEndDate, setRecurrenceEndDate] = React.useState('');

  // Real availability from backend
  const [takenSlots, setTakenSlots] = React.useState(new Set());
  const [slotsLoading, setSlotsLoading] = React.useState(false);

  // Dental warning: professional is odontólogo but box lacks Dental/Radiología authorization
  const userSpecialty = (() => { try { return JSON.parse(localStorage.getItem('lokat_user') || '{}').specialty || ''; } catch { return ''; } })();
  const showDentalWarning = userSpecialty === 'Odontología' && box.resolution_type !== 'Dental/Radiología';

  const today = new Date();
  const dates = Array.from({length: 7}, (_, i) => {
    const d = new Date(today);
    d.setDate(today.getDate() + i);
    return d;
  });

  const dayNames = ['Dom','Lun','Mar','Mié','Jue','Vie','Sáb'];
  const monthNames = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'];

  const hours = [8,9,10,11,12,13,14,15,16,17,18,19];

  // Fetch real taken slots whenever the selected date changes
  const fetchTakenSlots = React.useCallback(async (dateIndex) => {
    if (!box?.id) return;
    setSlotsLoading(true);
    try {
      const dateStr = dates[dateIndex].toISOString().split('T')[0];
      const response = await fetchWithAuth(
        `https://lokat.fly.dev/api/bookings/slots?boxId=${encodeURIComponent(box.id)}&date=${dateStr}`,
        {}
      );
      if (!response.ok) { console.warn('[SLOTS] fetch failed:', response.status); return; }
      const data = await response.json();
      setTakenSlots(new Set(data.takenSlots || []));
      console.log(`[SLOTS] ${dateStr}: taken = [${(data.takenSlots || []).join(', ')}]`);
    } catch (err) {
      if (err.sessionExpired) return;
      console.error('[SLOTS] Error fetching slots:', err.message);
    } finally {
      setSlotsLoading(false);
    }
  }, [box?.id]);

  // Fetch on mount and whenever selected date changes
  React.useEffect(() => {
    fetchTakenSlots(selectedDate);
  }, [selectedDate, fetchTakenSlots]);

  const getSlotState = (hour) => {
    if (takenSlots.has(hour)) return 'taken';
    if (takenSlots.has(hour - 1)) return 'buffer'; // hygiene buffer after a taken slot
    return 'free';
  };

  // ── Recurrence helpers ────────────────────────────────────────────────────────
  const getRecurrenceDates = () => {
    if (!recurrenceEnabled || !recurrenceEndDate) return [dates[selectedDate]];
    const intervalDays = recurrenceType === 'weekly' ? 7 : 14;
    const end = new Date(recurrenceEndDate);
    const result = [];
    const cur = new Date(dates[selectedDate]);
    while (cur <= end) {
      result.push(new Date(cur));
      cur.setDate(cur.getDate() + intervalDays);
    }
    return result;
  };

  const recurrenceDates = selectedSlot !== null ? getRecurrenceDates() : [];
  const sessionCount = recurrenceDates.length;
  const pricePerSession = Math.round(box.price * 1.1);
  const totalAllSessions = pricePerSession * sessionCount;

  // Min end date = start date + 1 interval
  const minEndDate = (() => {
    const d = new Date(dates[selectedDate]);
    d.setDate(d.getDate() + (recurrenceType === 'weekly' ? 7 : 14));
    return d.toISOString().split('T')[0];
  })();

  // When recurrence type changes, clear end date if it's now before the new minimum
  const handleRecurrenceTypeChange = (type) => {
    setRecurrenceType(type);
    if (recurrenceEndDate) {
      const newMin = new Date(dates[selectedDate]);
      newMin.setDate(newMin.getDate() + (type === 'weekly' ? 7 : 14));
      if (new Date(recurrenceEndDate) < newMin) setRecurrenceEndDate('');
    }
  };

  const handleConfirm = async () => {
    setConfirming(true);
    try {
      const token = localStorage.getItem('lokat_token');
      if (!token) {
        alert('No se encontró token de autenticación. Por favor, inicia sesión nuevamente.');
        setConfirming(false);
        return;
      }

      const dateStr = dates[selectedDate].toISOString().split('T')[0];

      const bodyPayload = {
        boxId: box.id,
        date: dateStr,
        slot: selectedSlot,
        total_amount: pricePerSession,
      };

      if (recurrenceEnabled && recurrenceEndDate && sessionCount > 1) {
        bodyPayload.recurrence = { type: recurrenceType, endDate: recurrenceEndDate };
      }

      const response = await fetchWithAuth('https://lokat.fly.dev/api/bookings', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(bodyPayload),
      });

      if (response.status === 409) {
        const error = await response.json();
        console.warn('[BOOKING] Slot conflict:', error);
        // Refresh slot availability so the UI reflects the real state
        await fetchTakenSlots(selectedDate);
        setSelectedSlot(null);
        setConfirming(false);
        alert(error.error || 'Este horario ya fue reservado. Por favor selecciona otro.');
        return;
      }

      if (!response.ok) {
        const error = await response.json();
        console.error('Booking API error response:', error);
        throw new Error(error.error || error.message || `Error: ${response.status}`);
      }

      const data = await response.json();
      console.log('Booking created successfully:', data);

      // Handle single and recurring responses
      const firstBooking = data.booking || data.bookings?.[0];
      onBooked({
        box,
        date:           dates[selectedDate],
        slot:           selectedSlot,
        booking_id:     firstBooking.id,
        booking_code:   firstBooking.booking_code,
        total_amount:   data.bookings ? totalAllSessions : pricePerSession,
        recurring_count: data.bookings?.length || 1,
      });
    } catch (err) {
      if (err.sessionExpired) return;
      console.error('Error creating booking:', {
        message: err.message,
        stack: err.stack,
        response: err.response,
      });
      alert(`Error al crear la reserva: ${err.message}`);
      setConfirming(false);
    }
  };

  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onBack();
  };

  return (
    <div style={pfStyles.page}>
      {lightbox && (
        <Lightbox
          images={lightbox.images}
          index={lightbox.index}
          onClose={() => setLightbox(null)}
          onNext={() => setLightbox(p => ({ ...p, index: (p.index + 1) % p.images.length }))}
          onPrev={() => setLightbox(p => ({ ...p, index: (p.index - 1 + p.images.length) % p.images.length }))}
        />
      )}
      <ProfessionalHeader screenName="Seleccionar horario" onLogout={handleLogout} onBack={onBack} />

      <div style={pfStyles.slotContainer}>
        {/* BOX MINI HEADER */}
        <div style={pfStyles.bookingSummary}>
          <div style={pfStyles.summaryIcon}>🏥</div>
          <div>
            <div style={pfStyles.summaryName}>{box.name}</div>
            <div style={pfStyles.summaryLoc}>{box.location} · ${box.price.toLocaleString()}/hr</div>
          </div>
        </div>

        {/* PHOTO GALLERY */}
        {box.images && box.images.length > 0 && (
          <div style={{overflowX:'auto', display:'flex', gap:8, paddingBottom:4, marginBottom:12, WebkitOverflowScrolling:'touch'}}>
            {box.images.map((url, i) => (
              <img
                key={i}
                src={url}
                alt={`${box.name} foto ${i+1}`}
                onClick={() => setLightbox({ images: box.images, index: i })}
                style={{height:120, minWidth:160, objectFit:'cover', borderRadius:10, border:'1px solid #e9ecef', flexShrink:0, cursor:'pointer'}}
              />
            ))}
          </div>
        )}

        {/* DENTAL WARNING */}
        {showDentalWarning && (
          <div style={{
            background: '#fff9e6',
            border: '1.5px solid #f39c12',
            borderRadius: 10,
            padding: '12px 16px',
            display: 'flex',
            gap: 10,
            alignItems: 'flex-start',
            marginBottom: 4,
          }}>
            <span style={{fontSize: 18, flexShrink: 0}}>⚠️</span>
            <div style={{fontSize: 13, color: '#7d5a00', lineHeight: 1.5}}>
              <strong>Este box no está habilitado para procedimientos dentales</strong> (sin autorización para rayos y autoclave). Verifica con el propietario antes de reservar.
            </div>
          </div>
        )}

        {/* DATE STRIP */}
        <div style={pfStyles.dateStrip}>
          {dates.map((d, i) => (
            <button key={i} style={{...pfStyles.dateBtn, ...(selectedDate === i ? pfStyles.dateBtnActive : {})}} onClick={() => { setSelectedDate(i); setSelectedSlot(null); setTakenSlots(new Set()); }}>
              <div style={pfStyles.dateDayName}>{dayNames[d.getDay()]}</div>
              <div style={pfStyles.dateDayNum}>{d.getDate()}</div>
              <div style={pfStyles.dateMonth}>{monthNames[d.getMonth()]}</div>
            </button>
          ))}
        </div>

        {/* LEGEND */}
        <div style={pfStyles.legend}>
          <span style={pfStyles.legendItem}><span style={{...pfStyles.legendDot, background: '#e9ecef'}}></span>Buffer higiene</span>
          <span style={pfStyles.legendItem}><span style={{...pfStyles.legendDot, background: '#e9ecef', border:'1.5px solid #ced4da'}}></span>Ocupado</span>
          <span style={pfStyles.legendItem}><span style={{...pfStyles.legendDot, background: '#0984e3'}}></span>Disponible</span>
        </div>

        {/* SLOT GRID */}
        <div style={{position:'relative'}}>
        {slotsLoading && (
          <div style={{position:'absolute', inset:0, background:'rgba(248,249,250,0.75)', borderRadius:12, display:'flex', alignItems:'center', justifyContent:'center', zIndex:2}}>
            <span style={{...pfStyles.spinnerSmall, width:22, height:22, borderWidth:2, display:'inline-block'}}></span>
          </div>
        )}
        <div style={{...pfStyles.slotGrid, gridTemplateColumns: isMobile ? 'repeat(3,1fr)' : 'repeat(4,1fr)'}}>
          {hours.map(hour => {
            const state = getSlotState(hour);
            const isSelected = selectedSlot === hour;
            const slotStyle = {
              ...pfStyles.slotCell,
              ...(state === 'taken' ? pfStyles.slotTaken : {}),
              ...(state === 'buffer' ? pfStyles.slotBuffer : {}),
              ...(state === 'free' && !isSelected ? pfStyles.slotFree : {}),
              ...(isSelected ? pfStyles.slotSelected : {}),
              ...(slotsLoading ? { opacity: 0.4, pointerEvents: 'none' } : {}),
            };
            return (
              <div key={hour} style={slotStyle} onClick={() => state === 'free' && !slotsLoading && setSelectedSlot(hour)}>
                <div style={{...pfStyles.slotTime, ...(state === 'taken' ? {textDecoration:'line-through', color:'#868e96'} : {})}}>{hour.toString().padStart(2,'0')}:00</div>
                {state === 'buffer' && <div style={pfStyles.slotNote}>buffer</div>}
                {state === 'taken' && <div style={{...pfStyles.slotNote, color:'#868e96', fontWeight:600, opacity:1}}>Ocupado</div>}
                {state === 'free' && <div style={pfStyles.slotNote}>60 min</div>}
                {isSelected && <div style={pfStyles.slotNote}>✓ selec.</div>}
              </div>
            );
          })}
        </div>
        </div>{/* end position:relative wrapper */}

        {/* BOOKING FOOTER */}
        {selectedSlot !== null && (
          <div style={pfStyles.bookingFooter}>
            {/* COST BREAKDOWN */}
            <div style={pfStyles.bookingCalc}>
              <div style={pfStyles.bookingCalcRow}>
                <span>1 hora ({fmtSlot(selectedSlot)})</span>
                <span>${box.price.toLocaleString()}</span>
              </div>
              <div style={pfStyles.bookingCalcRow}>
                <span style={{color:'#636e72', fontSize:13}}>Comisión plataforma (10%)</span>
                <span style={{color:'#636e72', fontSize:13}}>${Math.round(box.price * 0.1).toLocaleString()}</span>
              </div>
              {recurrenceEnabled && sessionCount > 1 ? (
                <>
                  <div style={{...pfStyles.bookingCalcRow, borderTop:'1px solid #e9ecef', paddingTop:8, marginTop:4}}>
                    <span style={{color:'#636e72'}}>Por sesión</span>
                    <span style={{color:'#636e72'}}>${pricePerSession.toLocaleString()}</span>
                  </div>
                  <div style={pfStyles.bookingCalcRow}>
                    <span style={{color:'#636e72', fontSize:13}}>{sessionCount} sesiones recurrentes</span>
                    <span style={{color:'#636e72', fontSize:13}}>× {sessionCount}</span>
                  </div>
                  <div style={{...pfStyles.bookingCalcRow, fontWeight:700, borderTop:'1px solid #e9ecef', paddingTop:8, marginTop:4}}>
                    <span>Total ({sessionCount} sesiones)</span>
                    <span style={{color:'#0984e3'}}>${totalAllSessions.toLocaleString()}</span>
                  </div>
                </>
              ) : (
                <div style={{...pfStyles.bookingCalcRow, fontWeight:700, borderTop:'1px solid #e9ecef', paddingTop:8, marginTop:4}}>
                  <span>Total</span>
                  <span style={{color:'#0984e3'}}>${pricePerSession.toLocaleString()}</span>
                </div>
              )}
            </div>

            {/* RECURRENCE PANEL */}
            <div style={{borderTop:'1px solid #e9ecef', paddingTop:14, marginTop:8, marginBottom:12}}>
              {/* Header row with toggle */}
              <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom: recurrenceEnabled ? 14 : 0}}>
                <div>
                  <div style={{fontSize:14, fontWeight:700, color:'#2D3436'}}>🔁 Reserva recurrente</div>
                  <div style={{fontSize:12, color:'#636e72', marginTop:2}}>Repite esta reserva automáticamente</div>
                </div>
                {/* Toggle switch */}
                <div
                  style={{width:44, height:24, borderRadius:12, background: recurrenceEnabled ? '#0984e3' : '#dee2e6', position:'relative', cursor:'pointer', transition:'background 0.2s', flexShrink:0}}
                  onClick={() => { setRecurrenceEnabled(e => !e); if (recurrenceEnabled) setRecurrenceEndDate(''); }}
                >
                  <div style={{position:'absolute', top:3, left: recurrenceEnabled ? 22 : 2, width:18, height:18, borderRadius:9, background:'#fff', boxShadow:'0 1px 3px rgba(0,0,0,0.2)', transition:'left 0.2s'}} />
                </div>
              </div>

              {recurrenceEnabled && (
                <div>
                  {/* Frequency buttons */}
                  <div style={{fontSize:12, fontWeight:600, color:'#636e72', marginBottom:6}}>Frecuencia</div>
                  <div style={{display:'flex', gap:8, marginBottom:14}}>
                    {[['weekly','Semanal'],['biweekly','Quincenal']].map(([val, label]) => (
                      <button
                        key={val}
                        onClick={() => handleRecurrenceTypeChange(val)}
                        style={{
                          flex:1,
                          padding:'9px 0',
                          borderRadius:8,
                          border: recurrenceType === val ? '2px solid #0984e3' : '1.5px solid #dee2e6',
                          background: recurrenceType === val ? '#e3f0fc' : '#fff',
                          color: recurrenceType === val ? '#0984e3' : '#636e72',
                          fontWeight: recurrenceType === val ? 700 : 500,
                          fontSize:13,
                          cursor:'pointer',
                        }}
                      >
                        {label}
                      </button>
                    ))}
                  </div>

                  {/* End date */}
                  <div style={{fontSize:12, fontWeight:600, color:'#636e72', marginBottom:6}}>Fecha de término</div>
                  <input
                    type="date"
                    value={recurrenceEndDate}
                    min={minEndDate}
                    onChange={e => setRecurrenceEndDate(e.target.value)}
                    style={{
                      width:'100%',
                      padding:'10px 12px',
                      border: recurrenceEndDate ? '1.5px solid #0984e3' : '1.5px solid #dee2e6',
                      borderRadius:8,
                      fontSize:14,
                      color:'#2D3436',
                      background:'#fff',
                      boxSizing:'border-box',
                      outline:'none',
                    }}
                  />

                  {/* Session preview */}
                  {recurrenceEndDate && sessionCount > 0 && (
                    <div style={{
                      marginTop:10,
                      background:'#e3f0fc',
                      borderRadius:8,
                      padding:'10px 12px',
                      fontSize:13,
                      color:'#0984e3',
                      fontWeight:600,
                      display:'flex',
                      alignItems:'center',
                      gap:6,
                    }}>
                      <span>📅</span>
                      <span>{sessionCount} sesión{sessionCount !== 1 ? 'es' : ''} · {recurrenceType === 'weekly' ? 'cada 7 días' : 'cada 14 días'} · ${totalAllSessions.toLocaleString()} total</span>
                    </div>
                  )}
                </div>
              )}
            </div>

            {showDentalWarning && (
              <div style={{background:'#fff9e6', border:'1.5px solid #f39c12', borderRadius:10, padding:'10px 14px', display:'flex', gap:8, alignItems:'flex-start', marginBottom:12, fontSize:12, color:'#7d5a00', lineHeight:1.5}}>
                <span style={{flexShrink:0}}>⚠️</span>
                <span><strong>Box sin autorización dental</strong> — sin rayos ni autoclave. Confirmas de todas formas bajo tu responsabilidad.</span>
              </div>
            )}

            <button
              style={{
                ...pfStyles.confirmBtn,
                opacity: (recurrenceEnabled && !recurrenceEndDate) ? 0.5 : (confirming ? 0.8 : 1),
              }}
              onClick={handleConfirm}
              disabled={confirming || (recurrenceEnabled && !recurrenceEndDate)}
            >
              {confirming ? (
                <span style={{display:'flex', alignItems:'center', gap:8, justifyContent:'center'}}>
                  <span style={pfStyles.spinnerSmall}></span>
                  {sessionCount > 1 ? `Creando ${sessionCount} reservas...` : 'Creando reserva...'}
                </span>
              ) : sessionCount > 1
                ? `💳 Confirmar ${sessionCount} sesiones · $${totalAllSessions.toLocaleString()}`
                : '💳 Confirmar y Pagar'
              }
            </button>
          </div>
        )}
      </div>
    </div>
  );
};

// ─── CONFIRMATION / PAYMENT ───────────────────────────────────────────────────
const BookingConfirmation = ({ booking, onHome, onMisReservas }) => {
  const d = booking.date;
  const dayNames   = ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'];
  const monthNames = ['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre'];

  // paymentStep: 'loading' | 'paying' | 'paid' | 'error'
  const [paymentStep, setPaymentStep] = React.useState('loading');
  const [payError,    setPayError]    = React.useState('');

  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onHome();
  };

  // Load the Klap Checkout Flex script (idempotent)
  const loadKlapScript = () => new Promise((resolve, reject) => {
    if (window.KLAP_FLEX) { resolve(); return; }
    const existing = document.getElementById('klap-flex-script');
    if (existing) { existing.addEventListener('load', resolve); existing.addEventListener('error', reject); return; }
    const s = document.createElement('script');
    s.id  = 'klap-flex-script';
    s.src = 'https://sandbox.mcdesaqa.cl/pagos/checkout-flex/v1/main.min.js';
    s.onload  = resolve;
    s.onerror = () => reject(new Error('No se pudo cargar la pasarela de pago'));
    document.head.appendChild(s);
  });

  // Initialise payment on mount
  React.useEffect(() => {
    let cancelled = false;

    const initPayment = async () => {
      try {
        const user  = JSON.parse(localStorage.getItem('lokat_user') || '{}');

        // 1 — create Klap order in backend
        const res = await fetchWithAuth('https://lokat.fly.dev/api/payments/create-order', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            bookingId: booking.booking_id,
            amount:    booking.total_amount,
            userEmail: user.email,
            userName:  user.fullName || user.full_name || user.email,
          }),
        });

        const data = await res.json();
        if (!res.ok) throw new Error(data.error || 'Error al crear orden de pago');

        const { orderId } = data;

        // 2 — load Klap Checkout Flex script
        await loadKlapScript();
        if (cancelled) return;

        // 3 — mount payment form inside #klap-checkout-container
        setPaymentStep('paying');

        // Small tick so the container div is in the DOM
        setTimeout(() => {
          if (cancelled) return;
          window.KLAP_FLEX.init({
            orderId,
            containerId: 'klap-checkout-container',
            onSuccess: () => { if (!cancelled) setPaymentStep('paid'); },
            onError:   (err) => {
              if (!cancelled) {
                setPayError((err && err.message) ? err.message : 'El pago no pudo completarse');
                setPaymentStep('error');
              }
            },
          });
        }, 50);

      } catch (err) {
        if (err.sessionExpired) return;
        if (!cancelled) { setPayError(err.message); setPaymentStep('error'); }
      }
    };

    initPayment();
    return () => { cancelled = true; };
  }, []);

  // ── PAID — success screen ─────────────────────────────────────────────────
  if (paymentStep === 'paid') return (
    <div style={pfStyles.page}>
      <ProfessionalHeader screenName="Reserva confirmada" onLogout={handleLogout} onBack={onHome} />
      <div style={pfStyles.confirmPage}>
        <div style={pfStyles.confirmIcon}>✓</div>
        <h2 style={pfStyles.confirmTitle}>¡Pago exitoso!</h2>
        <p style={pfStyles.confirmSub}>Tu reserva está confirmada. Recibirás un email en breve.</p>
        <div style={pfStyles.confirmCard}>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Box</span><span style={pfStyles.confirmVal}>{booking.box.name}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Dirección</span><span style={pfStyles.confirmVal}>{booking.box.address}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Fecha</span><span style={pfStyles.confirmVal}>{dayNames[d.getDay()]} {d.getDate()} de {monthNames[d.getMonth()]}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Horario</span><span style={pfStyles.confirmVal}>{fmtSlot(booking.slot)}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Total pagado</span><span style={{...pfStyles.confirmVal, color:'#0984e3', fontWeight:700}}>${(booking.total_amount || Math.round(booking.box.price * 1.1)).toLocaleString()}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Código</span><span style={{...pfStyles.confirmVal, fontFamily:'monospace', background:'#f0f4f8', padding:'2px 8px', borderRadius:4}}>{booking.booking_code || '—'}</span></div>
        </div>
        {booking.box.arrival_instructions && (
          <div style={{background:'#fff8e1', border:'1.5px solid #f39c12', borderRadius:12, padding:'14px 18px', marginBottom:20}}>
            <div style={{fontWeight:700, color:'#856404', fontSize:13, marginBottom:6}}>📍 Indicaciones de llegada</div>
            <div style={{fontSize:14, color:'#555', lineHeight:1.65, whiteSpace:'pre-wrap'}}>{booking.box.arrival_instructions}</div>
          </div>
        )}
        <div style={pfStyles.confirmActions}>
          <button style={pfStyles.confirmPrimBtn} onClick={onHome}>Volver al inicio</button>
        </div>
        {onMisReservas && (
          <button style={{...pfStyles.confirmSecBtn, width:'100%', marginTop:8}} onClick={onMisReservas}>
            Ver mis reservas →
          </button>
        )}
      </div>
    </div>
  );

  // ── ERROR ─────────────────────────────────────────────────────────────────
  if (paymentStep === 'error') return (
    <div style={pfStyles.page}>
      <ProfessionalHeader screenName="Error de pago" onLogout={handleLogout} onBack={onHome} />
      <div style={pfStyles.confirmPage}>
        <div style={{fontSize:48, textAlign:'center', marginBottom:16}}>❌</div>
        <h2 style={{...pfStyles.confirmTitle, color:'#e74c3c'}}>Error en el pago</h2>
        <p style={{...pfStyles.confirmSub, color:'#636e72'}}>{payError || 'El pago no pudo completarse.'}</p>
        <p style={{...pfStyles.confirmSub, fontSize:13}}>Tu reserva existe pero está pendiente de pago. Puedes intentarlo nuevamente.</p>
        <div style={pfStyles.confirmActions}>
          <button style={pfStyles.confirmPrimBtn} onClick={() => { setPayError(''); setPaymentStep('loading'); }}>Reintentar pago</button>
          <button style={pfStyles.confirmSecBtn} onClick={onHome}>Volver al inicio</button>
        </div>
      </div>
    </div>
  );

  // ── LOADING + PAYING — Klap form mounts here ─────────────────────────────
  return (
    <div style={pfStyles.page}>
      <ProfessionalHeader screenName="Pago" onLogout={handleLogout} onBack={onHome} />

      {/* TEST MODE BANNER */}
      {TEST_MODE && (
        <div style={{
          background: '#fff3cd',
          borderBottom: '1.5px solid #ffc107',
          padding: '8px 20px',
          display: 'flex',
          alignItems: 'center',
          gap: 8,
          fontSize: 13,
          color: '#856404',
          fontWeight: 600,
        }}>
          <span>🧪</span>
          <span>Modo de prueba activo — los pagos no son reales</span>
        </div>
      )}

      <div style={{maxWidth:520, margin:'0 auto', padding:'20px 16px'}}>

        {/* Booking summary */}
        <div style={{background:'#fff', borderRadius:16, padding:'16px 20px', border:'1px solid #e9ecef', marginBottom:16}}>
          <div style={{fontSize:15, fontWeight:700, marginBottom:12, color:'#2d3436'}}>Resumen de tu reserva</div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Box</span><span style={pfStyles.confirmVal}>{booking.box.name}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Fecha</span><span style={pfStyles.confirmVal}>{dayNames[d.getDay()]} {d.getDate()} de {monthNames[d.getMonth()]}</span></div>
          <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Horario</span><span style={pfStyles.confirmVal}>{fmtSlot(booking.slot)}</span></div>
          {booking.recurring_count > 1 && (
            <div style={pfStyles.confirmRow}><span style={pfStyles.confirmLabel}>Sesiones</span><span style={{...pfStyles.confirmVal, color:'#0984e3', fontWeight:600}}>{booking.recurring_count} reservas recurrentes</span></div>
          )}
          <div style={{...pfStyles.confirmRow, borderTop:'1px solid #e9ecef', paddingTop:10, marginTop:6}}>
            <span style={{fontWeight:700, fontSize:15}}>Total</span>
            <span style={{fontWeight:800, fontSize:17, color:'#0984e3'}}>${booking.total_amount.toLocaleString()}</span>
          </div>
        </div>

        {/* TEST MODE — simulate success button */}
        {TEST_MODE && (
          <div style={{
            background: '#fff',
            border: '2px dashed #ffc107',
            borderRadius: 16,
            padding: '20px',
            marginBottom: 16,
            textAlign: 'center',
          }}>
            <div style={{fontSize: 13, color: '#856404', fontWeight: 600, marginBottom: 4}}>🧪 Entorno de prueba</div>
            <div style={{fontSize: 12, color: '#adb5bd', marginBottom: 14}}>
              No se procesará ningún pago real
            </div>
            <button
              onClick={() => setPaymentStep('paid')}
              style={{
                width: '100%',
                background: '#28a745',
                color: '#fff',
                border: 'none',
                borderRadius: 10,
                padding: '13px 0',
                fontSize: 15,
                fontWeight: 700,
                cursor: 'pointer',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                gap: 8,
              }}
            >
              <span>✓</span> Simular pago exitoso
            </button>
          </div>
        )}

        {/* Klap container — shown when paymentStep is 'paying' */}
        {paymentStep === 'paying' && (
          <div id="klap-checkout-container" style={{background:'#fff', borderRadius:16, border:'1px solid #e9ecef', minHeight:300, overflow:'hidden'}} />
        )}

        {/* Loading spinner while creating order + fetching script */}
        {paymentStep === 'loading' && !TEST_MODE && (
          <div style={{background:'#fff', borderRadius:16, border:'1px solid #e9ecef', padding:'48px 24px', textAlign:'center'}}>
            <span style={{...pfStyles.spinnerSmall, width:28, height:28, borderWidth:3, display:'inline-block', marginBottom:16}}></span>
            <div style={{fontSize:14, fontWeight:600, color:'#636e72'}}>Preparando pasarela de pago...</div>
          </div>
        )}
      </div>
    </div>
  );
};

// ─── MIS RESERVAS ─────────────────────────────────────────────────────────────
const MisReservas = ({ onBack, onCancelar, onCalificar }) => {
  console.log('✅ MisReservas component mounted');

  const [reservas, setReservas] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const isMobile = useWindowWidth() <= 768;
  const [error, setError] = React.useState(null);
  const [searchBox, setSearchBox] = React.useState('');
  const [filterStatus, setFilterStatus] = React.useState('todas');
  const [filterSpecialty, setFilterSpecialty] = React.useState('todas');
  const [filterResolutionMR, setFilterResolutionMR] = React.useState('todas');
  const [filterFromDate, setFilterFromDate] = React.useState('');
  const [filterToDate, setFilterToDate] = React.useState('');
  const [filterSlot, setFilterSlot] = React.useState('todos');

  const fetchReservas = async () => {
    try {
      setLoading(true);
      console.log('📡 Fetching from: https://lokat.fly.dev/api/bookings/my');
      const response = await fetchWithAuth('https://lokat.fly.dev/api/bookings/my', {});

      console.log('📥 API Response status:', response.status);

      if (!response.ok) {
        const err = await response.json();
        console.error('❌ API error response:', err);
        throw new Error(err.error || `Error: ${response.status}`);
      }

      const data = await response.json();
      console.log('✅ Bookings fetched successfully:', data);
      console.log(`📊 Total bookings received: ${data.length}`);

      // Map API response to UI format
      const mappedReservas = data.map(booking => ({
        id: booking.booking_code,      // Display booking code (LKT-XXXXX)
        uuid: booking.id,               // Database UUID for API calls
        box: booking.boxes.name,
        address: booking.boxes.address,
        fecha: new Date(booking.date),
        slot: booking.slot,
        monto: booking.total_amount,
        status: booking.status,
        medico: booking.boxes.specialty || 'Profesional',
        resolution_type: booking.boxes.resolution_type || null,
        rating: booking.rating_by_professional, // Rating value if already rated
      }));

      console.log('✅ Reservas mapped successfully:', mappedReservas);
      console.log(`📈 Setting state: reservas array with ${mappedReservas.length} items`);
      console.log('🔹 Sample mapped reserva:', mappedReservas[0]);
      setReservas(mappedReservas);
      console.log('✅ setReservas() called with:', mappedReservas.length, 'items');
      setError(null);
      console.log('✅ setError(null) called');
    } catch (err) {
      if (err.sessionExpired) return;
      console.error('❌ Error fetching reservas:', {
        message: err.message,
        stack: err.stack,
      });
      setError(err.message);
      setReservas([]);
    } finally {
      console.log('✅ Finally block (MisReservas): Setting loading to false');
      setLoading(false);
    }
  };

  React.useEffect(() => {
    console.log('🔄 MisReservas useEffect: Starting API call to fetch bookings');
    fetchReservas();
  }, []);

  const formatFecha = (d) => {
    const days = ['Dom','Lun','Mar','Mié','Jue','Vie','Sáb'];
    const months = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'];
    return `${days[d.getDay()]} ${d.getDate()} ${months[d.getMonth()]} · ${d.getHours().toString().padStart(2,'0')}:00`;
  };

  const statusBadge = (s) => {
    if (s === 'confirmed') return { label: 'Confirmada', bg: '#d4edda', color: '#155724' };
    if (s === 'cancelled') return { label: 'Cancelada',  bg: '#f8d7da', color: '#721c24' };
    return { label: 'Completada', bg: '#e9ecef', color: '#495057' };
  };

  // Debug: Log current state before render decision
  console.log('🔍 RENDER DECISION - Current state:', {
    loading,
    error,
    reservasCount: reservas.length,
    reservas: reservas,
  });

  // Loading state
  if (loading) {
    console.log('🔄 Rendering LOADING state - loading is:', loading);
    return (
      <div style={pfStyles.page}>
        <div style={pfStyles.topBar}>
          <button style={pfStyles.backBtn} onClick={onBack}><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg></button>
          <div style={pfStyles.topBarTitle}>Mis Reservas</div>
          <div style={{width:36}}></div>
        </div>
        <div style={{textAlign:'center', padding:'80px 24px', color:'#636e72'}}>
          <div style={{fontSize:16, fontWeight:600}}>Cargando reservas...</div>
          <div style={{fontSize:13, marginTop:8}}>Consultando tus bookings</div>
        </div>
      </div>
    );
  }

  // Error state
  if (error) {
    console.log('❌ Rendering ERROR state:', error);
    return (
      <div style={pfStyles.page}>
        <div style={pfStyles.topBar}>
          <button style={pfStyles.backBtn} onClick={onBack}><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg></button>
          <div style={pfStyles.topBarTitle}>Error</div>
          <div style={{width:36}}></div>
        </div>
        <div style={{textAlign:'center', padding:'80px 24px', color:'#c0392b'}}>
          <div style={{fontSize:48, marginBottom:16}}>⚠️</div>
          <div style={{fontSize:16, fontWeight:600, marginBottom:8}}>Error al cargar reservas</div>
          <div style={{fontSize:13, color:'#636e72', marginBottom:24}}>{error}</div>
          <button style={{...pfStyles.bookBtn, marginTop:16}} onClick={() => window.location.reload()}>Intentar nuevamente</button>
        </div>
      </div>
    );
  }

  // Empty state
  if (reservas.length === 0) {
    console.log('📭 Rendering EMPTY state (no reservas)');
    return (
      <div style={pfStyles.page}>
        <div style={pfStyles.topBar}>
          <button style={pfStyles.backBtn} onClick={onBack}><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="m15 18-6-6 6-6"/></svg></button>
          <div style={pfStyles.topBarTitle}>Mis Reservas</div>
          <div style={{width:36}}></div>
        </div>
        <div style={{textAlign:'center', padding:'80px 24px', color:'#adb5bd'}}>
          <div style={{fontSize:48, marginBottom:16}}>📅</div>
          <div style={{fontSize:16, fontWeight:600, color:'#636e72'}}>No tienes reservas aún</div>
          <div style={{fontSize:13, marginTop:6}}>Busca y reserva un box para comenzar</div>
          <button style={{...pfStyles.bookBtn, marginTop:24}} onClick={onBack}>Buscar boxes →</button>
        </div>
      </div>
    );
  }

  // Normal render with real reservas
  console.log('✅ Rendering NORMAL state with', reservas.length, 'reservas');

  // Calculate KPIs
  const totalReservas = reservas.length;
  const gastoTotal = reservas.reduce((sum, r) => sum + r.monto, 0);
  const proximaReserva = reservas
    .filter(r => new Date(r.fecha) > new Date())
    .sort((a, b) => new Date(a.fecha) - new Date(b.fecha))[0];

  // Get unique specialties and time slots for filter options
  const specialties = ['todas', ...Array.from(new Set(reservas.map(r => r.medico))).sort()];
  const timeSlots = ['todos', ...Array.from(new Set(reservas.map(r => r.slot || 'Sin horario'))).sort((a, b) => {
    if (a === 'Sin horario') return 1;
    if (b === 'Sin horario') return -1;
    return a - b;
  })];

  // Apply filters
  const filteredReservas = reservas.filter(r => {
    const matchesSearch = r.box.toLowerCase().includes(searchBox.toLowerCase());
    const matchesStatus = filterStatus === 'todas' || r.status === filterStatus;
    const matchesSpecialty = filterSpecialty === 'todas' || r.medico === filterSpecialty;
    const matchesResolution = filterResolutionMR === 'todas' || r.resolution_type === filterResolutionMR;
    const matchesSlot = filterSlot === 'todos' || r.slot === parseInt(filterSlot);

    let matchesDateRange = true;
    if (filterFromDate) {
      matchesDateRange = matchesDateRange && r.fecha >= new Date(filterFromDate);
    }
    if (filterToDate) {
      matchesDateRange = matchesDateRange && r.fecha <= new Date(filterToDate);
    }

    return matchesSearch && matchesStatus && matchesSpecialty && matchesResolution && matchesDateRange && matchesSlot;
  });

  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onBack();
  };

  return (
    <div style={pfStyles.page}>
      <ProfessionalHeader screenName="Mis Reservas" onLogout={handleLogout} onBack={onBack} />

      <div style={{maxWidth: 1200, margin: '0 auto', padding: '0 16px 24px' }}>

        {/* Summary Bar */}
        <div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 12, padding: '20px 0'}}>
          <div style={mrSummaryCard}>
            <div style={mrSummaryLabel}>Total Reservas</div>
            <div style={{fontSize: 28, fontWeight: 800, color: '#0984e3'}}>{totalReservas}</div>
          </div>
          <div style={mrSummaryCard}>
            <div style={mrSummaryLabel}>Total Gastado</div>
            <div style={{fontSize: 28, fontWeight: 800, color: '#0984e3'}}>${gastoTotal.toLocaleString('es-CL')}</div>
          </div>
          <div style={mrSummaryCard}>
            <div style={mrSummaryLabel}>Próxima Reserva</div>
            <div style={{fontSize: 14, fontWeight: 700, color: '#2D3436', marginTop: 4}}>
              {proximaReserva
                ? new Date(proximaReserva.fecha).toLocaleDateString('es-CL', {month: 'short', day: 'numeric'})
                : '—'
              }
            </div>
          </div>
        </div>

        {/* Filter Bar */}
        <div style={{background: '#fff', borderRadius: 12, padding: 16, border: '1px solid #e9ecef', marginBottom: 20}}>
          <div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12}}>
            {/* Search */}
            <input
              type="text"
              placeholder="Buscar por nombre del box..."
              value={searchBox}
              onChange={(e) => setSearchBox(e.target.value)}
              style={{...mrFilterInput, gridColumn: 'span 1'}}
            />

            {/* Status Filter */}
            <select
              value={filterStatus}
              onChange={(e) => setFilterStatus(e.target.value)}
              style={mrFilterInput}
            >
              <option value="todas">Todas</option>
              <option value="confirmed">Confirmada</option>
              <option value="completed">Completada</option>
              <option value="cancelled">Cancelada</option>
            </select>

            {/* Specialty Filter */}
            <select
              value={filterSpecialty}
              onChange={(e) => setFilterSpecialty(e.target.value)}
              style={mrFilterInput}
            >
              <option value="todas">Todas las especialidades</option>
              {specialties.filter(s => s !== 'todas').map(specialty => (
                <option key={specialty} value={specialty}>{specialty}</option>
              ))}
            </select>

            {/* Resolution Type Filter */}
            <select
              value={filterResolutionMR}
              onChange={(e) => setFilterResolutionMR(e.target.value)}
              style={mrFilterInput}
            >
              <option value="todas">Todas las resoluciones</option>
              {['Solo consulta', 'Procedimientos invasivos', 'Dental/Radiología', 'Sin resolución sanitaria'].map(r => (
                <option key={r} value={r}>{r}</option>
              ))}
            </select>

            {/* Time Slot Filter */}
            <select
              value={filterSlot}
              onChange={(e) => setFilterSlot(e.target.value)}
              style={mrFilterInput}
            >
              <option value="todos">Todos los horarios</option>
              {timeSlots.filter(s => s !== 'todos').map(slot => (
                <option key={slot} value={slot}>{fmtSlot(slot)}</option>
              ))}
            </select>

            {/* Date Range */}
            <input
              type="date"
              value={filterFromDate}
              onChange={(e) => setFilterFromDate(e.target.value)}
              placeholder="Desde"
              style={mrFilterInput}
            />

            <input
              type="date"
              value={filterToDate}
              onChange={(e) => setFilterToDate(e.target.value)}
              placeholder="Hasta"
              style={mrFilterInput}
            />

            {/* Clear Filters Button */}
            <button
              onClick={() => {
                setSearchBox('');
                setFilterStatus('todas');
                setFilterSpecialty('todas');
                setFilterSlot('todos');
                setFilterFromDate('');
                setFilterToDate('');
              }}
              style={{...mrFilterInput, background: '#f8f9fa', color: '#0984e3', fontWeight: 600, cursor: 'pointer', border: '1px solid #dee2e6'}}
            >
              Limpiar filtros
            </button>
          </div>
        </div>

        {/* Results Count */}
        {filteredReservas.length !== totalReservas && (
          <div style={{fontSize: 13, color: '#636e72', marginBottom: 12}}>
            Mostrando {filteredReservas.length} de {totalReservas} reservas
          </div>
        )}

        {/* Grid of Booking Cards */}
        {filteredReservas.length === 0 ? (
          <div style={{textAlign: 'center', padding: '60px 24px', color: '#636e72'}}>
            <div style={{fontSize: 48, marginBottom: 12}}>🔍</div>
            <div style={{fontSize: 16, fontWeight: 600, marginBottom: 8}}>No se encontraron reservas</div>
            <div style={{fontSize: 13}}>Intenta ajustar tus filtros</div>
          </div>
        ) : (
          <div style={{display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(auto-fill, minmax(350px, 1fr))', gap: 16}}>
            {filteredReservas.map(r => {
              const badge = statusBadge(r.status);
              const isCancelled = r.status === 'cancelled';
              return (
                <div key={r.id} style={{background:'#fff', borderRadius:16, border:'1px solid #e9ecef', boxShadow:'0 4px 16px rgba(0,0,0,0.07)', overflow:'hidden', opacity: isCancelled ? 0.6 : 1, transition:'opacity 0.3s', display: 'flex', flexDirection: 'column'}}>

                  {/* Card Header with Status Badge */}
                  <div style={{padding:'16px 18px 12px', borderBottom:'1px solid #f0f4f8', display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:12}}>
                    <div style={{flex:1}}>
                      <div style={{fontSize:16, fontWeight:700, marginBottom:3}}>{r.box}</div>
                      <div style={{fontSize:12, color:'#636e72', display:'flex', alignItems:'center', gap:4}}>
                        <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="#636e72" strokeWidth="2"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
                        {r.address}
                      </div>
                    </div>
                    <span style={{borderRadius:20, padding:'4px 12px', fontSize:11, fontWeight:700, background:badge.bg, color:badge.color, flexShrink:0}}>{badge.label}</span>
                  </div>

                  {/* Details Grid */}
                  <div style={{padding:'14px 18px', display:'grid', gridTemplateColumns: '1fr 1fr', gap: 12, flex: 1}}>
                    <div style={mrDetailCell}>
                      <span style={mrDetailLabel}>Especialidad</span>
                      <span style={mrDetailVal}>{r.medico}</span>
                    </div>
                    <div style={mrDetailCell}>
                      <span style={mrDetailLabel}>Fecha</span>
                      <span style={mrDetailVal}>{r.fecha.toLocaleDateString('es-CL', {month: 'short', day: 'numeric', year: 'numeric'})}</span>
                    </div>
                    <div style={mrDetailCell}>
                      <span style={mrDetailLabel}>Hora</span>
                      <span style={mrDetailVal}>{r.slot ? fmtSlot(r.slot) : 'Sin horario'}</span>
                    </div>
                    <div style={mrDetailCell}>
                      <span style={mrDetailLabel}>Monto</span>
                      <span style={{...mrDetailVal, color:'#0984e3', fontWeight:700}}>${r.monto.toLocaleString()}</span>
                    </div>
                    <div style={{...mrDetailCell, gridColumn: '1 / -1'}}>
                      <span style={mrDetailLabel}>Código de Reserva</span>
                      <span style={{...mrDetailVal, fontFamily:'monospace', background:'#f0f4f8', padding:'4px 8px', borderRadius:4, display: 'inline-block'}}>{r.id}</span>
                    </div>
                  </div>

                  {/* Actions */}
                  <div style={{padding:'12px 18px', borderTop: '1px solid #f0f4f8', display:'flex', flexWrap:'wrap', gap:8}}>
                    {!isCancelled && (
                      <button
                        style={mrBtn}
                        onClick={() => window.open(`https://maps.google.com/?q=${encodeURIComponent(r.address)}`, '_blank')}
                      >📍 Cómo llegar</button>
                    )}
                    <button
                      style={mrBtn}
                      onClick={() => alert(`Comprobante descargado\nReserva: ${r.id}\nBox: ${r.box}\nMonto: $${r.monto.toLocaleString()}`)}
                    >⬇ Comprobante</button>
                    {r.status === 'confirmed' && (
                      <button
                        style={{...mrBtn, background:'#fff0f0', color:'#c0392b', borderColor:'#f5c6cb'}}
                        onClick={() => onCancelar(r)}
                      >Cancelar</button>
                    )}
                    {r.status === 'completed' && (
                      r.rating ? (
                        <button
                          style={{...mrBtn, background:'#fff9e6', color:'#f39c12', borderColor:'#ffe58f', cursor:'default'}}
                          disabled
                        >⭐ {r.rating.toFixed(1)}/5</button>
                      ) : (
                        <button
                          style={{...mrBtn, background:'#e3f0fc', color:'#0984e3', borderColor:'#b8d8f5'}}
                          onClick={() => onCalificar(r)}
                        >Calificar ★</button>
                      )
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
};

const mrDetailCell = { display:'flex', flexDirection:'column', gap:2, minWidth:120 };
const mrDetailLabel = { fontSize:11, color:'#adb5bd', fontWeight:500 };
const mrDetailVal = { fontSize:13, fontWeight:600, color:'#2D3436' };
const mrBtn = { background:'#f8f9fa', border:'1px solid #dee2e6', borderRadius:8, padding:'7px 13px', fontSize:12, fontWeight:600, cursor:'pointer', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", color:'#2D3436' };
const mrSummaryCard = { background:'#fff', borderRadius:12, padding:16, border:'1px solid #e9ecef', textAlign:'center' };
const mrSummaryLabel = { fontSize:12, color:'#636e72', fontWeight:500, marginBottom:8 };
const mrFilterInput = { padding:'10px 12px', border:'1px solid #dee2e6', borderRadius:8, fontSize:13, fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", color:'#2D3436', background:'#fff', outline:'none' };

// ─── CANCELACION FLOW ─────────────────────────────────────────────────────────
const CancelacionFlow = ({ reserva, onBack, onCancelled, onBookingCancelled }) => {
  const [showConfirm, setShowConfirm] = React.useState(false);
  const [cancelled, setCancelled] = React.useState(false);

  const now = Date.now();
  const msUntil = reserva.fecha.getTime() - now;
  const hoursUntil = msUntil / (1000 * 60 * 60);

  let multa = 0, reembolso = reserva.monto, policy = '', policyColor = '#00b894';
  if (hoursUntil > 24) {
    multa = 0; reembolso = reserva.monto;
    policy = 'Más de 24h de anticipación — sin multa, reembolso total.';
    policyColor = '#00b894';
  } else if (hoursUntil >= 12) {
    multa = Math.round(reserva.monto * 0.5);
    reembolso = reserva.monto - multa;
    policy = 'Entre 12 y 24h — multa del 50%.';
    policyColor = '#f39c12';
  } else {
    multa = reserva.monto; reembolso = 0;
    policy = 'Menos de 12h — multa del 100%, sin reembolso.';
    policyColor = '#e74c3c';
  }

  const hoursDisplay = Math.abs(Math.floor(hoursUntil));
  const minutesDisplay = Math.abs(Math.floor((hoursUntil % 1) * 60));
  const pct = Math.min(100, Math.max(0, (hoursUntil / 48) * 100));

  const handleConfirm = async () => {
    console.log('🚀🚀🚀 handleConfirm CALLED 🚀🚀🚀');
    try {
      console.log('🔵 CancelacionFlow: Starting cancellation...', { reserva });

      const token = localStorage.getItem('lokat_token');
      if (!token) {
        alert('No token found. Please log in again.');
        setShowConfirm(false);
        return;
      }

      // Get the booking UUID (database ID) from reserva object
      const bookingId = reserva.uuid;

      console.log('🔵 CancelacionFlow: Making DELETE request for bookingId (uuid):', bookingId);

      const response = await fetchWithAuth(`https://lokat.fly.dev/api/bookings/${bookingId}`, {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
      });

      console.log('🔵 CancelacionFlow: DELETE response status:', response.status);

      if (!response.ok) {
        const errorData = await response.json();
        console.error('🔴 CancelacionFlow: DELETE error:', errorData);
        alert(`Error: ${errorData.error || 'Could not cancel booking'}`);
        setShowConfirm(false);
        return;
      }

      const data = await response.json();
      console.log('🔵 CancelacionFlow: Cancellation successful:', data);

      setShowConfirm(false);
      setCancelled(true);

      // Refetch bookings from parent component to update the list
      if (onBookingCancelled) {
        console.log('🔄 CancelacionFlow: Calling onBookingCancelled to refetch bookings');
        setTimeout(() => {
          onBookingCancelled();
        }, 1500); // Small delay to show success message before refetch
      }
    } catch (error) {
      if (error.sessionExpired) return;
      console.error('🔴 CancelacionFlow: Exception:', error);
      alert(`Error: ${error.message}`);
      setShowConfirm(false);
    }
  };

  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onBack();
  };

  if (cancelled) {
    return (
      <div style={pfStyles.page}>
        <ProfessionalHeader screenName="Reserva Cancelada" onLogout={handleLogout} onBack={onCancelled || onBack} />
        <div style={{maxWidth:460, margin:'0 auto', padding:'64px 20px', textAlign:'center', display:'flex', flexDirection:'column', alignItems:'center', gap:18}}>
          <div style={{width:76, height:76, borderRadius:'50%', background:'#f8d7da', display:'flex', alignItems:'center', justifyContent:'center', fontSize:34}}>✕</div>
          <h2 style={{fontSize:22, fontWeight:800, margin:0}}>Reserva cancelada</h2>
          <p style={{fontSize:14, color:'#636e72', margin:0}}>Tu reserva <strong>{reserva.id}</strong> ha sido cancelada.</p>
          <div style={{background:'#fff', borderRadius:16, padding:20, border:'1px solid #e9ecef', width:'100%', textAlign:'left'}}>
            <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f0f4f8', fontSize:14}}>
              <span style={{color:'#636e72'}}>Box</span><span style={{fontWeight:600}}>{reserva.box}</span>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f0f4f8', fontSize:14}}>
              <span style={{color:'#636e72'}}>Multa</span><span style={{fontWeight:700, color:'#e74c3c'}}>{multa > 0 ? `$${multa.toLocaleString()}` : 'Sin multa'}</span>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', fontSize:14}}>
              <span style={{color:'#636e72'}}>Reembolso</span>
              <span style={{fontWeight:700, color: reembolso > 0 ? '#00b894' : '#adb5bd'}}>
                {reembolso > 0 ? `$${reembolso.toLocaleString()}` : 'Sin reembolso'}
              </span>
            </div>
          </div>
          {reembolso > 0 && <p style={{fontSize:12, color:'#636e72', margin:0}}>El reembolso se acreditará en 3–5 días hábiles.</p>}
          <button style={{...pfStyles.confirmPrimBtn, padding:'13px 40px'}} onClick={onCancelled || onBack}>Volver a mis reservas</button>
        </div>
      </div>
    );
  }

  return (
    <div style={pfStyles.page}>
      <ProfessionalHeader screenName="Cancelar Reserva" onLogout={handleLogout} onBack={onBack} />

      <div style={{maxWidth:520, margin:'0 auto', padding:'20px 16px', display:'flex', flexDirection:'column', gap:16}}>
        {/* Reservation summary */}
        <div style={{background:'#fff', borderRadius:16, padding:'16px 18px', border:'1px solid #e9ecef'}}>
          <div style={{fontSize:16, fontWeight:700, marginBottom:6}}>{reserva.box}</div>
          <div style={{fontSize:13, color:'#636e72', marginBottom:4}}>
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#636e72" strokeWidth="2" style={{marginRight:4}}><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
            {reserva.address}
          </div>
          <div style={{fontSize:13, color:'#636e72'}}>
            Código: <strong style={{fontFamily:'monospace'}}>{reserva.id}</strong>
            {' · '}Monto: <strong style={{color:'#0984e3'}}>${reserva.monto.toLocaleString()}</strong>
          </div>
        </div>

        {/* Time bar */}
        <div style={{background:'#fff', borderRadius:16, padding:'18px 20px', border:'1px solid #e9ecef'}}>
          <div style={{display:'flex', justifyContent:'space-between', marginBottom:8, fontSize:13}}>
            <span style={{fontWeight:600, color:'#2D3436'}}>Tiempo hasta la reserva</span>
            <span style={{fontWeight:700, color: policyColor}}>
              {hoursUntil > 0 ? `${hoursDisplay}h ${minutesDisplay}m` : 'Ya pasó'}
            </span>
          </div>
          <div style={{height:8, background:'#e9ecef', borderRadius:4, overflow:'hidden', marginBottom:10}}>
            <div style={{height:'100%', width:`${pct}%`, background: policyColor, borderRadius:4, transition:'width 0.4s'}}></div>
          </div>
          <div style={{fontSize:13, color: policyColor, fontWeight:500}}>{policy}</div>
        </div>

        {/* Cost breakdown */}
        <div style={{background:'#fff', borderRadius:16, padding:'18px 20px', border:'1px solid #e9ecef'}}>
          <div style={{fontSize:14, fontWeight:700, marginBottom:14}}>Resumen económico</div>
          <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f0f4f8', fontSize:14}}>
            <span style={{color:'#636e72'}}>Monto pagado</span>
            <span style={{fontWeight:600}}>${reserva.monto.toLocaleString()}</span>
          </div>
          <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f0f4f8', fontSize:14}}>
            <span style={{color:'#636e72'}}>Multa por cancelación</span>
            <span style={{fontWeight:700, color: multa > 0 ? '#e74c3c' : '#adb5bd'}}>{multa > 0 ? `-$${multa.toLocaleString()}` : '$0'}</span>
          </div>
          <div style={{display:'flex', justifyContent:'space-between', padding:'10px 0 0', fontSize:15}}>
            <span style={{fontWeight:700}}>Reembolso</span>
            <span style={{fontWeight:800, color: reembolso > 0 ? '#00b894' : '#e74c3c', fontSize:18}}>
              {reembolso > 0 ? `$${reembolso.toLocaleString()}` : '$0'}
            </span>
          </div>
        </div>

        {/* Cancel button */}
        <button
          style={{width:'100%', background:'#e74c3c', color:'#fff', border:'none', borderRadius:12, padding:15, fontSize:15, fontWeight:700, cursor:'pointer', fontFamily:'inherit'}}
          onClick={() => { console.log('📍 "Cancelar reserva" button clicked, opening confirmation modal'); setShowConfirm(true); }}
        >Cancelar reserva</button>

        <p style={{textAlign:'center', fontSize:12, color:'#adb5bd', margin:0}}>Esta acción no se puede deshacer.</p>
      </div>

      {/* Confirmation modal */}
      {showConfirm && (
        <div style={{position:'fixed', inset:0, background:'rgba(0,0,0,0.45)', zIndex:200, display:'flex', alignItems:'center', justifyContent:'center', padding:20}}>
          <div style={{background:'#fff', borderRadius:20, padding:28, maxWidth:360, width:'100%', boxShadow:'0 16px 48px rgba(0,0,0,0.2)'}}>
            <div style={{fontSize:18, fontWeight:800, marginBottom:10}}>¿Estás seguro?</div>
            <p style={{fontSize:14, color:'#636e72', marginBottom:20, lineHeight:1.6}}>
              Esta acción no se puede deshacer.{reembolso > 0 ? ` Recibirás un reembolso de $${reembolso.toLocaleString()}.` : ' No recibirás reembolso.'}
            </p>
            <div style={{display:'flex', gap:10}}>
              <button style={{flex:1, background:'#f0f4f8', border:'none', borderRadius:10, padding:13, fontSize:14, fontWeight:600, cursor:'pointer', fontFamily:'inherit'}} onClick={() => { console.log('⬅️ "Mantener" button clicked, closing modal'); setShowConfirm(false); }}>Mantener</button>
              <button style={{flex:1, background:'#e74c3c', color:'#fff', border:'none', borderRadius:10, padding:13, fontSize:14, fontWeight:700, cursor:'pointer', fontFamily:'inherit'}} onClick={() => { console.log('✅ "Sí, cancelar" confirmation button clicked'); handleConfirm(); }}>Sí, cancelar</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

// ─── RATING FLOW ──────────────────────────────────────────────────────────────
const RatingFlow = ({ userType, reserva, onBack, onDone }) => {
  const [ratings, setRatings] = React.useState({
    punctuality: 5,
    cleanliness: 5,
    equipment: 5,
    communication: 5,
  });
  const [comment, setComment] = React.useState('');
  const [submitted, setSubmitted] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  const criterios = [
    { key: 'punctuality', label: 'Puntualidad', description: 'Llegada y atención a tiempo' },
    { key: 'cleanliness', label: 'Limpieza', description: 'Estado de limpieza del espacio' },
    { key: 'equipment', label: 'Equipamiento', description: 'Calidad y disponibilidad de equipos' },
    { key: 'communication', label: 'Comunicación', description: 'Claridad en la comunicación' },
  ];

  const averageScore = Math.round(
    Object.values(ratings).reduce((a, b) => a + b, 0) / Object.keys(ratings).length
  );

  const handleSubmit = async () => {
    try {
      console.log('🌟 RatingFlow: Submitting rating...', { userType, reserva, ratings, averageScore });

      const token = localStorage.getItem('lokat_token');
      if (!token) {
        alert('No token found. Please log in again.');
        return;
      }

      setLoading(true);

      // Determine the field name based on userType
      const ratingField = userType === 'professional' ? 'rating_by_professional' : 'rating_by_owner';
      const updateData = { [ratingField]: averageScore };

      // Add comment if provided
      if (comment.trim()) {
        updateData.rating_comment = comment.trim();
      }

      console.log('🌟 RatingFlow: Making PATCH request with:', updateData);

      const response = await fetchWithAuth(`https://lokat.fly.dev/api/bookings/${reserva.uuid}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(updateData),
      });

      console.log('🌟 RatingFlow: PATCH response status:', response.status);

      if (!response.ok) {
        const errorData = await response.json();
        console.error('🔴 RatingFlow: PATCH error:', errorData);
        alert(`Error: ${errorData.error || 'Could not submit rating'}`);
        return;
      }

      const data = await response.json();
      console.log('🌟 RatingFlow: Rating submitted successfully:', data);

      setSubmitted(true);
    } catch (error) {
      if (error.sessionExpired) return;
      console.error('🔴 RatingFlow: Exception:', error);
      alert(`Error: ${error.message}`);
    } finally {
      setLoading(false);
    }
  };

  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onBack();
  };

  if (submitted) {
    return (
      <div style={pfStyles.page}>
        <ProfessionalHeader screenName="Gracias por Valorar" onLogout={handleLogout} onBack={onDone} />
        <div style={{maxWidth:460, margin:'0 auto', padding:'64px 20px', textAlign:'center', display:'flex', flexDirection:'column', alignItems:'center', gap:18}}>
          <div style={{width:76, height:76, borderRadius:'50%', background:'#d4edda', display:'flex', alignItems:'center', justifyContent:'center', fontSize:34}}>✓</div>
          <h2 style={{fontSize:22, fontWeight:800, margin:0}}>Gracias por tu valoración</h2>
          <p style={{fontSize:14, color:'#636e72', margin:0}}>Tu evaluación ha sido registrada exitosamente.</p>
          <div style={{background:'#fff', borderRadius:16, padding:20, border:'1px solid #e9ecef', width:'100%', textAlign:'left'}}>
            <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', borderBottom:'1px solid #f0f4f8', fontSize:14}}>
              <span style={{color:'#636e72'}}>Box</span><span style={{fontWeight:600}}>{reserva.box}</span>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', padding:'8px 0', fontSize:14}}>
              <span style={{color:'#636e72'}}>Puntuación</span><span style={{fontWeight:700, color:'#f39c12'}}>★★★★★ ({averageScore}/5)</span>
            </div>
          </div>
          <button style={{...pfStyles.confirmPrimBtn, padding:'13px 40px'}} onClick={onDone}>Volver a mis reservas</button>
        </div>
      </div>
    );
  }

  return (
    <div style={pfStyles.page}>
      <ProfessionalHeader screenName="Valorar Reserva" onLogout={handleLogout} onBack={onBack} />

      <div style={{maxWidth:540, margin:'0 auto', padding:'20px 16px', display:'flex', flexDirection:'column', gap:16}}>
        {/* Reservation info */}
        <div style={{background:'#fff', borderRadius:16, padding:'16px 18px', border:'1px solid #e9ecef'}}>
          <div style={{fontSize:16, fontWeight:700, marginBottom:6}}>{reserva.box}</div>
          <div style={{fontSize:13, color:'#636e72', marginBottom:4}}>
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#636e72" strokeWidth="2" style={{marginRight:4}}><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/></svg>
            {reserva.address}
          </div>
          <div style={{fontSize:13, color:'#636e72'}}>
            Código: <strong style={{fontFamily:'monospace'}}>{reserva.id}</strong>
          </div>
        </div>

        {/* Rating criteria */}
        <div style={{background:'#fff', borderRadius:16, padding:'18px 20px', border:'1px solid #e9ecef'}}>
          <div style={{fontSize:14, fontWeight:700, marginBottom:16}}>¿Cómo fue tu experiencia?</div>

          {criterios.map(criterio => (
            <div key={criterio.key} style={{marginBottom:16}}>
              <div style={{display:'flex', justifyContent:'space-between', marginBottom:8}}>
                <div>
                  <div style={{fontSize:13, fontWeight:600, color:'#2D3436'}}>{criterio.label}</div>
                  <div style={{fontSize:12, color:'#636e72'}}>{criterio.description}</div>
                </div>
                <div style={{fontSize:14, fontWeight:700, color:'#f39c12'}}>{ratings[criterio.key]}</div>
              </div>
              <input
                type="range"
                min="1"
                max="5"
                value={ratings[criterio.key]}
                onChange={(e) => setRatings({...ratings, [criterio.key]: parseInt(e.target.value)})}
                style={{width:'100%', cursor:'pointer'}}
              />
              <div style={{display:'flex', justifyContent:'space-between', fontSize:11, color:'#adb5bd', marginTop:4}}>
                <span>Muy malo</span>
                <span>Excelente</span>
              </div>
            </div>
          ))}
        </div>

        {/* Average score */}
        <div style={{background:'#e3f0fc', borderRadius:16, padding:16, textAlign:'center', border:'1px solid #b8d8f5'}}>
          <div style={{fontSize:13, color:'#0984e3', marginBottom:4}}>Puntuación promedio</div>
          <div style={{fontSize:28, fontWeight:800, color:'#0984e3'}}>
            ★ {averageScore}/5
          </div>
        </div>

        {/* Comments section */}
        <div style={{background:'#fff', borderRadius:16, padding:'18px 20px', border:'1px solid #e9ecef'}}>
          <div style={{fontSize:13, fontWeight:600, color:'#2D3436', marginBottom:10}}>Comentario (opcional)</div>
          <textarea
            placeholder="Cuéntanos más sobre tu experiencia..."
            value={comment}
            onChange={(e) => setComment(e.target.value.substring(0, 500))}
            maxLength={500}
            style={{
              width:'100%',
              border:'1px solid #e9ecef',
              borderRadius:8,
              padding:'12px',
              fontSize:13,
              fontFamily:'inherit',
              resize:'vertical',
              minHeight:'100px',
              boxSizing:'border-box',
              color:'#2D3436',
              outline:'none',
              transition:'border-color 0.2s'
            }}
            onFocus={(e) => e.target.style.borderColor = '#0984e3'}
            onBlur={(e) => e.target.style.borderColor = '#e9ecef'}
          />
          <div style={{fontSize:11, color:'#adb5bd', marginTop:6}}>{comment.length}/500</div>
        </div>

        {/* Submit button */}
        <button
          style={{width:'100%', background:'#0984e3', color:'#fff', border:'none', borderRadius:12, padding:15, fontSize:15, fontWeight:700, cursor:'pointer', fontFamily:'inherit', opacity: loading ? 0.7 : 1}}
          onClick={handleSubmit}
          disabled={loading}
        >
          {loading ? 'Enviando...' : 'Enviar valoración'}
        </button>
      </div>
    </div>
  );
};

// ─── PROFESSIONAL DASHBOARD ────────────────────────────────────────────────────
const ProfessionalDashboard = ({ onSearch, onMisReservas, onSettings, onBack }) => {
  const isMobile = useWindowWidth() <= 768;
  const [bookings, setBookings] = React.useState([]);
  const [calendarMonth, setCalendarMonth] = React.useState(new Date());
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  const [selectedBooking, setSelectedBooking] = React.useState(null);
  const [activeNav, setActiveNav] = React.useState('dashboard');
  // Sub-step state for the booking flow started inside the dashboard
  const [dashSubStep, setDashSubStep] = React.useState(null); // null | 'sis' | 'slots' | 'confirm' | 'cancelacion' | 'rating'
  const [dashSelectedBox, setDashSelectedBox] = React.useState(null);
  const [dashBooking, setDashBooking] = React.useState(null);
  const [cancelReservaData, setCancelReservaData] = React.useState(null);
  const [ratingReservaData, setRatingReservaData] = React.useState(null);

  // Get logged-in user from localStorage
  const userJson = localStorage.getItem('lokat_user');
  const user = userJson ? JSON.parse(userJson) : null;

  // Get full name from either fullName or full_name field
  const fullName = user?.fullName || user?.full_name || user?.email || 'Profesional';
  console.log('📊 ProfessionalDashboard - User data from localStorage:', { userJson, user, fullName });
  const userInitials = fullName === 'Profesional'
    ? 'P'
    : fullName.split(' ').map(n => n[0]).join('').toUpperCase().substring(0, 2);

  // Fetch recent bookings
  React.useEffect(() => {
    const fetchBookings = async () => {
      try {
        setLoading(true);
        const token = localStorage.getItem('lokat_token');
        if (!token) throw new Error('No token');

        const response = await fetchWithAuth('https://lokat.fly.dev/api/bookings/my', {});

        if (!response.ok) throw new Error('Failed to fetch bookings');
        const data = await response.json();

        // Sort by date and take last 3
        const sorted = data.sort((a, b) => new Date(b.booked_at) - new Date(a.booked_at)).slice(0, 3);
        setBookings(sorted);
        setError(null);
      } catch (err) {
        if (err.sessionExpired) return;
        console.error('Error fetching bookings:', err);
        setError(err.message);
        setBookings([]);
      } finally {
        setLoading(false);
      }
    };

    fetchBookings();
  }, []);

  // Calculate KPIs
  const totalReservas = bookings.length;
  const proximaReserva = bookings
    .filter(b => new Date(b.date) > new Date())
    .sort((a, b) => new Date(a.date) - new Date(b.date))[0];
  const gastoTotal = bookings.reduce((sum, b) => sum + (b.total_amount || 0), 0);

  const handleLogout = () => {
    localStorage.removeItem('lokat_token');
    localStorage.removeItem('lokat_user');
    onBack();
  };

  // ── Box selection from the inline search tab ────────────────────────────────
  const handleSelectBoxInDash = (box) => {
    setDashSelectedBox(box);
    setDashSubStep('sis');
  };

  // ── Dashboard tab content (KPIs + bookings + calendar) ────────────────────
  const dashboardContent = (
    <>
      {/* KPI Cards */}
      <div style={{display:'grid', gridTemplateColumns: isMobile ? 'repeat(2,1fr)' : 'repeat(3,1fr)', gap:16, marginBottom:24}}>
        <div style={pfStyles.dashKPI}>
          <div style={pfStyles.dashKPIValue}>{totalReservas}</div>
          <div style={pfStyles.dashKPILabel}>Reservas totales</div>
        </div>
        <div style={pfStyles.dashKPI}>
          <div style={pfStyles.dashKPIValue}>${gastoTotal.toLocaleString('es-CL')}</div>
          <div style={pfStyles.dashKPILabel}>Gasto total</div>
        </div>
        <div style={pfStyles.dashKPI}>
          <div style={pfStyles.dashKPIValue}>
            {proximaReserva
              ? new Date(proximaReserva.date).toLocaleDateString('es-CL', {month:'short', day:'numeric'})
              : '—'}
          </div>
          <div style={pfStyles.dashKPILabel}>Próxima reserva</div>
        </div>
      </div>

      {/* Two-Column Layout: Recent Bookings + Calendar */}
      <div style={{display:'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap:16}}>

        {/* LEFT COLUMN: Recent Bookings */}
        <div>
          <div style={pfStyles.sectionTitle}>Últimas reservas</div>
          {loading && <div style={{textAlign:'center', padding:'40px 20px', color:'#636e72', fontSize:14, fontWeight:600}}>Cargando...</div>}
          {error && <div style={{textAlign:'center', padding:'40px 20px', color:'#e74c3c', fontSize:12, fontWeight:600}}>Error al cargar</div>}
          {!loading && !error && bookings.length === 0 && (
            <div style={{textAlign:'center', padding:'40px 20px', color:'#636e72', fontSize:13, fontWeight:600}}>No hay reservas</div>
          )}
          {!loading && !error && bookings.length > 0 && (
            <div style={{display:'flex', flexDirection:'column', gap:12}}>
              {bookings.slice(0,3).map((booking) => (
                <div key={booking.id} style={pfStyles.bookingCardPro}>
                  <div style={{flex:1}}>
                    <div style={pfStyles.bookingCardBoxName}>{booking.boxes?.name || 'Box'}</div>
                    <div style={pfStyles.bookingCardDate}>
                      {new Date(booking.date).toLocaleDateString('es-CL', {weekday:'short', year:'numeric', month:'short', day:'numeric'})}
                      {booking.slot && <span> • {fmtSlot(booking.slot)}</span>}
                    </div>
                    <div style={pfStyles.bookingCardStatus}>
                      {booking.status === 'confirmed'  && <span style={{color:'#27ae60'}}>✓ Confirmada</span>}
                      {booking.status === 'pending'    && <span style={{color:'#f39c12'}}>⏳ Pendiente</span>}
                      {booking.status === 'completed'  && <span style={{color:'#636e72'}}>✓ Completada</span>}
                      {booking.status === 'cancelled'  && <span style={{color:'#e74c3c'}}>✕ Cancelada</span>}
                    </div>
                  </div>
                  <div style={{textAlign:'right', flexShrink:0}}>
                    <div style={pfStyles.bookingCardPrice}>${(booking.total_amount || 0).toLocaleString('es-CL')}</div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* RIGHT COLUMN: Calendar */}
        <div>
          <div style={pfStyles.sectionTitle}>Calendario</div>
          <div style={pfStyles.calendarCard}>
            {(() => {
              const now = new Date();
              const year = calendarMonth.getFullYear();
              const month = calendarMonth.getMonth();
              const firstDay = new Date(year, month, 1);
              const lastDay = new Date(year, month + 1, 0);
              const daysInMonth = lastDay.getDate();
              const startingDayOfWeek = firstDay.getDay();
              const bookingsByDate = new Map();
              bookings.forEach(b => {
                const bd = new Date(b.date);
                const key = `${bd.getFullYear()}-${bd.getMonth()}-${bd.getDate()}`;
                if (!bookingsByDate.has(key)) bookingsByDate.set(key, []);
                bookingsByDate.get(key).push(b);
              });
              const dayNames = ['Dom','Lun','Mar','Mié','Jue','Vie','Sáb'];
              const monthName = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'][month];
              const calendarDays = [];
              for (let i = 0; i < startingDayOfWeek; i++) calendarDays.push(null);
              for (let d = 1; d <= daysInMonth; d++) calendarDays.push(d);
              return (
                <>
                  <div style={pfStyles.calendarHeader}>
                    <div style={{display:'flex', alignItems:'center', justifyContent:'space-between'}}>
                      <button onClick={() => setCalendarMonth(new Date(year, month - 1, 1))} style={{background:'none', border:'none', cursor:'pointer', fontSize:18, padding:'0 8px'}}>‹</button>
                      <div style={{fontSize:14, fontWeight:700, color:'#2D3436'}}>{monthName} {year}</div>
                      <button onClick={() => setCalendarMonth(new Date(year, month + 1, 1))} style={{background:'none', border:'none', cursor:'pointer', fontSize:18, padding:'0 8px'}}>›</button>
                    </div>
                  </div>
                  <div style={pfStyles.calendarDayNames}>
                    {dayNames.map(day => <div key={day} style={pfStyles.calendarDayName}>{day}</div>)}
                  </div>
                  <div style={pfStyles.calendarGrid}>
                    {calendarDays.map((day, idx) => {
                      if (day === null) return <div key={`empty-${idx}`} style={pfStyles.calendarEmptyCell}></div>;
                      const key = `${year}-${month}-${day}`;
                      const dayBookings = bookingsByDate.get(key) || [];
                      const bookingStatus = dayBookings.length > 0
                        ? (dayBookings.some(b => new Date(b.date) > now) ? 'upcoming' : 'past')
                        : null;
                      return (
                        <div key={day}
                          onClick={() => dayBookings.length > 0 && setSelectedBooking(dayBookings)}
                          style={{...pfStyles.calendarDayCell, ...(bookingStatus==='upcoming' ? pfStyles.calendarDayUpcoming : {}), ...(bookingStatus==='past' ? pfStyles.calendarDayPast : {}), ...(dayBookings.length > 0 ? {cursor:'pointer', position:'relative'} : {})}}
                        >
                          {day}
                          {dayBookings.length > 1 && <div style={pfStyles.bookingBadge}>{dayBookings.length}</div>}
                        </div>
                      );
                    })}
                  </div>
                  <div style={pfStyles.calendarLegend}>
                    <div style={{display:'flex', alignItems:'center', gap:6, fontSize:12}}>
                      <div style={{width:12, height:12, background:'#0984e3', borderRadius:3}}></div><span>Próximas</span>
                    </div>
                    <div style={{display:'flex', alignItems:'center', gap:6, fontSize:12}}>
                      <div style={{width:12, height:12, background:'#bdc3c7', borderRadius:3}}></div><span>Pasadas</span>
                    </div>
                  </div>
                </>
              );
            })()}
          </div>
        </div>
      </div>

      {/* Booking Details Modal */}
      {selectedBooking && (
        <div style={pfStyles.modalOverlay} onClick={() => setSelectedBooking(null)}>
          <div style={pfStyles.modalContent} onClick={e => e.stopPropagation()}>
            <button style={pfStyles.modalCloseBtn} onClick={() => setSelectedBooking(null)} title="Cerrar">✕</button>
            <div style={pfStyles.modalHeader}>
              <div style={pfStyles.modalTitle}>
                {selectedBooking.length === 1 ? 'Detalles de la Reserva' : `Reservas del día (${selectedBooking.length})`}
              </div>
            </div>
            <div style={pfStyles.modalBody}>
              <div style={{display:'flex', flexDirection:'column', gap: selectedBooking.length > 1 ? 16 : 0}}>
                {selectedBooking.map((booking, idx) => (
                  <div key={booking.id || idx} style={selectedBooking.length > 1 ? pfStyles.bookingDetailCard : {}}>
                    <div style={pfStyles.modalSection}><div style={pfStyles.modalLabel}>Código de Reserva</div><div style={pfStyles.modalValue}>{booking.booking_code || 'N/A'}</div></div>
                    <div style={pfStyles.modalSection}><div style={pfStyles.modalLabel}>Box</div><div style={pfStyles.modalValue}>{booking.boxes?.name || 'Box'}</div></div>
                    <div style={pfStyles.modalSection}><div style={pfStyles.modalLabel}>Dirección</div><div style={pfStyles.modalValue}>{booking.boxes?.address || 'N/A'}</div></div>
                    <div style={pfStyles.modalSection}>
                      <div style={pfStyles.modalLabel}>Fecha y Hora</div>
                      <div style={pfStyles.modalValue}>
                        {new Date(booking.date).toLocaleDateString('es-CL', {weekday:'long', year:'numeric', month:'long', day:'numeric'})}
                        {booking.slot && <div style={{fontSize:12, color:'#636e72', marginTop:4}}>{fmtSlot(booking.slot)}</div>}
                      </div>
                    </div>
                    <div style={pfStyles.modalSection}><div style={pfStyles.modalLabel}>Monto</div><div style={{...pfStyles.modalValue, color:'#0984e3', fontWeight:700, fontSize:18}}>${(booking.total_amount || 0).toLocaleString('es-CL')}</div></div>
                    <div style={pfStyles.modalSection}>
                      <div style={pfStyles.modalLabel}>Estado</div>
                      <div style={{...pfStyles.modalValue, fontWeight:600}}>
                        {booking.status === 'confirmed' && <span style={{color:'#27ae60'}}>✓ Confirmada</span>}
                        {booking.status === 'pending'   && <span style={{color:'#f39c12'}}>⏳ Pendiente</span>}
                        {booking.status === 'completed' && <span style={{color:'#636e72'}}>✓ Completada</span>}
                        {booking.status === 'cancelled' && <span style={{color:'#e74c3c'}}>✕ Cancelada</span>}
                      </div>
                    </div>
                    {booking.boxes?.arrival_instructions && (
                      <div style={{background:'#fff8e1', border:'1.5px solid #f39c12', borderRadius:10, padding:'12px 14px', marginTop:8}}>
                        <div style={{fontWeight:700, color:'#856404', fontSize:12, marginBottom:5}}>📍 Indicaciones de llegada</div>
                        <div style={{fontSize:13, color:'#555', lineHeight:1.6, whiteSpace:'pre-wrap'}}>{booking.boxes.arrival_instructions}</div>
                      </div>
                    )}
                  </div>
                ))}
              </div>
            </div>
            <div style={pfStyles.modalFooter}>
              <button style={pfStyles.modalCloseActionBtn} onClick={() => setSelectedBooking(null)}>Cerrar</button>
            </div>
          </div>
        </div>
      )}
    </>
  );

  // ── Sidebar (shared by all tabs) ─────────────────────────────────────────────
  const sidebarIcons = {
    dashboard: (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
        <polyline points="9 22 9 12 15 12 15 22"/>
      </svg>
    ),
    buscar: (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <circle cx="11" cy="11" r="8"/>
        <line x1="21" y1="21" x2="16.65" y2="16.65"/>
      </svg>
    ),
    reservas: (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <rect x="3" y="4" width="18" height="18" rx="2"/>
        <line x1="16" y1="2" x2="16" y2="6"/>
        <line x1="8" y1="2" x2="8" y2="6"/>
        <line x1="3" y1="10" x2="21" y2="10"/>
      </svg>
    ),
    ajustes: (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <circle cx="12" cy="12" r="3"/>
        <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
      </svg>
    ),
  };

  const sidebar = !isMobile && (
    <aside style={{width:220, background:'#fff', borderRight:'1px solid #e9ecef', display:'flex', flexDirection:'column', position:'fixed', top:40, left:0, height:'calc(100vh - 40px)', zIndex:100}}>
      <div style={{padding:'24px 20px 16px', borderBottom:'1px solid #e9ecef'}}>
        <div style={{fontSize:22, fontWeight:800, color:'#2D3436', letterSpacing:-0.5}}>Lokat</div>
        <div style={{fontSize:11, color:'#adb5bd', marginTop:2}}>Dashboard profesional</div>
      </div>
      <nav style={{flex:1, padding:'12px 8px'}}>
        {[
          {id:'dashboard', label:'Inicio'},
          {id:'buscar',    label:'Buscar box'},
          {id:'reservas',  label:'Mis reservas'},
          {id:'ajustes',   label:'Ajustes'},
        ].map(item => (
          <button key={item.id}
            onClick={() => { setActiveNav(item.id); setDashSubStep(null); }}
            style={{
              width:'100%', display:'flex', alignItems:'center', gap:10,
              padding:'10px 12px', borderRadius:8,
              background: activeNav===item.id ? '#f0f7ff' : 'none',
              border:'none',
              color: activeNav===item.id ? '#0984e3' : '#636e72',
              cursor:'pointer', fontFamily:'inherit', fontSize:14,
              fontWeight: activeNav===item.id ? 600 : 400,
              textAlign:'left', marginBottom:2,
            }}
          >
            <span style={{display:'flex', alignItems:'center', flexShrink:0}}>{sidebarIcons[item.id]}</span>
            <span>{item.label}</span>
          </button>
        ))}
      </nav>
      <div style={{padding:'16px 20px', borderTop:'1px solid #e9ecef'}}>
        <div style={{fontSize:12, color:'#636e72', marginBottom:8, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{fullName}</div>
        {user?.rnpi_declared === true && (
          <div style={{fontSize:10, fontWeight:600, color:'#27ae60', background:'rgba(39,174,96,0.15)', padding:'2px 8px', borderRadius:20, letterSpacing:0.3, marginBottom:8, display:'inline-block'}}>
            Verificado RNPI ✓
          </div>
        )}
        <button onClick={handleLogout} style={{background:'none', border:'1px solid #e9ecef', color:'#636e72', borderRadius:6, padding:'6px 12px', fontSize:12, cursor:'pointer', fontFamily:'inherit', width:'100%'}}>
          Cerrar sesión
        </button>
      </div>
    </aside>
  );

  const mainStyle = {marginLeft: isMobile ? 0 : 220, flex:1, minHeight:'100vh', display:'flex', flexDirection:'column'};

  // ── Booking sub-steps (SIS → Slots → Confirm) inside dashboard ───────────────
  if (activeNav === 'buscar' && dashSubStep === 'sis') return (
    <div style={{display:'flex', minHeight:'100vh', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", background:'#f4f5f7'}}>
      {sidebar}
      <main style={mainStyle}>
        <SISVerification box={dashSelectedBox} onVerified={() => setDashSubStep('slots')} onBack={() => setDashSubStep(null)} />
      </main>
    </div>
  );
  if (activeNav === 'buscar' && dashSubStep === 'slots') return (
    <div style={{display:'flex', minHeight:'100vh', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", background:'#f4f5f7'}}>
      {sidebar}
      <main style={mainStyle}>
        <TimeSlotGrid box={dashSelectedBox} onBooked={b => { setDashBooking(b); setDashSubStep('confirm'); }} onBack={() => setDashSubStep('sis')} />
      </main>
    </div>
  );
  if (activeNav === 'buscar' && dashSubStep === 'confirm') return (
    <div style={{display:'flex', minHeight:'100vh', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", background:'#f4f5f7'}}>
      {sidebar}
      <main style={mainStyle}>
        <BookingConfirmation
          booking={dashBooking}
          onHome={() => { setDashSubStep(null); setActiveNav('dashboard'); }}
          onMisReservas={() => { setDashSubStep(null); setActiveNav('reservas'); }}
        />
      </main>
    </div>
  );
  if (activeNav === 'reservas' && dashSubStep === 'cancelacion') return (
    <div style={{display:'flex', minHeight:'100vh', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", background:'#f4f5f7'}}>
      {sidebar}
      <main style={mainStyle}>
        <CancelacionFlow reserva={cancelReservaData} onBack={() => setDashSubStep(null)} onCancelled={() => setDashSubStep(null)} />
      </main>
    </div>
  );
  if (activeNav === 'reservas' && dashSubStep === 'rating') return (
    <div style={{display:'flex', minHeight:'100vh', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", background:'#f4f5f7'}}>
      {sidebar}
      <main style={mainStyle}>
        <RatingFlow userType="professional" reserva={ratingReservaData} onBack={() => setDashSubStep(null)} onDone={() => setDashSubStep(null)} />
      </main>
    </div>
  );

  return (
    <div style={{display:'flex', minHeight:'100vh', fontFamily:"'Helvetica Neue',Helvetica,Arial,sans-serif", background:'#f4f5f7'}}>
      {sidebar}

      <main style={mainStyle}>

        {/* ── Tab: Buscar box ── */}
        {activeNav === 'buscar' && (
          <SearchResults
            onSelect={handleSelectBoxInDash}
            onBack={() => { setActiveNav('dashboard'); setDashSubStep(null); }}
            isLoggedIn={true}
            onMisReservas={() => { setActiveNav('reservas'); setDashSubStep(null); }}
          />
        )}

        {/* ── Tab: Mis reservas ── */}
        {activeNav === 'reservas' && (
          <MisReservas
            onBack={() => { setActiveNav('dashboard'); setDashSubStep(null); }}
            onCancelar={r => { setCancelReservaData(r); setDashSubStep('cancelacion'); }}
            onCalificar={r => { setRatingReservaData(r); setDashSubStep('rating'); }}
          />
        )}

        {/* ── Tab: Ajustes ── */}
        {activeNav === 'ajustes' && (
          <ProfileSettings onBack={() => setActiveNav('dashboard')} userRole="professional" />
        )}

        {/* ── Tab: Inicio (dashboard) ── */}
        {activeNav === 'dashboard' && (
          <>
            {/* Top header */}
            <div style={{background:'#fff', borderBottom:'1px solid #e9ecef', padding:'16px 24px', display:'flex', justifyContent:'space-between', alignItems:'center', position:'sticky', top:40, zIndex:50}}>
              <div>
                <div style={{fontSize:18, fontWeight:700, color:'#1a1d23'}}>Inicio</div>
                <div style={{fontSize:12, color:'#adb5bd', marginTop:2}}>Buenos días, {fullName.split(' ')[0]} 👋</div>
              </div>
              <div style={{display:'flex', alignItems:'center', gap:10}}>
                {isMobile && (
                  <>
                    <button style={{background:'none', border:'1px solid #e9ecef', padding:'6px 10px', borderRadius:6, cursor:'pointer', color:'#636e72', fontSize:15}} onClick={() => setActiveNav('ajustes')} title="Ajustes">⚙️</button>
                    <button style={{background:'none', border:'none', color:'#adb5bd', padding:'6px 4px', borderRadius:6, fontSize:12, cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:4}} onClick={handleLogout}>
                      <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/></svg>
                      Salir
                    </button>
                  </>
                )}
                <div style={{width:36, height:36, borderRadius:'50%', background:'#0984e3', color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontWeight:700, fontSize:14}}>{userInitials}</div>
              </div>
            </div>
            {/* Dashboard content */}
            <div style={{padding:24, flex:1}}>
              {dashboardContent}
            </div>
          </>
        )}

      </main>
    </div>
  );
};

// ─── PROFESSIONAL FLOW ORCHESTRATOR ──────────────────────────────────────────
const ProfessionalFlow = ({ onBack, isLoggedIn: initialLoggedIn = false, initialStep = 'search' }) => {
  // Check localStorage directly for token presence
  const tokenExists = !!localStorage.getItem('lokat_token');
  const userExists = !!localStorage.getItem('lokat_user');
  const hasValidAuth = tokenExists && userExists;

  // Determine initial step based on localStorage token, not prop
  const effectiveInitialStep = hasValidAuth ? 'dashboard' : initialStep;

  console.log('🎬 ProfessionalFlow orchestrator mounted');
  console.log('   Token exists:', tokenExists);
  console.log('   User exists:', userExists);
  console.log('   Initial step:', initialStep);
  console.log('   Effective initial step:', effectiveInitialStep);

  const [step, setStep] = React.useState(effectiveInitialStep); // dashboard | search | auth-gate | sis | slots | confirm | mis-reservas | cancelacion | rating-prof
  const [selectedBox, setSelectedBox] = React.useState(null);
  const [booking, setBooking] = React.useState(null);
  const [isLoggedIn, setIsLoggedIn] = React.useState(!!localStorage.getItem('lokat_token'));

  // Use refs for reserva data so they persist across component remounts
  const cancelReservaRef = React.useRef(null);
  const ratingReservaRef = React.useRef(null);

  // Log step changes
  React.useEffect(() => {
    console.log('📍 ProfessionalFlow step changed to:', step);
  }, [step]);

  // Handle initialStep prop changes (when navigating between search and mis-reservas)
  React.useEffect(() => {
    console.log('🔄 initialStep prop changed to:', initialStep);
    setStep(initialStep);
  }, [initialStep]);

  const handleSelectBox = (box) => {
    setSelectedBox(box);
    if (!isLoggedIn) {
      console.log('🔐 Box selected, redirecting to auth-gate (not logged in)');
      setStep('auth-gate');
    } else {
      console.log('✅ Box selected, redirecting to sis (logged in)');
      setStep('sis');
    }
  };

  if (step === 'dashboard') return (
    <ProfessionalDashboard
      onSearch={() => { console.log('🔍 Search clicked from dashboard'); setStep('search'); }}
      onMisReservas={() => { console.log('📋 Mis Reservas clicked from dashboard'); setStep('mis-reservas'); }}
      onSettings={() => { console.log('⚙️ Settings clicked from dashboard'); setStep('settings'); }}
      onBack={onBack}
    />
  );
  if (step === 'search') return (
    <SearchResults
      onSelect={handleSelectBox}
      onBack={() => {
        if (isLoggedIn) {
          console.log('⬅️ Back to dashboard from search');
          setStep('dashboard');
        } else {
          console.log('⬅️ Back to landing from search');
          onBack();
        }
      }}
      isLoggedIn={isLoggedIn}
      onMisReservas={() => { console.log('📋 "Mis Reservas" button clicked from search'); setStep('mis-reservas'); }}
    />
  );
  if (step === 'auth-gate') return (
    <AuthFlow
      onSuccess={() => { console.log('✅ Auth successful, moving to dashboard'); setIsLoggedIn(true); setStep('dashboard'); }}
      onBack={() => setStep('search')}
      context="booking"
      box={selectedBox}
    />
  );
  if (step === 'sis') return <SISVerification box={selectedBox} onVerified={() => { console.log('✅ SIS verified, moving to slots'); setStep('slots'); }} onBack={() => setStep('search')} />;
  if (step === 'slots') return <TimeSlotGrid box={selectedBox} onBooked={b => { console.log('✅ Booking confirmed, moving to confirm'); setBooking(b); setStep('confirm'); }} onBack={() => setStep('sis')} />;
  if (step === 'confirm') return (
    <BookingConfirmation
      booking={booking}
      onHome={onBack}
      onMisReservas={() => { console.log('📋 User clicked "Ver mis reservas", moving to mis-reservas'); setStep('mis-reservas'); }}
    />
  );
  if (step === 'mis-reservas') {
    console.log('📋 Rendering MisReservas component');
    return (
      <MisReservas
        onBack={() => {
          if (isLoggedIn) {
            console.log('⬅️ Back to dashboard from mis-reservas');
            setStep('dashboard');
          } else {
            console.log('⬅️ Back to search from mis-reservas');
            setStep('search');
          }
        }}
        onCancelar={(r) => { console.log('🚫 Cancelling reserva:', r.id); cancelReservaRef.current = r; setStep('cancelacion'); }}
        onCalificar={(r) => { console.log('⭐ Rating reserva:', r.id); ratingReservaRef.current = r; setStep('rating-prof'); }}
      />
    );
  }
  if (step === 'cancelacion') return (
    <CancelacionFlow
      reserva={cancelReservaRef.current}
      onBack={() => setStep('mis-reservas')}
      onCancelled={() => setStep('mis-reservas')}
    />
  );
  if (step === 'rating-prof') return (
    <RatingFlow
      userType="professional"
      reserva={ratingReservaRef.current}
      onBack={() => setStep('mis-reservas')}
      onDone={() => setStep('mis-reservas')}
    />
  );
  if (step === 'settings') return (
    <ProfileSettings
      onBack={() => { console.log('⬅️ Back to dashboard from settings'); setStep('dashboard'); }}
      userRole="professional"
    />
  );
};

// ─── SHARED STYLES ────────────────────────────────────────────────────────────
const pfStyles = {
  page: { minHeight: '100vh', background: '#f4f5f7', fontFamily: "'Helvetica Neue', Helvetica, Arial, sans-serif", color: '#2D3436', lineHeight: 1.6, overflowX: 'hidden' },
  topBar: { background: '#fff', borderBottom: '1px solid #f0f0f0', display: 'flex', alignItems: 'center', gap: 12, padding: '0 16px', height: 60, position: 'sticky', top: 0, zIndex: 50 },
  backBtn: { width: 34, height: 34, borderRadius: 7, border: '1px solid #e9ecef', background: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', flexShrink: 0, color: '#636e72' },
  // Dashboard styles (header moved to inline JSX)
  dashHeader: { background: '#fff', borderBottom: '1px solid #f0f0f0', padding: '16px 20px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16 },
  dashHeaderContent: { display: 'flex', alignItems: 'center', gap: 14, flex: 1 },
  userAvatar: { width: 38, height: 38, background: '#1a1d23', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, fontWeight: 600, color: '#fff', flexShrink: 0 },
  dashGreeting: { fontSize: 15, fontWeight: 600, color: '#1a1d23', marginBottom: 2 },
  dashSubtitle: { fontSize: 12, color: '#adb5bd' },
  dashKPIContainer: { display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, padding: '16px', background: '#f4f5f7' },
  dashKPI: { background: '#fff', borderRadius: 12, padding: 16, textAlign: 'center', border: '1px solid #ebebeb', boxShadow: '0 2px 12px rgba(0,0,0,0.06)' },
  dashKPIValue: { fontSize: 24, fontWeight: 600, color: '#1a1d23', marginBottom: 4 },
  dashKPILabel: { fontSize: 12, color: '#adb5bd', fontWeight: 500 },
  dashActionsContainer: { display: 'flex', gap: 10, padding: '0 16px 16px', justifyContent: 'center' },
  dashActionBtn: { background: '#fff', color: '#1a1d23', border: '1.5px solid #e9ecef', borderRadius: 20, padding: '8px 20px', fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit', transition: 'all 0.15s' },
  sectionTitle: { fontSize: 15, fontWeight: 600, marginBottom: 12, color: '#2D3436' },
  bookingCardPro: { background: '#fff', borderRadius: 12, padding: 14, border: '1px solid #ebebeb', boxShadow: '0 2px 12px rgba(0,0,0,0.06)', display: 'flex', alignItems: 'flex-start', gap: 12 },
  bookingCardBoxName: { fontSize: 14, fontWeight: 600, color: '#2D3436', marginBottom: 4 },
  bookingCardDate: { fontSize: 12, color: '#636e72', marginBottom: 6, lineHeight: 1.6 },
  bookingCardStatus: { fontSize: 11, fontWeight: 600 },
  bookingCardPrice: { fontSize: 18, fontWeight: 600, color: '#1a1d23' },
  bookingCardPriceLabel: { fontSize: 11, color: '#adb5bd' },
  // Calendar styles
  calendarCard: { background: '#fff', borderRadius: 12, padding: 16, border: '1px solid #e9ecef' },
  calendarHeader: { marginBottom: 16, textAlign: 'center' },
  calendarDayNames: { display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4, marginBottom: 8 },
  calendarDayName: { textAlign: 'center', fontSize: 11, fontWeight: 600, color: '#636e72', padding: 4 },
  calendarGrid: { display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4, marginBottom: 12 },
  calendarEmptyCell: { aspectRatio: '1', background: 'transparent' },
  calendarDayCell: { aspectRatio: '1', display: 'flex', alignItems: 'center', justifyContent: 'center', borderRadius: 6, background: '#f8f9fa', fontSize: 12, fontWeight: 600, color: '#2D3436', border: '1px solid #e9ecef' },
  calendarDayUpcoming: { background: '#0984e3', color: '#fff', border: '1px solid #0984e3', fontWeight: 700 },
  calendarDayPast: { background: '#bdc3c7', color: '#fff', border: '1px solid #bdc3c7', opacity: 0.7 },
  calendarLegend: { display: 'flex', gap: 16, justifyContent: 'center', fontSize: 12, color: '#636e72' },
  searchMini: { flex: 1, display: 'flex', alignItems: 'center', gap: 8, background: '#f8f9fa', borderRadius: 8, padding: '8px 12px', border: '1px solid #e9ecef' },
  searchMiniInput: { border: 'none', outline: 'none', background: 'transparent', fontSize: 14, color: '#2D3436', fontFamily: 'inherit', flex: 1 },
  sortSelect: { background: '#fff', border: '1px solid #dee2e6', borderRadius: 8, padding: '6px 10px', fontSize: 13, color: '#2D3436', fontFamily: 'inherit', cursor: 'pointer' },
  topBarTitle: { flex: 1, fontSize: 16, fontWeight: 700 },
  stepIndicator: { fontSize: 12, color: '#0984e3', fontWeight: 600, background: '#e3f0fc', padding: '4px 10px', borderRadius: 12 },
  filterRow: { display: 'flex', gap: 8, padding: '12px 16px', overflowX: 'auto', background: '#f4f5f7' },
  filterPill: { background: '#fff', border: '1px solid #e9ecef', borderRadius: 20, padding: '6px 16px', fontSize: 13, cursor: 'pointer', fontFamily: 'inherit', whiteSpace: 'nowrap', color: '#636e72' },
  filterPillActive: { background: '#1a1d23', color: '#fff', borderColor: '#1a1d23', fontWeight: 600 },
  resultsCount: { padding: '0 16px 8px', fontSize: 13, color: '#adb5bd', background: '#f4f5f7' },
  cardList: { padding: '0 16px 24px', background: '#f4f5f7' },
  card: { background: '#fff', borderRadius: 12, overflow: 'hidden', boxShadow: '0 2px 12px rgba(0,0,0,0.06)', border: '1px solid #ebebeb', transition: 'box-shadow 0.2s, transform 0.2s', cursor: 'pointer' },
  cardHover: { boxShadow: '0 6px 24px rgba(0,0,0,0.10)', transform: 'translateY(-2px)' },
  cardImg: { height: 140, background: '#f0f4f8', display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative', borderBottom: '1px solid #e9ecef' },
  cardImgPlaceholder: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, opacity: 0.5 },
  cardImgLabel: { fontSize: 11, color: '#adb5bd', fontFamily: 'monospace', textTransform: 'uppercase', letterSpacing: 1 },
  availBadge: { position: 'absolute', top: 10, right: 10, borderRadius: 20, padding: '4px 10px', fontSize: 12, fontWeight: 600 },
  cardBody: { padding: 16 },
  cardHeader: { display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 12, gap: 12 },
  cardName: { fontSize: 15, fontWeight: 600, marginBottom: 4 },
  cardLoc: { fontSize: 12, color: '#adb5bd', display: 'flex', alignItems: 'center', gap: 4, lineHeight: 1.6 },
  cardPriceBlock: { textAlign: 'right', flexShrink: 0 },
  cardPrice: { fontSize: 20, fontWeight: 600, color: '#1a1d23', lineHeight: 1 },
  cardPriceLabel: { fontSize: 11, color: '#adb5bd' },
  equipRow: { display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 12 },
  equipChip: { background: '#f0f4f8', borderRadius: 6, padding: '4px 8px', fontSize: 12, color: '#2D3436' },
  cardFooter: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' },
  ratingRow: { display: 'flex', alignItems: 'center', gap: 4 },
  starIcon: { color: '#f39c12', fontSize: 16 },
  ratingNum: { fontSize: 14, fontWeight: 700 },
  reviewCount: { fontSize: 12, color: '#adb5bd' },
  bookBtn: { background: '#1a1d23', color: '#fff', border: 'none', borderRadius: 8, padding: '8px 18px', fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  bookBtnDisabled: { background: '#dee2e6', color: '#adb5bd', cursor: 'not-allowed' },
  // Verify
  verifyContainer: { maxWidth: 560, margin: '0 auto', padding: '24px 16px' },
  bookingSummary: { background: '#fff', borderRadius: 12, padding: 16, display: 'flex', alignItems: 'center', gap: 14, marginBottom: 20, border: '1px solid #e9ecef' },
  summaryIcon: { fontSize: 28 },
  summaryName: { fontSize: 15, fontWeight: 700 },
  summaryLoc: { fontSize: 13, color: '#636e72' },
  verifyCard: { background: '#fff', borderRadius: 16, padding: 28, border: '1px solid #e9ecef', boxShadow: '0 4px 24px rgba(0,0,0,0.06)' },
  verifyHeader: { display: 'flex', alignItems: 'center', gap: 16, marginBottom: 16 },
  verifyIconBg: { width: 52, height: 52, background: '#e3f0fc', borderRadius: 14, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 },
  verifyTitle: { fontSize: 18, fontWeight: 700 },
  verifySub: { fontSize: 13, color: '#0984e3', fontWeight: 500 },
  verifyDesc: { fontSize: 14, color: '#636e72', marginBottom: 24, lineHeight: 1.6 },
  formGroup: { marginBottom: 18 },
  label: { display: 'block', fontSize: 13, fontWeight: 600, color: '#2D3436', marginBottom: 6 },
  input: { width: '100%', border: '1.5px solid #dee2e6', borderRadius: 10, padding: '11px 14px', fontSize: 15, color: '#2D3436', fontFamily: 'inherit', background: '#fff', boxSizing: 'border-box', outline: 'none' },
  verifyBtn: { width: '100%', background: '#0984e3', color: '#fff', border: 'none', borderRadius: 10, padding: 14, fontSize: 15, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  validatingBox: { background: '#e3f0fc', borderRadius: 12, padding: 16, display: 'flex', alignItems: 'center', gap: 14 },
  spinner: { width: 24, height: 24, border: '3px solid #b8d8f5', borderTop: '3px solid #0984e3', borderRadius: '50%', animation: 'spin 0.8s linear infinite', flexShrink: 0 },
  validatingTitle: { fontSize: 14, fontWeight: 600, color: '#0984e3' },
  validatingSub: { fontSize: 12, color: '#636e72' },
  successBox: { background: '#d4edda', borderRadius: 12, padding: 16, display: 'flex', alignItems: 'center', gap: 14, marginBottom: 16 },
  successIcon: { width: 36, height: 36, background: '#28a745', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 18, flexShrink: 0 },
  successTitle: { fontSize: 14, fontWeight: 700, color: '#155724' },
  successSub: { fontSize: 12, color: '#155724' },
  continueBtn: { width: '100%', background: '#28a745', color: '#fff', border: 'none', borderRadius: 10, padding: 14, fontSize: 15, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  // Slots
  slotContainer: { maxWidth: 700, margin: '0 auto', padding: '24px 16px' },
  dateStrip: { display: 'flex', gap: 8, marginBottom: 20, overflowX: 'auto' },
  dateBtn: { flexShrink: 0, background: '#fff', border: '1.5px solid #dee2e6', borderRadius: 12, padding: '10px 14px', cursor: 'pointer', textAlign: 'center', fontFamily: 'inherit', minWidth: 60 },
  dateBtnActive: { background: '#0984e3', borderColor: '#0984e3' },
  dateDayName: { fontSize: 11, color: '#636e72', marginBottom: 2 },
  dateDayNum: { fontSize: 20, fontWeight: 800, color: '#2D3436', lineHeight: 1 },
  dateMonth: { fontSize: 11, color: '#adb5bd', marginTop: 2 },
  legend: { display: 'flex', gap: 16, marginBottom: 16, fontSize: 12, color: '#636e72' },
  legendItem: { display: 'flex', alignItems: 'center', gap: 6 },
  legendDot: { width: 12, height: 12, borderRadius: 4, flexShrink: 0 },
  slotGrid: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8, marginBottom: 24 },
  slotCell: { borderRadius: 10, padding: '12px 8px', textAlign: 'center', cursor: 'pointer', border: '1.5px solid transparent', transition: 'all 0.15s' },
  slotFree: { background: '#fff', border: '1.5px solid #dee2e6', cursor: 'pointer' },
  slotTaken: { background: '#e9ecef', border: '1.5px solid #ced4da', cursor: 'not-allowed', pointerEvents: 'none', opacity: 0.65 },
  slotBuffer: { background: '#e9ecef', border: '1.5px solid #dee2e6', cursor: 'not-allowed' },
  slotSelected: { background: '#0984e3', border: '1.5px solid #0984e3', color: '#fff' },
  slotTime: { fontSize: 16, fontWeight: 700 },
  slotNote: { fontSize: 10, marginTop: 2, color: 'inherit', opacity: 0.75 },
  bookingFooter: { background: '#fff', borderRadius: 16, padding: 20, border: '1px solid #e9ecef', boxShadow: '0 4px 24px rgba(0,0,0,0.06)' },
  bookingCalc: { marginBottom: 16 },
  bookingCalcRow: { display: 'flex', justifyContent: 'space-between', fontSize: 14, marginBottom: 6 },
  confirmBtn: { width: '100%', background: '#0984e3', color: '#fff', border: 'none', borderRadius: 10, padding: 14, fontSize: 15, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  spinnerSmall: { width: 16, height: 16, border: '2px solid rgba(255,255,255,0.4)', borderTop: '2px solid #fff', borderRadius: '50%', animation: 'spin 0.8s linear infinite' },
  // Confirmation
  confirmPage: { maxWidth: 480, margin: '0 auto', padding: '60px 24px', textAlign: 'center' },
  confirmIcon: { width: 80, height: 80, background: '#0984e3', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 36, fontWeight: 800, margin: '0 auto 24px' },
  confirmTitle: { fontSize: 28, fontWeight: 800, marginBottom: 8 },
  confirmSub: { fontSize: 15, color: '#636e72', marginBottom: 32 },
  confirmCard: { background: '#fff', borderRadius: 16, padding: 24, textAlign: 'left', marginBottom: 24, border: '1px solid #e9ecef' },
  confirmRow: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px 0', borderBottom: '1px solid #f0f4f8', fontSize: 14 },
  confirmLabel: { color: '#636e72', fontWeight: 500 },
  confirmVal: { fontWeight: 600 },
  confirmActions: { display: 'flex', gap: 12 },
  confirmSecBtn: { flex: 1, background: '#fff', border: '1.5px solid #dee2e6', borderRadius: 10, padding: 13, fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  confirmPrimBtn: { flex: 1, background: '#0984e3', color: '#fff', border: 'none', borderRadius: 10, padding: 13, fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  // Modal styles for booking details
  modalOverlay: { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 100 },
  modalContent: { background: '#fff', borderRadius: 16, padding: 0, maxWidth: 480, width: '90vw', maxHeight: '80vh', overflowY: 'auto', position: 'relative', boxShadow: '0 12px 48px rgba(0,0,0,0.15)' },
  modalCloseBtn: { position: 'absolute', top: 12, right: 12, width: 32, height: 32, background: '#f8f9fa', border: 'none', borderRadius: 8, cursor: 'pointer', fontSize: 18, color: '#636e72', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, zIndex: 101, transition: 'all 0.15s' },
  modalHeader: { padding: '20px 24px', borderBottom: '1px solid #e9ecef', background: '#f8f9fa' },
  modalTitle: { fontSize: 18, fontWeight: 800, color: '#2D3436' },
  modalBody: { padding: '24px' },
  modalSection: { marginBottom: 18 },
  modalLabel: { fontSize: 12, fontWeight: 600, color: '#636e72', marginBottom: 6, textTransform: 'uppercase', letterSpacing: 0.5 },
  modalValue: { fontSize: 15, fontWeight: 600, color: '#2D3436' },
  modalFooter: { padding: '16px 24px', borderTop: '1px solid #e9ecef', display: 'flex', gap: 12 },
  modalCloseActionBtn: { flex: 1, background: '#0984e3', color: '#fff', border: 'none', borderRadius: 10, padding: 12, fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit' },
  // Booking badge and list styles
  bookingBadge: { position: 'absolute', top: -6, right: -6, width: 24, height: 24, background: '#e74c3c', color: '#fff', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 800, border: '2px solid #fff' },
  bookingDetailCard: { background: '#f8f9fa', borderRadius: 12, padding: 16, border: '1px solid #e9ecef' },
};

window.ProfessionalFlow = ProfessionalFlow;
