'use client';

import { useState, useEffect, useRef, useCallback } from 'react';
import { formatDisplayDate, formatDisplayDateTime } from '@/lib/date';

type Image = { id: number; filename: string; data: string; category: string; room_id: number | null; location_target: string; uploaded_at: string };
type Slide = { id: number; title: string; subtitle: string; image_url: string | null; image_id: number | null; active: boolean; sort_order: number };
type Room = { id: number; name: string; description: string; price: string; photos: string[]; featured_photo: string | null; active: boolean; sort_order: number; amenity_ids?: number[] };
type CalendarEvent = { id: number; date: string; title: string; type: string; color: string; description: string | null; active: boolean };
type SocialEvent = { id: number; name: string; description: string; price: string | null; date: string | null; photos: string[]; featured_photo: string | null; active: boolean; is_private: boolean; max_guests: number | null; sort_order: number };
type MenuItem = { id: number; category: string; name: string; description: string; price: string; is_daily_special: boolean; active: boolean; sort_order: number; photos: string[]; featured_photo: string | null };
type Place = { id: number; name: string; description: string; photos: string[]; featured_photo: string | null; distance_km: string; visit_time: string; suggestion: string; active: boolean; sort_order: number };
type Review = { id: number; author_name: string; author_email: string | null; rating: number; text: string; approved: boolean };
type FooterConfig = { logo: string; favicon: string; tagline: string; facebook_url: string; instagram_url: string; whatsapp_url: string; address: string; phone: string; email: string };
type SocialRes = { id: number; event_id: number; username: string; event_name: string; guests: number; notes: string; status: string; created_at: string };
type Amenity = { id: number; name: string; icon_svg: string; sort_order: number };
type RestaurantReservation = { id: number; user_id: number | null; date: string; time: string; guests: number; table_name: string; created_at: string; username?: string; first_name?: string; last_name?: string };
type RoomReservation = { id: number; room_id: number; user_id: number | null; check_in: string; check_out: string; status: string; total_price: string; guest_name: string | null; guest_contact_method: string | null; guest_contact: string | null; created_at: string; room_name?: string; username?: string; first_name?: string; last_name?: string };
type Order = { id: number; user_id: number | null; order_type: string; room_id: number | null; subtotal: string; service_fee: string; total: string; status: string; notes: string | null; created_at: string; room_name?: string; username?: string; first_name?: string; last_name?: string; items: { menu_item_id: number; name: string; quantity: number; unit_price: string; total_price: string }[] };

const C = {
  gold: '#D4A853', goldLight: 'rgba(212,168,83,0.12)', navy: '#010D1E',
  warm: '#7A5A3A', bg: '#F7F4EF', card: '#FFFFFF', border: 'rgba(1,13,30,0.08)',
  text: '#444444', textLight: '#888888', danger: '#D32F2F', success: '#388E3C',
  shadow: '0 1px 4px rgba(1,13,30,0.06)', shadowHover: '0 6px 20px rgba(1,13,30,0.12)',
};

const NAV = [
  { id: 'brand', label: 'Brand', icon: '🎨' },
  { id: 'gallery', label: 'Images', icon: '🖼️' },
  { id: 'slides', label: 'Slideshow', icon: '🎞️' },
  { id: 'calendar', label: 'Calendar', icon: '📅' },
  { id: 'social', label: 'Events', icon: '🎪' },
  { id: 'rooms', label: 'Rooms', icon: '🏨' },
  { id: 'room-status', label: 'Room Status', icon: '🧹' },
  { id: 'room-assignments', label: 'Assignments', icon: '🔑' },
  { id: 'room-reservations', label: 'Room Bookings', icon: '🛏️' },
  { id: 'restaurant-reservations', label: 'Restaurant', icon: '🍽️' },
  { id: 'orders', label: 'Food Orders', icon: '📦' },
  { id: 'kitchen', label: 'Kitchen', icon: '👨‍🍳' },
  { id: 'amenities', label: 'Amenities', icon: '✨' },
  { id: 'trips', label: 'Trips', icon: '✈️' },
  { id: 'messages', label: 'Messages', icon: '💬' },
  { id: 'menu', label: 'Menu', icon: '📋' },
  { id: 'places', label: 'Places', icon: '🗺️' },
  { id: 'reviews', label: 'Reviews', icon: '⭐' },
  { id: 'users', label: 'Users', icon: '👥' },
  { id: 'terms', label: 'Terms', icon: '📜' },
  { id: 'weather', label: 'Weather', icon: '🌤️' },
];

function I({ label, value, onChange, type = 'text', placeholder, style }: any) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
      {label && <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>{label}</label>}
      <input type={type} value={value ?? ''} onChange={e => onChange(e.target.value)} placeholder={placeholder}
        style={{ padding: '8px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: '14px', outline: 'none', background: '#FAFAFA', ...style }}
        onFocus={e => { (e.target.style as any).borderColor = C.gold; (e.target.style as any).background = '#FFFFFF'; }}
        onBlur={e => { (e.target.style as any).borderColor = C.border; (e.target.style as any).background = '#FAFAFA'; }} />
    </div>
  );
}

function TA({ label, value, onChange, rows = 3 }: any) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
      {label && <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>{label}</label>}
      <textarea value={value ?? ''} onChange={e => onChange(e.target.value)} rows={rows}
        style={{ padding: '8px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: '14px', outline: 'none', background: '#FAFAFA', resize: 'vertical', fontFamily: 'inherit' }}
        onFocus={e => { (e.target.style as any).borderColor = C.gold; (e.target.style as any).background = '#FFFFFF'; }}
        onBlur={e => { (e.target.style as any).borderColor = C.border; (e.target.style as any).background = '#FAFAFA'; }} />
    </div>
  );
}

function S({ label, value, onChange, options, style }: any) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
      {label && <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>{label}</label>}
      <select value={value ?? ''} onChange={e => onChange(e.target.value)}
        style={{ padding: '8px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: '14px', outline: 'none', background: '#FAFAFA' }}>
        {options.map((o: any) => <option key={o.value} value={o.value}>{o.label}</option>)}
      </select>
    </div>
  );
}

function Tgl({ label, checked, onChange }: any) {
  return (
    <label style={{ display: 'flex', alignItems: 'center', gap: '10px', cursor: 'pointer', fontSize: '14px', color: C.text }}>
      <input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)}
        style={{ width: 18, height: 18, accentColor: C.gold, cursor: 'pointer' }} />
      {label}
    </label>
  );
}

function Btn({ children, onClick, variant = 'primary', size = 'md', disabled }: any) {
  const sz = size === 'sm' ? { padding: '5px 10px', fontSize: '12px' } : { padding: '8px 16px', fontSize: '14px' };
  const bg = variant === 'danger' ? C.danger : variant === 'secondary' ? '#E8E4DF' : C.gold;
  const color = variant === 'secondary' ? C.text : '#fff';
  return (
    <button onClick={onClick} disabled={disabled} style={{ ...sz, borderRadius: 8, border: 'none', cursor: disabled ? 'default' : 'pointer',
      background: bg, color, fontWeight: 600, opacity: disabled ? 0.5 : 1, transition: 'all 200ms' }}
      onMouseEnter={e => { if (!disabled) { e.currentTarget.style.opacity = '0.85'; e.currentTarget.style.transform = 'translateY(-1px)'; } }}
      onMouseLeave={e => { if (!disabled) { e.currentTarget.style.opacity = '1'; e.currentTarget.style.transform = 'translateY(0)'; } }}>
      {children}
    </button>
  );
}

function Badge({ children, color: c }: any) {
  return (
    <span style={{ padding: '2px 10px', borderRadius: 20, fontSize: '12px', fontWeight: 600,
      background: c || C.goldLight, color: c ? '#fff' : C.gold }}>
      {children}
    </span>
  );
}

function Toast({ message, type, onClose }: any) {
  useEffect(() => { const t = setTimeout(onClose, 3500); return () => clearTimeout(t); }, [onClose]);
  return (
    <div style={{ position: 'fixed', top: '20px', right: '20px', padding: '12px 20px', borderRadius: 12,
      background: type === 'success' ? C.success : type === 'error' ? C.danger : C.gold,
      color: '#fff', boxShadow: C.shadowHover, zIndex: 9999, fontSize: '14px', fontWeight: 500,
      display: 'flex', alignItems: 'center', gap: '10px' }}>
      {message}
      <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: '#fff', cursor: 'pointer', fontSize: '18px', lineHeight: 1 }}>×</button>
    </div>
  );
}

function StatCard({ icon, value, label }: any) {
  return (
    <div style={{ background: C.card, borderRadius: 14, padding: '16px 20px', boxShadow: C.shadow,
      display: 'flex', alignItems: 'center', gap: '14px', minWidth: '160px' }}>
      <span style={{ fontSize: '28px' }}>{icon}</span>
      <div>
        <div style={{ fontSize: '22px', fontWeight: 700, color: C.navy }}>{value}</div>
        <div style={{ fontSize: '12px', color: C.textLight }}>{label}</div>
      </div>
    </div>
  );
}

function Empty({ icon, title, desc }: any) {
  return (
    <div style={{ textAlign: 'center', padding: '40px 20px', color: C.textLight }}>
      <div style={{ fontSize: '48px', marginBottom: '8px' }}>{icon}</div>
      <div style={{ fontSize: '16px', fontWeight: 600, color: C.text, marginBottom: '4px' }}>{title}</div>
      {desc && <div style={{ fontSize: '13px' }}>{desc}</div>}
    </div>
  );
}

/* ─── WebP Migration ─── */
function WebPMigration({ onToast, onRefresh }: { onToast: (msg: string, type: string) => void; onRefresh: () => void }) {
  const [migrating, setMigrating] = useState(false);
  const [stats, setStats] = useState<{ totalImages: number; totalSizeMB: number } | null>(null);

  useEffect(() => {
    fetch('/api/admin/migrate-images')
      .then(res => res.ok ? res.json() : null)
      .then(data => data && setStats({ totalImages: data.totalImages, totalSizeMB: data.totalSizeMB }))
      .catch(() => {});
  }, []);

  const runMigration = async () => {
    setMigrating(true);
    try {
      const res = await fetch('/api/admin/migrate-images', { method: 'POST' });
      const data = await res.json();
      if (res.ok) {
        onToast(`Converted ${data.converted} images, saved ${data.totalSavedMB} MB`, 'success');
        onRefresh();
      } else {
        onToast(data.error || 'Migration failed', 'error');
      }
    } catch {
      onToast('Migration failed', 'error');
    }
    setMigrating(false);
  };

  return (
    <div style={{
      marginBottom: '16px',
      padding: '12px 16px',
      background: '#fff',
      borderRadius: '12px',
      border: `1px solid ${C.border}`,
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'space-between',
      flexWrap: 'wrap',
      gap: '12px',
    }}>
      <div>
        <div style={{ fontWeight: 600, color: C.navy, fontSize: '14px' }}>🔄 WebP Migration</div>
        <div style={{ fontSize: '12px', color: C.textLight }}>
          {stats ? `${stats.totalImages} images · ${stats.totalSizeMB} MB total` : 'Checking...'}
        </div>
      </div>
      <Btn onClick={runMigration} disabled={migrating} size="sm">
        {migrating ? 'Migrating...' : 'Convert to WebP'}
      </Btn>
    </div>
  );
}

function SecHead({ title, count, action }: any) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px', flexWrap: 'wrap', gap: '10px' }}>
      <h2 style={{ margin: 0, fontSize: '20px', fontWeight: 700, color: C.navy }}>
        {title} <span style={{ fontSize: '14px', fontWeight: 400, color: C.textLight }}>({count})</span>
      </h2>
      {action}
    </div>
  );
}

/* ─── Image helpers ─── */
function readFileBase64(file: File): Promise<string> {
  return new Promise((res, rej) => {
    const r = new FileReader();
    r.onload = () => res(r.result as string);
    r.onerror = rej;
    r.readAsDataURL(file);
  });
}

/* ─── Entity thumbnail ─── */
function Thumb({ urls, w = 200, h = 140 }: { urls: string[]; w?: number; h?: number }) {
  if (!urls?.length) return <div style={{ width: w, height: h, background: '#EEE', borderRadius: 12, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#BBB' }}>No image</div>;
  return <img src={urls[0]} alt="" style={{ width: w, height: h, objectFit: 'cover', borderRadius: 12 }} />;
}

/* ─── Thumbnail grid (inline, small) ─── */
function MiniThumbs({ urls, max = 3 }: { urls: string[]; max?: number }) {
  if (!urls?.length) return null;
  return (
    <div style={{ display: 'flex', gap: '6px', marginTop: '8px' }}>
      {urls.slice(0, max).map((u, i) => (
        <img key={i} src={u} alt="" style={{ width: 70, height: 50, objectFit: 'cover', borderRadius: 8, cursor: 'pointer', border: '1px solid #eee' }} />
      ))}
      {urls.length > max && <span style={{ padding: '8px', background: '#EEE', borderRadius: 8, fontSize: '12px', color: '#999' }}>+{urls.length - max}</span>}
    </div>
  );
}

/* ─── Section uploader (per-section image upload) ─── */
function SectionUploader({ category, room_id, label, onUploaded }: { category: string; room_id: number | null; label: string; onUploaded?: () => void }) {
  const ref = useRef<HTMLInputElement>(null);
  return (
    <>
      <Btn onClick={() => ref.current?.click()} size="sm">{label}</Btn>
      <input ref={ref} type="file" accept="image/*" multiple style={{ display: 'none' }}
        onChange={async (e) => {
          for (const file of Array.from(e.target.files || [])) {
            const b64 = await readFileBase64(file);
            try {
              const res = await fetch('/api/admin/images', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ filename: file.name, data: b64, category, room_id, location_target: category }),
              });
              if (res.ok) onUploaded?.();
            } catch (err) { console.error(err); }
          }
          e.target.value = '';
        }} />
    </>
  );
}

/* ─── Organized image gallery with sections and borders ─── */
function ImageGallery({ images, onDelete }: { images: Image[]; onDelete: (id: number) => void }) {
  const [selectedCategory, setSelectedCategory] = useState<string>('all');
  const [hoveredCard, setHoveredCard] = useState<number | null>(null);

  const sectionCategories = [
    { key: 'slides', label: '🎞️ Slideshow Gallery', filter: (i: Image) => i.category === 'slides' || i.location_target === 'slides' },
    { key: 'food', label: '🍽️ Food Gallery', filter: (i: Image) => i.category === 'food' || i.location_target === 'food' },
    { key: 'spa', label: '🧖 Spa Gallery', filter: (i: Image) => i.category === 'spa' || i.location_target === 'spa' },
    { key: 'pool', label: '🏊 Pool Gallery', filter: (i: Image) => i.category === 'pool' || i.location_target === 'pool' },
    { key: 'calendar', label: '📅 Calendar Events Gallery', filter: (i: Image) => i.category === 'calendar' || i.location_target === 'calendar' },
    { key: 'public', label: '🎪 Public Events Gallery', filter: (i: Image) => i.category === 'public' || i.location_target === 'public' || i.category === 'social' || i.location_target === 'social' },
    { key: 'private', label: '🔒 Private Events Gallery', filter: (i: Image) => i.category === 'private' || i.location_target === 'private' },
  ];

  // Group room images by room location_target (e.g. "room-1", "room-2")
  const roomImages = images.filter(
    (i) => i.category === 'rooms' || i.location_target?.startsWith('room-')
  );
  const roomsByNumber: Record<string, Image[]> = roomImages.reduce((acc, img) => {
    const key = img.location_target?.replace('room-', '') || 'uncategorized';
    if (!acc[key]) acc[key] = [];
    acc[key].push(img);
    return acc;
  }, {} as Record<string, Image[]>);

  const filteredImages = images.filter((img) => {
    if (selectedCategory === 'all') return true;
    if (selectedCategory === 'rooms') return img.category === 'rooms' || img.location_target?.startsWith('room-');
    if (selectedCategory === 'food') return img.category === 'food' || img.location_target === 'food';
    if (selectedCategory === 'spa') return img.category === 'spa' || img.location_target === 'spa';
    if (selectedCategory === 'pool') return img.category === 'pool' || img.location_target === 'pool';
    if (selectedCategory === 'public') return img.category === 'public' || img.location_target === 'public' || img.category === 'social' || img.location_target === 'social';
    if (selectedCategory === 'private') return img.category === 'private' || img.location_target === 'private';
    return img.category === selectedCategory || img.location_target === selectedCategory;
  });

  const ImageCard = ({ img }: { img: Image }) => {
    const isHov = hoveredCard === img.id;
    return (
      <div
        style={{
          position: 'relative', borderRadius: '10px', overflow: 'hidden',
          boxShadow: isHov ? C.shadowHover : C.shadow,
          border: `1px solid ${isHov ? C.gold : C.border}`,
          transform: isHov ? 'translateY(-2px)' : 'none',
          transition: 'all 200ms ease',
          cursor: 'default',
        }}
        onMouseEnter={() => setHoveredCard(img.id)}
        onMouseLeave={() => setHoveredCard(null)}
      >
        <img
          src={img.data}
          alt={img.filename}
          style={{
            width: '100%', height: '110px', objectFit: 'cover', display: 'block',
          }}
        />
        <div style={{
          padding: '6px 8px', fontSize: '11px', color: C.text,
          whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
          background: C.card,
        }}>
          {img.filename}
        </div>
        <div style={{ display: 'flex', justifyContent: 'flex-end', padding: '4px' }}>
          <button
            onClick={(e) => { e.stopPropagation(); onDelete(img.id); }}
            style={{
              width: '24px', height: '24px', borderRadius: '6px',
              border: '1px solid rgba(211,47,47,0.2)',
              background: isHov ? 'rgba(211,47,47,0.15)' : 'transparent',
              color: C.danger, fontSize: '14px', cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              transition: 'all 200ms',
            }}
          >
            ×
          </button>
        </div>
        {/* Category label overlay on hover */}
        {isHov && img.location_target && (
          <div style={{
            position: 'absolute', bottom: '30px', left: '4px', right: '4px',
            padding: '3px 6px', fontSize: '10px', color: '#fff',
            background: 'rgba(1,13,30,0.75)', borderRadius: '4px',
            whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
            textAlign: 'center',
          }}>
            {img.location_target}
          </div>
        )}
      </div>
    );
  };

  const SectionBox = ({ title, count, children }: { title: string; count: number; children: React.ReactNode }) => (
    <div style={{
      borderRadius: '12px', overflow: 'hidden',
      border: `1px solid ${C.border}`, background: '#fff',
      boxShadow: C.shadow,
    }}>
      <div style={{
        padding: '10px 16px',
        background: C.goldLight,
        borderBottom: `1px solid ${C.border}`,
        fontWeight: 700, color: C.navy, fontSize: '14px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      }}>
        <span>{title}</span>
        <span style={{
          fontSize: '11px', padding: '2px 10px', borderRadius: '999px',
          background: C.success, color: '#fff', fontWeight: 600,
        }}>{count}</span>
      </div>
      <div style={{ padding: '16px' }}>
        {children}
      </div>
    </div>
  );

  return (
    <div>
      {/* Category filter bar with borders */}
      <div style={{
        display: 'flex', gap: '8px', marginBottom: '20px', flexWrap: 'wrap',
        padding: '12px 16px', borderRadius: '12px',
        border: `1px solid ${C.border}`, background: '#fff',
        boxShadow: C.shadow,
      }}>
        {['all', 'slides', 'food', 'spa', 'pool', 'calendar', 'public', 'private', 'rooms', 'other'].map((cat) => (
          <Btn
            key={cat}
            onClick={() => setSelectedCategory(cat)}
            variant={selectedCategory === cat ? 'primary' : 'secondary'}
            size="sm"
          >
            {cat === 'all' ? 'All Images' : cat.charAt(0).toUpperCase() + cat.slice(1)}
          </Btn>
        ))}
      </div>

      {selectedCategory === 'all' ? (
        <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
          {/* Static sections */}
          {sectionCategories.map((section) => {
            const imgs = images.filter(section.filter);
            if (imgs.length === 0) return null;
            return (
              <SectionBox key={section.key} title={section.label} count={imgs.length}>
                <div style={{
                  display: 'grid',
                  gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
                  gap: '12px',
                }}>
                  {imgs.map((img) => <ImageCard key={img.id} img={img} />)}
                </div>
              </SectionBox>
            );
          })}

          {/* Rooms section with room number subdivision */}
          {Object.keys(roomsByNumber).length > 0 && (
            <SectionBox title="🏨 Rooms Gallery" count={roomImages.length}>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
                {Object.entries(roomsByNumber).map(([roomKey, imgs]) => (
                  <div key={roomKey}>
                    <div style={{
                      display: 'flex', alignItems: 'center', gap: '8px',
                      marginBottom: '10px', padding: '8px 12px',
                      background: '#FAFAFA', borderRadius: '8px',
                      border: `1px solid ${C.border}`,
                    }}>
                      <span style={{ fontSize: '13px', fontWeight: 600, color: C.navy }}>
                        🛏️ Room {roomKey}
                      </span>
                      <span style={{
                        fontSize: '11px', padding: '2px 8px', borderRadius: '999px',
                        background: C.goldLight, color: C.gold, fontWeight: 600,
                      }}>{imgs.length} photo{imgs.length !== 1 ? 's' : ''}</span>
                    </div>
                    <div style={{
                      display: 'grid',
                      gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
                      gap: '12px',
                    }}>
                      {imgs.map((img) => <ImageCard key={img.id} img={img} />)}
                    </div>
                  </div>
                ))}
              </div>
            </SectionBox>
          )}

          {/* Uncategorized/other */}
          {(() => {
            const otherImages = images.filter(
              (i) => !sectionCategories.some(s => s.filter(i)) &&
                     !(i.category === 'rooms' || i.location_target?.startsWith('room-'))
            );
            if (otherImages.length === 0) return null;
            return (
              <SectionBox title="📁 Uncategorized" count={otherImages.length}>
                <div style={{
                  display: 'grid',
                  gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
                  gap: '12px',
                }}>
                  {otherImages.map((img) => <ImageCard key={img.id} img={img} />)}
                </div>
              </SectionBox>
            );
          })()}
        </div>
      ) : (
        <SectionBox title={
          selectedCategory === 'rooms' ? '🏨 Rooms' :
          selectedCategory === 'other' ? '📁 Other' :
          selectedCategory.charAt(0).toUpperCase() + selectedCategory.slice(1)
        } count={filteredImages.length}>
          {filteredImages.length === 0 ? (
            <div style={{ padding: '40px 20px', textAlign: 'center', color: C.textLight }}>
              No images in this category
            </div>
          ) : (
            <div style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
              gap: '12px',
            }}>
              {filteredImages.map((img) => <ImageCard key={img.id} img={img} />)}
            </div>
          )}
        </SectionBox>
      )}
    </div>
  );
}

/* ─── Entity card ─── */

/* ─── Entity card ─── */
function EntityCard({ title, desc, meta, thumb, actions, photoUrls }: any) {
  return (
    <div style={{ background: C.card, borderRadius: 16, overflow: 'hidden', boxShadow: C.shadow, transition: 'all 200ms', border: `1px solid ${C.border}` }}
      onMouseEnter={e => { e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = C.shadowHover; }}
      onMouseLeave={e => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = C.shadow; }}>
      {thumb ? (
        <img src={thumb} alt="" style={{ width: '100%', height: 140, objectFit: 'cover' }} />
      ) : photoUrls?.length ? <Thumb urls={photoUrls} /> : <div style={{ height: 100, background: '#EEE', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#CCC' }}>📷</div>}
      <div style={{ padding: '14px 16px' }}>
        <div style={{ fontWeight: 700, color: C.navy, fontSize: '15px', marginBottom: '4px' }}>{title}</div>
        {desc && <div style={{ fontSize: '13px', color: C.text, lineHeight: 1.4, marginBottom: '6px', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{desc}</div>}
        {meta && <div style={{ fontSize: '12px', color: C.textLight, marginBottom: '10px' }}>{meta}</div>}
        {photoUrls?.length ? <MiniThumbs urls={photoUrls} /> : null}
        {actions && <div style={{ display: 'flex', gap: '8px', marginTop: '12px' }}>{actions}</div>}
      </div>
    </div>
  );
}

/* ─── Confirm dialog ─── */
function Confirm({ message, onConfirm, onCancel }: any) {
  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 360, width: '90%', boxShadow: '0 20px 60px rgba(0,0,0,0.2)' }}>
        <p style={{ margin: '0 0 20px', fontSize: '15px', color: C.text }}>{message}</p>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={onConfirm} variant="danger">Delete</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Slides Section ─── */
function SlidesSection({ slides, setSlides, images, onToast, onRefreshImages }: any) {
  const [editing, setEditing] = useState<Slide | null>(null);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  const saveSlide = async (slide: Slide) => {
    try {
      // If image_id is set, clear image_url (image is in images table)
      const payload = { 
        ...slide, 
        image_url: slide.image_id ? null : slide.image_url 
      };
      const url = payload.id ? `/api/slides/${payload.id}` : '/api/slides';
      const res = await fetch(url, {
        method: payload.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (res.ok) {
        const data = await res.json();
        setEditing(null);
        setSlides((s: any) => payload.id ? s.map((x: Slide) => x.id === payload.id ? data.data : x) : [...s, data.data]);
        onToast('Slide saved!', 'success');
      } else {
        const err = await res.json();
        console.error('Slide save error:', err);
        onToast(err.error || 'Error saving slide', 'error');
      }
    } catch (err) { 
      console.error('Slide save exception:', err);
      onToast('Error saving slide', 'error'); 
    }
  };

  const delSlide = async (id: number) => {
    try {
      await fetch(`/api/slides/${id}`, { method: 'DELETE' });
      setSlides((s: any) => s.filter((x: Slide) => x.id !== id));
      onToast('Slide deleted', 'success');
    } catch { onToast('Error deleting slide', 'error'); }
    setConfirmDel(null);
  };

  return (
    <div>
      <SecHead title="🎞️ Slideshow" count={slides.length}
        action={<Btn onClick={() => setEditing({ id: 0, title: '', subtitle: '', image_url: null, image_id: null, active: true, sort_order: slides.length })} size="sm">+ New Slide</Btn>} />
      {slides.length === 0 ? <Empty icon="🎞️" title="No slides yet" /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px' }}>
          {slides.map((s: Slide) => (
            <EntityCard key={s.id} title={s.title} desc={s.subtitle} meta={s.active ? 'Active' : 'Inactive'}
              thumb={s.image_url || s.image_id ? (images.find((i: Image) => i.id === s.image_id)?.data) : null}
              actions={
                <>
                  <Btn size="sm" variant="secondary" onClick={() => setEditing(s)}>Edit</Btn>
                  <Btn size="sm" variant="danger" onClick={() => setConfirmDel(s.id)}>Del</Btn>
                </>
              } />
          ))}
        </div>
      )}
      {editing && (
        <SlideEditor slide={editing} setSlide={setEditing} images={images} onRefreshImages={onRefreshImages} onSave={saveSlide} onCancel={() => setEditing(null)} />
      )}
      {confirmDel !== null && <Confirm message="Delete this slide?" onCancel={() => setConfirmDel(null)} onConfirm={() => delSlide(confirmDel)} />}
    </div>
  );
}

function SlideEditor({ slide, setSlide, images, onRefreshImages, onSave, onCancel }: any) {
  const [showPicker, setShowPicker] = useState(false);
  const [uploading, setUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  
  const handleUpload = async (files: FileList) => {
    setUploading(true);
    try {
      for (const file of Array.from(files)) {
        const b64 = await readFileBase64(file);
        const res = await fetch('/api/admin/images', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ filename: file.name, data: b64, category: 'slides', room_id: null, location_target: 'slides' }),
        });
        if (res.ok) {
          const data = await res.json();
          await onRefreshImages?.();
          setSlide((prev: any) => ({ ...prev, image_id: data.data.id, image_url: data.data.data }));
        } else {
          const err = await res.json();
          console.error('Image upload error:', err);
          alert('Upload failed: ' + (err.error || 'Unknown error'));
        }
      }
    } catch (err) {
      console.error('Upload failed:', err);
      alert('Upload failed');
    } finally {
      setUploading(false);
    }
  };
  
  const s = slide;
  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 500, width: '90%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{s.id ? 'Edit Slide' : 'New Slide'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Title" value={s.title} onChange={(v: string) => setSlide({ ...s, title: v })} />
          <I label="Subtitle" value={s.subtitle} onChange={(v: string) => setSlide({ ...s, subtitle: v })} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Image</label>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
              <Btn onClick={() => setShowPicker(!showPicker)} size="sm" variant="secondary">{showPicker ? 'Hide picker' : 'Pick from gallery'}</Btn>
              <input ref={fileInputRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={(e) => { if (e.target.files?.length) handleUpload(e.target.files); e.target.value = ''; }} />
              <Btn size="sm" variant="secondary" disabled={uploading} onClick={() => fileInputRef.current?.click()}>{uploading ? 'Uploading...' : 'Upload from computer'}</Btn>
              {s.image_id && images.find((i: Image) => i.id === s.image_id) && (
                <img src={images.find((i: Image) => i.id === s.image_id)!.data} style={{ width: 80, height: 56, objectFit: 'cover', borderRadius: 8, border: `2px solid ${C.gold}` }} />
              )}
            </div>
            {showPicker && (
              <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap', padding: '8px', background: '#FAFAFA', borderRadius: 8 }}>
                {images.filter((i: Image) => i.category === 'slides').map((img: Image) => (
                  <img key={img.id} src={img.data} alt="" onClick={() => { setSlide({ ...s, image_id: img.id, image_url: img.data }); setShowPicker(false); }}
                    style={{ width: 64, height: 48, objectFit: 'cover', borderRadius: 6, cursor: 'pointer', border: s.image_id === img.id ? `2px solid ${C.gold}` : '1px solid #eee' }} />
                ))}
                {images.filter((i: Image) => i.category === 'slides').length === 0 && <span style={{ fontSize: '12px', color: C.textLight, padding: '8px' }}>No images uploaded. Use "Upload from computer" above.</span>}
              </div>
            )}
          </div>
          <div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
            <Tgl label="Active" checked={s.active} onChange={(v: boolean) => setSlide({ ...s, active: v })} />
            <I label="Sort Order" type="number" value={s.sort_order} onChange={(v: string) => setSlide({ ...s, sort_order: Number(v) })} style={{ width: 80 }} />
          </div>
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(s)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Calendar Section ─── */
function CalendarSection({ events, setEvents, images, onToast }: any) {
  const [editing, setEditing] = useState<CalendarEvent | null>(null);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  const save = async (ev: CalendarEvent) => {
    try {
      const url = ev.id ? `/api/calendar_events/${ev.id}` : '/api/calendar_events';
      const res = await fetch(url, {
        method: ev.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(ev),
      });
      if (res.ok) {
        const data = await res.json();
        setEditing(null);
        setEvents((e: any) => ev.id ? e.map((x: CalendarEvent) => x.id === ev.id ? data.data : x) : [...e, data.data]);
        onToast('Event saved!', 'success');
      }
    } catch { onToast('Error', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/calendar_events/${id}`, { method: 'DELETE' });
    setEvents((e: any) => e.filter((x: CalendarEvent) => x.id !== id));
    onToast('Event deleted', 'success');
    setConfirmDel(null);
  };

  return (
    <div>
      <SecHead title="📅 Calendar Events" count={events.length}
        action={<Btn onClick={() => setEditing({ id: 0, date: '', title: '', type: 'default', color: '#D4A853', description: null, active: true })} size="sm">+ New Event</Btn>} />
      {events.length === 0 ? <Empty icon="📅" title="No events" /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', gap: '16px' }}>
          {events.map((ev: CalendarEvent) => (
            <EntityCard key={ev.id} title={ev.title} desc={ev.description || ev.type} meta={`${ev.date} • ${ev.type}`}
              actions={
                <>
                  <Btn size="sm" variant="secondary" onClick={() => setEditing(ev)}>Edit</Btn>
                  <Btn size="sm" variant="danger" onClick={() => setConfirmDel(ev.id)}>Del</Btn>
                </>
              } />
          ))}
        </div>
      )}
      {editing && <CalendarEditor event={editing} setEvent={setEditing} onSave={save} onCancel={() => setEditing(null)} />}
      {confirmDel !== null && <Confirm message="Delete this event?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

function CalendarEditor({ event, setEvent, onSave, onCancel }: any) {
  const e = { ...event };
  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 460, width: '90%' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{e.id ? 'Edit Event' : 'New Event'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Title" value={e.title} onChange={(v: string) => setEvent({ ...e, title: v })} />
          <I label="Date" type="date" value={e.date} onChange={(v: string) => setEvent({ ...e, date: v })} />
          <S label="Type" value={e.type} onChange={(v: string) => setEvent({ ...e, type: v })}
            options={[{ value: 'default', label: 'Default' }, { value: 'special', label: 'Special' }, { value: 'holiday', label: 'Holiday' }]} />
          <I label="Color" value={e.color} onChange={(v: string) => setEvent({ ...e, color: v })} />
          <TA label="Description" value={e.description || ''} onChange={(v: string) => setEvent({ ...e, description: v || null })} />
          <Tgl label="Active" checked={e.active} onChange={(v: boolean) => setEvent({ ...e, active: v })} />
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(e)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Social Events Section ─── */
function SocialSection({ events, setEvents, images, onToast }: any) {
  const [editing, setEditing] = useState<SocialEvent | null>(null);
  const [confirmDelEvent, setConfirmDelEvent] = useState<number | null>(null);
  const [confirmDelReservation, setConfirmDelReservation] = useState<number | null>(null);
  const [tab, setTab] = useState<'public' | 'private' | 'reservations'>('public');
  const [reservations, setReservations] = useState<any[]>([]);
  const [statusFilter, setStatusFilter] = useState<'pending' | 'confirmed' | 'cancelled' | 'all'>('pending');
  const [loading, setLoading] = useState(false);

  const publicEvents = events.filter((e: SocialEvent) => !e.is_private);
  const privateEvents = events.filter((e: SocialEvent) => e.is_private);

  useEffect(() => {
    if (tab === 'reservations') loadReservations();
  }, [tab, statusFilter]);

  const loadReservations = async () => {
    setLoading(true);
    try {
      const url = statusFilter === 'all' ? '/api/social_event_reservations' : `/api/social_event_reservations?status=${statusFilter}`;
      const res = await fetch(url);
      const data = await res.json();
      setReservations(data.data || []);
    } catch { onToast('Error loading reservations', 'error'); }
    setLoading(false);
  };

  const updateStatus = async (id: number, status: 'confirmed' | 'cancelled') => {
    try {
      await fetch(`/api/social_event_reservations/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ status }),
      });
      setReservations(r => r.map(x => x.id === id ? { ...x, status } : x));
      onToast(`Reservation ${status}`, 'success');
    } catch { onToast('Error updating reservation', 'error'); }
  };

  const delReservation = async (id: number) => {
    await fetch(`/api/social_event_reservations/${id}`, { method: 'DELETE' });
    setReservations(r => r.filter(x => x.id !== id));
    onToast('Reservation deleted', 'success');
    setConfirmDelReservation(null);
  };

  const save = async (ev: SocialEvent) => {
    try {
      const url = ev.id ? `/api/social_events/${ev.id}` : '/api/social_events';
      const res = await fetch(url, {
        method: ev.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(ev),
      });
      if (res.ok) {
        const data = await res.json();
        setEditing(null);
        setEvents((e: any) => ev.id ? e.map((x: SocialEvent) => x.id === ev.id ? data.data : x) : [...e, data.data]);
        onToast('Event saved!', 'success');
      }
    } catch { onToast('Error', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/social_events/${id}`, { method: 'DELETE' });
    setEvents((e: any) => e.filter((x: SocialEvent) => x.id !== id));
    onToast('Event deleted', 'success');
    setConfirmDelEvent(null);
  };

  const formatDate = (d: string | null) => d ? new Date(d).toLocaleDateString() : '-';
  const contactMethodIcon = (m: string) => m === 'email' ? '✉️' : m === 'whatsapp' ? '📱' : '📞';

  const renderEventList = (eventList: SocialEvent[], title: string, icon: string) => (
    <>
      <SecHead title={`${icon} ${title}`} count={eventList.length}
        action={<Btn onClick={() => setEditing({ id: 0, name: '', description: '', price: null, date: null, photos: [], featured_photo: null, active: true, is_private: icon === '🔒', max_guests: null, sort_order: events.length })} size="sm">+ New Event</Btn>} />
      {eventList.length === 0 ? <Empty icon={icon} title={`No ${title.toLowerCase()}`} /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px' }}>
          {eventList.map((ev: SocialEvent) => (
            <EntityCard key={ev.id} title={ev.name} desc={ev.description || ''} meta={`${ev.price || 'Free'}${ev.date ? ' • ' + ev.date : ''}${ev.max_guests ? ' • Max ' + ev.max_guests + ' guests' : ''}`}
              thumb={ev.featured_photo || ev.photos?.[0]}
              photoUrls={ev.photos}
              actions={
                <>
                  <Btn size="sm" variant="secondary" onClick={() => setEditing(ev)}>Edit</Btn>
                  <Btn size="sm" variant="danger" onClick={() => setConfirmDelEvent(ev.id)}>Del</Btn>
                </>
              } />
          ))}
        </div>
      )}
    </>
  );

  return (
    <div>
      <div style={{ display: 'flex', gap: '12px', marginBottom: '16px', borderBottom: '1px solid #e5e7eb', paddingBottom: '12px' }}>
        <Btn size="sm" variant={tab === 'public' ? 'primary' : 'secondary'} onClick={() => setTab('public')}>🎪 Public</Btn>
        <Btn size="sm" variant={tab === 'private' ? 'primary' : 'secondary'} onClick={() => setTab('private')}>🔒 Private</Btn>
        <Btn size="sm" variant={tab === 'reservations' ? 'primary' : 'secondary'} onClick={() => setTab('reservations')}>📅 Reservations</Btn>
      </div>

      {tab === 'public' && renderEventList(publicEvents, 'Public Events', '🎪')}
      {tab === 'private' && renderEventList(privateEvents, 'Private Events', '🔒')}
      {tab === 'reservations' && (
        <>
          <SecHead title="📅 Public Event Reservations" count={reservations.length} />
          <div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
            {(['pending', 'confirmed', 'cancelled', 'all'] as const).map(s => (
              <Btn key={s} size="sm" variant={statusFilter === s ? 'primary' : 'secondary'} onClick={() => setStatusFilter(s)}>
                {s.charAt(0).toUpperCase() + s.slice(1)}
              </Btn>
            ))}
          </div>
          {loading ? <Empty icon="⏳" title="Loading..." /> : reservations.length === 0 ? <Empty icon="📅" title="No reservations" desc={`No ${statusFilter === 'all' ? '' : statusFilter} reservations`} /> : (
            <div style={{ display: 'grid', gap: '12px' }}>
              {reservations.map((r: any) => (
                <div key={r.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', border: `1px solid ${r.status === 'pending' ? '#f59e0b' : r.status === 'confirmed' ? '#10b981' : '#ef4444'}` }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '12px' }}>
                    <div>
                      <div style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>{r.event_name}</div>
                      <div style={{ fontSize: '13px', color: '#666', marginTop: '4px' }}>{r.guests} guests</div>
                    </div>
                    <span style={{ 
                      padding: '4px 10px', borderRadius: 12, fontSize: '12px', fontWeight: 600,
                      background: r.status === 'confirmed' ? '#d1fae5' : r.status === 'cancelled' ? '#fee2e2' : '#fef3c7',
                      color: r.status === 'confirmed' ? '#047857' : r.status === 'cancelled' ? '#b91c1c' : '#b45309'
                    }}>{r.status}</span>
                  </div>
                  <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', fontSize: '13px', marginBottom: '12px' }}>
                    <div><strong>Contact:</strong> {r.contact_name || r.first_name || r.username || '-'}</div>
                    <div><strong>Method:</strong> {r.contact_method ? contactMethodIcon(r.contact_method) : '-'} {r.contact_method || '-'}</div>
                    {r.contact_email && <div><strong>Email:</strong> {r.contact_email}</div>}
                    {r.contact_phone && <div><strong>Phone:</strong> {r.contact_phone}</div>}
                  </div>
                  {r.notes && <div style={{ fontSize: '13px', color: '#666', marginBottom: '12px', fontStyle: 'italic' }}>"{r.notes}"</div>}
                  <div style={{ display: 'flex', gap: '8px' }}>
                    {r.status === 'pending' && (
                      <>
                        <Btn size="sm" variant="secondary" onClick={() => updateStatus(r.id, 'confirmed')}>✓ Confirm</Btn>
                        <Btn size="sm" variant="danger" onClick={() => updateStatus(r.id, 'cancelled')}>✗ Cancel</Btn>
                      </>
                    )}
                    {r.status === 'confirmed' && <Btn size="sm" variant="danger" onClick={() => updateStatus(r.id, 'cancelled')}>✗ Cancel</Btn>}
                    {r.status === 'cancelled' && <Btn size="sm" variant="secondary" onClick={() => updateStatus(r.id, 'confirmed')}>✓ Reactivate</Btn>}
                    <Btn size="sm" variant="danger" onClick={() => setConfirmDelReservation(r.id)}>🗑 Delete</Btn>
                  </div>
                </div>
              ))}
            </div>
          )}
          {confirmDelReservation !== null && <Confirm message="Delete this reservation?" onCancel={() => setConfirmDelReservation(null)} onConfirm={() => delReservation(confirmDelReservation)} />}
        </>
      )}
      {editing && <SocialEditor event={editing} setEvent={setEditing} images={images} onSave={save} onCancel={() => setEditing(null)} />}
      {confirmDelEvent !== null && <Confirm message="Delete this event?" onCancel={() => setConfirmDelEvent(null)} onConfirm={() => del(confirmDelEvent)} />}
    </div>
  );
}

function SocialEditor({ event, setEvent, images, onSave, onCancel }: any) {
  const [showPicker, setShowPicker] = useState(false);
  const [localPhotos, setLocalPhotos] = useState<string[]>(event.photos || []);
  const ev = { ...event, photos: localPhotos };

  const addPhotos = async (files: FileList) => {
    const newPhotos: string[] = [];
    for (const f of Array.from(files)) {
      const b64 = await readFileBase64(f);
      try {
        const r = await fetch('/api/admin/images', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ filename: f.name, data: b64, category: event.is_private ? 'private' : 'social', room_id: null, location_target: event.is_private ? 'private' : 'social' }),
        });
        if (r.ok) { const d = await r.json(); newPhotos.push(d.data.data); }
      } catch { const b = await readFileBase64(f); newPhotos.push(b); }
    }
    setLocalPhotos(prev => [...prev, ...newPhotos]);
  };

  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 500, width: '90%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{ev.id ? 'Edit Event' : 'New Event'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Name" value={ev.name} onChange={(v: string) => setEvent({ ...ev, name: v })} />
          <TA label="Description" value={ev.description || ''} onChange={(v: string) => setEvent({ ...ev, description: v })} />
          <I label="Price" value={ev.price || ''} onChange={(v: string) => setEvent({ ...ev, price: v || null })} />
          <I label="Date" type="date" value={ev.date || ''} onChange={(v: string) => setEvent({ ...ev, date: v || null })} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Photos</label>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
              <Btn onClick={() => document.getElementById('social-photos')?.click()} size="sm" variant="secondary">+ Add Photos</Btn>
              <input id="social-photos" type="file" accept="image/*" multiple style={{ display: 'none' }}
                onChange={e => { addPhotos(e.target.files!); e.target.value = ''; }} />
            </div>
            <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
              {localPhotos.map((p, i) => (
                <div key={i} style={{ position: 'relative' }}>
                  <img src={p} alt="" style={{ width: 64, height: 48, objectFit: 'cover', borderRadius: 6, border: '1px solid #eee' }} />
                  <button onClick={() => setLocalPhotos(prev => prev.filter((_, j) => j !== i))}
                    style={{ position: 'absolute', top: -4, right: -4, width: 18, height: 18, borderRadius: '50%', background: C.danger, color: '#fff', border: 'none', cursor: 'pointer', fontSize: '11px', lineHeight: 18, padding: 0 }}
                  >×</button>
                </div>
              ))}
            </div>
          </div>
          <Tgl label="Private Event" checked={ev.is_private || false} onChange={(v: boolean) => setEvent({ ...ev, is_private: v })} />
          {ev.is_private && (
            <I label="Max Guests" type="number" value={ev.max_guests || ''} onChange={(v: string) => setEvent({ ...ev, max_guests: v ? parseInt(v) : null })} placeholder="Leave empty for unlimited" />
          )}
          <Tgl label="Active" checked={ev.active} onChange={(v: boolean) => setEvent({ ...ev, active: v })} />
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(ev)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Rooms Section ─── */
function PrivateEventsSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [reservations, setReservations] = useState<any[]>([]);
  const [statusFilter, setStatusFilter] = useState<'pending' | 'confirmed' | 'cancelled' | 'all'>('pending');
  const [loading, setLoading] = useState(true);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  useEffect(() => {
    loadReservations();
  }, [statusFilter]);

  const loadReservations = async () => {
    setLoading(true);
    try {
      const url = statusFilter === 'all' ? '/api/private-event-reservations' : `/api/private-event-reservations?status=${statusFilter}`;
      const res = await fetch(url);
      const data = await res.json();
      setReservations(data.data || []);
    } catch { onToast('Error loading reservations', 'error'); }
    setLoading(false);
  };

  const updateStatus = async (id: number, status: 'confirmed' | 'cancelled') => {
    try {
      await fetch(`/api/private-event-reservations/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ status }),
      });
      setReservations(r => r.map(x => x.id === id ? { ...x, status } : x));
      onToast(`Reservation ${status}`, 'success');
    } catch { onToast('Error updating reservation', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/private-event-reservations/${id}`, { method: 'DELETE' });
    setReservations(r => r.filter(x => x.id !== id));
    onToast('Reservation deleted', 'success');
    setConfirmDel(null);
  };

  const formatDate = (d: string | null) => d ? new Date(d).toLocaleDateString() : '-';
  const formatTime = (t: string | null) => t || '-';
  const contactMethodIcon = (m: string) => m === 'email' ? '✉️' : m === 'whatsapp' ? '📱' : '📞';

  return (
    <div>
      <SecHead title="🔒 Private Event Reservations" count={reservations.length} />
      <div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
        {(['pending', 'confirmed', 'cancelled', 'all'] as const).map(s => (
          <Btn key={s} size="sm" variant={statusFilter === s ? 'primary' : 'secondary'} onClick={() => setStatusFilter(s)}>
            {s.charAt(0).toUpperCase() + s.slice(1)}
          </Btn>
        ))}
      </div>
      {loading ? <Empty icon="⏳" title="Loading..." /> : reservations.length === 0 ? <Empty icon="🔒" title="No reservations" desc={`No ${statusFilter === 'all' ? '' : statusFilter} reservations`} /> : (
        <div style={{ display: 'grid', gap: '12px' }}>
          {reservations.map((r: any) => (
            <div key={r.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', border: `1px solid ${r.status === 'pending' ? '#f59e0b' : r.status === 'confirmed' ? '#10b981' : '#ef4444'}` }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '12px' }}>
                <div>
                  <div style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>{r.event_name}</div>
                  <div style={{ fontSize: '13px', color: '#666', marginTop: '4px' }}>{r.guests} guests • {formatDate(r.event_date)} • {formatTime(r.event_time)}</div>
                </div>
                <span style={{ 
                  padding: '4px 10px', borderRadius: 12, fontSize: '12px', fontWeight: 600,
                  background: r.status === 'confirmed' ? '#d1fae5' : r.status === 'cancelled' ? '#fee2e2' : '#fef3c7',
                  color: r.status === 'confirmed' ? '#047857' : r.status === 'cancelled' ? '#b91c1c' : '#b45309'
                }}>{r.status}</span>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', fontSize: '13px', marginBottom: '12px' }}>
                <div><strong>Contact:</strong> {r.contact_name}</div>
                <div><strong>Method:</strong> {contactMethodIcon(r.contact_method)} {r.contact_method}</div>
                {r.contact_email && <div><strong>Email:</strong> {r.contact_email}</div>}
                {r.contact_phone && <div><strong>Phone:</strong> {r.contact_phone}</div>}
              </div>
              {r.notes && <div style={{ fontSize: '13px', color: '#666', marginBottom: '12px', fontStyle: 'italic' }}>"{r.notes}"</div>}
              <div style={{ display: 'flex', gap: '8px' }}>
                {r.status === 'pending' && (
                  <>
                    <Btn size="sm" variant="secondary" onClick={() => updateStatus(r.id, 'confirmed')}>✓ Confirm</Btn>
                    <Btn size="sm" variant="danger" onClick={() => updateStatus(r.id, 'cancelled')}>✗ Cancel</Btn>
                  </>
                )}
                {r.status === 'confirmed' && <Btn size="sm" variant="danger" onClick={() => updateStatus(r.id, 'cancelled')}>✗ Cancel</Btn>}
                {r.status === 'cancelled' && <Btn size="sm" variant="secondary" onClick={() => updateStatus(r.id, 'confirmed')}>✓ Reactivate</Btn>}
                <Btn size="sm" variant="danger" onClick={() => setConfirmDel(r.id)}>🗑 Delete</Btn>
              </div>
            </div>
          ))}
        </div>
      )}
      {confirmDel !== null && <Confirm message="Delete this reservation?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

/* ─── Room Reservations Section ─── */
function RoomReservationsSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [reservations, setReservations] = useState<RoomReservation[]>([]);
  const [statusFilter, setStatusFilter] = useState<'pending' | 'confirmed' | 'cancelled' | 'all'>('pending');
  const [loading, setLoading] = useState(true);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  useEffect(() => { loadReservations(); }, [statusFilter]);

  const loadReservations = async () => {
    setLoading(true);
    try {
      const url = statusFilter === 'all' ? '/api/admin/room-reservations?status=all' : `/api/admin/room-reservations?status=${statusFilter}`;
      const res = await fetch(url);
      const data = await res.json();
      setReservations(data.reservations || []);
    } catch { onToast('Error loading reservations', 'error'); }
    setLoading(false);
  };

  const updateStatus = async (id: number, status: 'confirmed' | 'cancelled') => {
    try {
      const res = await fetch('/api/admin/room-reservations', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id, status }),
      });
      if (res.ok) {
        setReservations(r => r.map(x => x.id === id ? { ...x, status } : x));
        onToast(`Reservation ${status}`, 'success');
      }
    } catch { onToast('Error updating reservation', 'error'); }
  };

  const del = async (id: number) => {
    try {
      await fetch(`/api/admin/room-reservations?id=${id}`, { method: 'DELETE' });
      setReservations(r => r.filter(x => x.id !== id));
      onToast('Reservation deleted', 'success');
    } catch { onToast('Error deleting reservation', 'error'); }
    setConfirmDel(null);
  };

  const formatDate = (d: string) => new Date(d).toLocaleDateString();
  const formatPrice = (p: string) => `$${parseFloat(p).toFixed(2)}`;

  return (
    <div>
      <SecHead title="🛏️ Room Bookings" count={reservations.length} />
      <div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
        {(['pending', 'confirmed', 'cancelled', 'all'] as const).map(s => (
          <Btn key={s} size="sm" variant={statusFilter === s ? 'primary' : 'secondary'} onClick={() => setStatusFilter(s)}>
            {s.charAt(0).toUpperCase() + s.slice(1)}
          </Btn>
        ))}
      </div>
      {loading ? <Empty icon="⏳" title="Loading..." /> : reservations.length === 0 ? <Empty icon="🛏️" title="No bookings" desc={`No ${statusFilter === 'all' ? '' : statusFilter} bookings`} /> : (
        <div style={{ display: 'grid', gap: '12px' }}>
          {reservations.map((r) => (
            <div key={r.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', border: `1px solid ${r.status === 'pending' ? '#f59e0b' : r.status === 'confirmed' ? '#10b981' : '#ef4444'}` }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '12px' }}>
                <div>
                  <div style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>{r.room_name || `Room #${r.room_id}`}</div>
                  <div style={{ fontSize: '13px', color: '#666', marginTop: '4px' }}>
                    {formatDate(r.check_in)} → {formatDate(r.check_out)} • {formatPrice(r.total_price)}
                  </div>
                </div>
                <span style={{
                  padding: '4px 10px', borderRadius: 12, fontSize: '12px', fontWeight: 600,
                  background: r.status === 'confirmed' ? '#d1fae5' : r.status === 'cancelled' ? '#fee2e2' : '#fef3c7',
                  color: r.status === 'confirmed' ? '#047857' : r.status === 'cancelled' ? '#b91c1c' : '#b45309'
                }}>{r.status}</span>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', fontSize: '13px', marginBottom: '12px' }}>
                <div><strong>Guest:</strong> {r.guest_name || r.username || r.first_name || 'N/A'}</div>
                {r.guest_contact && <div><strong>Contact:</strong> {r.guest_contact}</div>}
                {r.guest_contact_method && <div><strong>Method:</strong> {r.guest_contact_method}</div>}
              </div>
              <div style={{ display: 'flex', gap: '8px' }}>
                {r.status === 'pending' && (
                  <>
                    <Btn size="sm" variant="secondary" onClick={() => updateStatus(r.id, 'confirmed')}>✓ Confirm</Btn>
                    <Btn size="sm" variant="danger" onClick={() => updateStatus(r.id, 'cancelled')}>✗ Cancel</Btn>
                  </>
                )}
                {r.status === 'confirmed' && <Btn size="sm" variant="danger" onClick={() => updateStatus(r.id, 'cancelled')}>✗ Cancel</Btn>}
                {r.status === 'cancelled' && <Btn size="sm" variant="secondary" onClick={() => updateStatus(r.id, 'confirmed')}>✓ Reactivate</Btn>}
                <Btn size="sm" variant="danger" onClick={() => setConfirmDel(r.id)}>🗑 Delete</Btn>
              </div>
            </div>
          ))}
        </div>
      )}
      {confirmDel !== null && <Confirm message="Delete this booking?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

/* ─── Restaurant Reservations Section ─── */
function RestaurantReservationsSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [reservations, setReservations] = useState<RestaurantReservation[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => { loadReservations(); }, []);

  const loadReservations = async () => {
    setLoading(true);
    try {
      const res = await fetch('/api/admin/restaurant-reservations');
      const data = await res.json();
      setReservations(data.reservations || []);
    } catch { onToast('Error loading reservations', 'error'); }
    setLoading(false);
  };

  const del = async (id: number) => {
    try {
      await fetch(`/api/admin/restaurant-reservations?id=${id}`, { method: 'DELETE' });
      setReservations(r => r.filter(x => x.id !== id));
      onToast('Reservation deleted', 'success');
    } catch { onToast('Error deleting reservation', 'error'); }
  };

  return (
    <div>
      <SecHead title="🍽️ Restaurant Reservations" count={reservations.length} />
      {loading ? <Empty icon="⏳" title="Loading..." /> : reservations.length === 0 ? <Empty icon="🍽️" title="No reservations" desc="No restaurant reservations yet" /> : (
        <div style={{ display: 'grid', gap: '12px' }}>
          {reservations.map((r) => (
            <div key={r.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', border: `1px solid ${C.border}` }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '8px' }}>
                <div>
                  <div style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>{r.table_name}</div>
                  <div style={{ fontSize: '13px', color: '#666', marginTop: '4px' }}>
                    {formatDisplayDate(r.date)} at {r.time} • {r.guests} guests
                  </div>
                </div>
                <div style={{ fontSize: '12px', color: C.textLight }}>{formatDisplayDateTime(r.created_at)}</div>
              </div>
              <div style={{ fontSize: '13px', color: '#666', marginBottom: '8px' }}>
                <strong>Guest:</strong> {r.username || r.first_name || 'Guest'}
              </div>
              <Btn size="sm" variant="danger" onClick={() => del(r.id)}>🗑 Delete</Btn>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ─── Orders Section ─── */
function OrdersSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [orders, setOrders] = useState<Order[]>([]);
  const [statusFilter, setStatusFilter] = useState<'pending' | 'preparing' | 'ready' | 'delivered' | 'cancelled' | 'all'>('pending');
  const [loading, setLoading] = useState(true);

  useEffect(() => { loadOrders(); }, [statusFilter]);

  const loadOrders = async () => {
    setLoading(true);
    try {
      const url = statusFilter === 'all' ? '/api/orders?status=all' : `/api/orders?status=${statusFilter}`;
      const res = await fetch(url);
      const data = await res.json();
      setOrders(data.orders || []);
    } catch { onToast('Error loading orders', 'error'); }
    setLoading(false);
  };

  const updateStatus = async (id: number, status: string) => {
    try {
      const res = await fetch('/api/orders', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ order_id: id, status }),
      });
      if (res.ok) {
        setOrders(o => o.map(x => x.id === id ? { ...x, status } : x));
        onToast(`Order ${status}`, 'success');
      }
    } catch { onToast('Error updating order', 'error'); }
  };

  const formatPrice = (p: string) => `$${parseFloat(p).toFixed(2)}`;
  const statusColor = (s: string) => s === 'pending' ? '#f59e0b' : s === 'preparing' ? '#3b82f6' : s === 'ready' ? '#10b981' : s === 'delivered' ? '#6b7280' : '#ef4444';

  return (
    <div>
      <SecHead title="📦 Food Orders" count={orders.length} />
      <div style={{ display: 'flex', gap: '8px', marginBottom: '16px', flexWrap: 'wrap' }}>
        {(['pending', 'preparing', 'ready', 'delivered', 'cancelled', 'all'] as const).map(s => (
          <Btn key={s} size="sm" variant={statusFilter === s ? 'primary' : 'secondary'} onClick={() => setStatusFilter(s)}>
            {s.charAt(0).toUpperCase() + s.slice(1)}
          </Btn>
        ))}
      </div>
      {loading ? <Empty icon="⏳" title="Loading..." /> : orders.length === 0 ? <Empty icon="📦" title="No orders" desc={`No ${statusFilter === 'all' ? '' : statusFilter} orders`} /> : (
        <div style={{ display: 'grid', gap: '12px' }}>
          {orders.map((o) => (
            <div key={o.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', border: `1px solid ${statusColor(o.status)}` }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '12px' }}>
                <div>
                  <div style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>
                    {o.order_type === 'room_delivery' ? `🚪 Room ${o.room_name || o.room_id}` : o.order_type === 'dine_in' ? '🍽️ Dine-in' : '📦 Pickup'}
                  </div>
                  <div style={{ fontSize: '13px', color: '#666', marginTop: '4px' }}>
                    {formatPrice(o.total)} • {formatDisplayDateTime(o.created_at)}
                  </div>
                  {o.username && <div style={{ fontSize: '12px', color: '#888', marginTop: '2px' }}>👤 {o.first_name || o.username}</div>}
                </div>
                <span style={{
                  padding: '4px 10px', borderRadius: 12, fontSize: '12px', fontWeight: 600,
                  background: `${statusColor(o.status)}20`, color: statusColor(o.status)
                }}>{o.status}</span>
              </div>
              <div style={{ marginBottom: '12px' }}>
                {o.items?.map((item, i) => (
                  <div key={i} style={{ fontSize: '13px', color: '#666', display: 'flex', justifyContent: 'space-between' }}>
                    <span>{item.quantity}x {item.name}</span>
                    <span>{formatPrice(item.total_price)}</span>
                  </div>
                ))}
              </div>
              {o.notes && <div style={{ fontSize: '13px', color: '#666', fontStyle: 'italic', marginBottom: '12px' }}>"{o.notes}"</div>}
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {o.status === 'pending' && (
                  <>
                    <Btn size="sm" variant="secondary" onClick={() => updateStatus(o.id, 'preparing')}>🍳 Start Preparing</Btn>
                    <Btn size="sm" variant="danger" onClick={() => updateStatus(o.id, 'cancelled')}>✗ Cancel</Btn>
                  </>
                )}
                {o.status === 'preparing' && <Btn size="sm" variant="secondary" onClick={() => updateStatus(o.id, 'ready')}>✓ Ready</Btn>}
                {o.status === 'ready' && <Btn size="sm" variant="secondary" onClick={() => updateStatus(o.id, 'delivered')}>✓ Delivered</Btn>}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}


/* Kitchen Section */
function KitchenSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [orders, setOrders] = useState<Order[]>([]);
  const [loading, setLoading] = useState(true);
  const [autoRefresh, setAutoRefresh] = useState(true);

  const loadOrders = async () => {
    try {
      const res = await fetch('/api/orders?status=all');
      const data = await res.json();
      const active = (data.orders || []).filter((o: Order) => ['pending', 'preparing', 'ready'].includes(o.status));
      setOrders(active);
    } catch { onToast('Error loading orders', 'error'); }
    setLoading(false);
  };

  useEffect(() => {
    loadOrders();
    if (autoRefresh) {
      const interval = setInterval(loadOrders, 30000);
      return () => clearInterval(interval);
    }
  }, [autoRefresh]);

  const updateStatus = async (id: number, status: string) => {
    try {
      const res = await fetch('/api/orders', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ order_id: id, status }),
      });
      if (res.ok) {
        if (status === 'delivered' || status === 'cancelled') {
          setOrders(o => o.filter(x => x.id !== id));
        } else {
          setOrders(o => o.map(x => x.id === id ? { ...x, status } : x));
        }
        onToast(`Order ${status}`, 'success');
      }
    } catch { onToast('Error updating order', 'error'); }
  };

  const formatPrice = (p: string) => `$${parseFloat(p).toFixed(2)}`;
  const statusColor = (s: string) => s === 'pending' ? '#f59e0b' : s === 'preparing' ? '#3b82f6' : '#10b981';

  const pending = orders.filter(o => o.status === 'pending');
  const preparing = orders.filter(o => o.status === 'preparing');
  const ready = orders.filter(o => o.status === 'ready');

  const OrderCard = ({ o }: { o: Order }) => (
    <div style={{ background: '#fff', borderRadius: 12, padding: '16px', border: `2px solid ${statusColor(o.status)}`, boxShadow: C.shadow }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '12px' }}>
        <div>
          <div style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>
            {o.order_type === 'room_delivery' ? `Room ${o.room_name || o.room_id}` : o.order_type === 'dine_in' ? 'Dine-in' : 'Pickup'}
          </div>
          <div style={{ fontSize: '13px', color: '#666', marginTop: '4px' }}>
            {formatPrice(o.total)} - {formatDisplayDateTime(o.created_at)}
          </div>
          {o.username && <div style={{ fontSize: '12px', color: '#888', marginTop: '2px' }}>User: {o.first_name || o.username}</div>}
        </div>
        <span style={{
          padding: '4px 12px', borderRadius: 12, fontSize: '12px', fontWeight: 600,
          background: statusColor(o.status), color: '#fff'
        }}>{o.status.toUpperCase()}</span>
      </div>
      <div style={{ marginBottom: '12px', maxHeight: '120px', overflowY: 'auto' }}>
        {o.items?.map((item, i) => (
          <div key={i} style={{ fontSize: '14px', color: '#333', display: 'flex', justifyContent: 'space-between', padding: '4px 0' }}>
            <span style={{ fontWeight: 500 }}>{item.quantity}x {item.name}</span>
            <span style={{ color: '#666' }}>{formatPrice(item.total_price)}</span>
          </div>
        ))}
      </div>
      {o.notes && <div style={{ fontSize: '13px', color: '#b45309', background: '#fef3c7', padding: '8px 12px', borderRadius: 6, marginBottom: '12px', fontStyle: 'italic' }}>Note: "{o.notes}"</div>}
      <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
        {o.status === 'pending' && (
          <>
            <Btn onClick={() => updateStatus(o.id, 'preparing')}>Start Preparing</Btn>
            <Btn variant="danger" onClick={() => updateStatus(o.id, 'cancelled')}>Cancel</Btn>
          </>
        )}
        {o.status === 'preparing' && <Btn onClick={() => updateStatus(o.id, 'ready')}>Mark Ready</Btn>}
        {o.status === 'ready' && <Btn onClick={() => updateStatus(o.id, 'delivered')}>Delivered</Btn>}
      </div>
    </div>
  );

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
        <h2 style={{ margin: 0, fontSize: '24px', fontWeight: 700, color: C.navy }}>Kitchen Dashboard</h2>
        <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px', cursor: 'pointer' }}>
          <input type="checkbox" checked={autoRefresh} onChange={e => setAutoRefresh(e.target.checked)} style={{ width: 16, height: 16, accentColor: C.gold }} />
          Auto-refresh (30s)
        </label>
      </div>

      {loading ? <Empty icon="Loading..." title="Loading..." /> : orders.length === 0 ? (
        <Empty icon="Done" title="All caught up!" desc="No active orders" />
      ) : (
        <div style={{ display: 'grid', gap: '24px' }}>
          {pending.length > 0 && (
            <div>
              <h3 style={{ margin: '0 0 12px', fontSize: '18px', fontWeight: 600, color: '#f59e0b' }}>Pending ({pending.length})</h3>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))', gap: '12px' }}>
                {pending.map(o => <OrderCard key={o.id} o={o} />)}
              </div>
            </div>
          )}
          {preparing.length > 0 && (
            <div>
              <h3 style={{ margin: '0 0 12px', fontSize: '18px', fontWeight: 600, color: '#3b82f6' }}>Preparing ({preparing.length})</h3>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))', gap: '12px' }}>
                {preparing.map(o => <OrderCard key={o.id} o={o} />)}
              </div>
            </div>
          )}
          {ready.length > 0 && (
            <div>
              <h3 style={{ margin: '0 0 12px', fontSize: '18px', fontWeight: 600, color: '#10b981' }}>Ready for Delivery ({ready.length})</h3>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))', gap: '12px' }}>
                {ready.map(o => <OrderCard key={o.id} o={o} />)}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

/* Room Assignments Section */
type RoomAssignment = { id: number; room_id: number; room_name: string; user_id: number; username: string; first_name: string | null; last_name: string | null; email: string; check_in: string; check_out: string; notes: string | null };

function RoomAssignmentsSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [assignments, setAssignments] = useState<RoomAssignment[]>([]);
  const [rooms, setRooms] = useState<Room[]>([]);
  const [users, setUsers] = useState<{ id: number; username: string; first_name: string | null; last_name: string | null }[]>([]);
  const [loading, setLoading] = useState(true);
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState({ room_id: '', user_id: '', check_in: '', check_out: '', notes: '' });

  useEffect(() => {
    Promise.all([
      fetch('/api/room-assignments').then(r => r.json()),
      fetch('/api/rooms').then(r => r.json()),
      fetch('/api/admin/users').then(r => r.json()),
    ]).then(([assignData, roomData, userData]) => {
      setAssignments(assignData.assignments || []);
      setRooms(roomData.rooms || []);
      setUsers(userData.users || []);
    }).catch(() => onToast('Error loading data', 'error'))
    .finally(() => setLoading(false));
  }, []);

  const today = new Date().toISOString().split('T')[0];
  const active = assignments.filter(a => a.check_in <= today && a.check_out >= today);
  const upcoming = assignments.filter(a => a.check_in > today);

  const saveAssignment = async () => {
    if (!form.room_id || !form.user_id || !form.check_in || !form.check_out) {
      onToast('All fields required', 'error');
      return;
    }
    try {
      const res = await fetch('/api/room-assignments', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(form),
      });
      if (res.ok) {
        const data = await res.json();
        setAssignments(a => [...a, data.assignment]);
        setForm({ room_id: '', user_id: '', check_in: '', check_out: '', notes: '' });
        setShowForm(false);
        onToast('Assignment created', 'success');
      } else {
        const err = await res.json();
        onToast(err.error || 'Failed to create assignment', 'error');
      }
    } catch { onToast('Error saving assignment', 'error'); }
  };

  const deleteAssignment = async (id: number) => {
    if (!confirm('Delete this assignment?')) return;
    try {
      await fetch(`/api/room-assignments?id=${id}`, { method: 'DELETE' });
      setAssignments(a => a.filter(x => x.id !== id));
      onToast('Assignment deleted', 'success');
    } catch { onToast('Error deleting assignment', 'error'); }
  };

  return (
    <div>
      <SecHead title="Room Assignments" count={assignments.length} action={<Btn onClick={() => setShowForm(true)}>+ Assign Room</Btn>} />

      {showForm && (
        <div style={{ background: '#fff', borderRadius: 12, padding: '20px', marginBottom: '20px', boxShadow: C.shadow }}>
          <h3 style={{ margin: '0 0 16px', fontSize: '16px', fontWeight: 600, color: C.navy }}>New Assignment</h3>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '12px', marginBottom: '16px' }}>
            <S label="Room" value={form.room_id} onChange={(v: string) => setForm(f => ({ ...f, room_id: v }))} options={rooms.map(r => ({ value: r.id.toString(), label: r.name }))} />
            <S label="User" value={form.user_id} onChange={(v: string) => setForm(f => ({ ...f, user_id: v }))} options={users.map(u => ({ value: u.id.toString(), label: `${u.username} (${u.first_name || ''} ${u.last_name || ''})`.trim() }))} />
            <I label="Check-in" type="date" value={form.check_in} onChange={(v: string) => setForm(f => ({ ...f, check_in: v }))} />
            <I label="Check-out" type="date" value={form.check_out} onChange={(v: string) => setForm(f => ({ ...f, check_out: v }))} />
          </div>
          <TA label="Notes (optional)" value={form.notes} onChange={(v: string) => setForm(f => ({ ...f, notes: v }))} rows={2} />
          <div style={{ display: 'flex', gap: '8px', marginTop: '12px' }}>
            <Btn onClick={saveAssignment}>Save Assignment</Btn>
            <Btn variant="secondary" onClick={() => { setShowForm(false); setForm({ room_id: '', user_id: '', check_in: '', check_out: '', notes: '' }); }}>Cancel</Btn>
          </div>
        </div>
      )}

      {loading ? <Empty icon="Loading..." title="Loading..." /> : (
        <div>
          <div style={{ marginBottom: '24px' }}>
            <h3 style={{ margin: '0 0 12px', fontSize: '16px', fontWeight: 600, color: C.navy }}>Currently Active ({active.length})</h3>
            {active.length === 0 ? (
              <div style={{ background: '#fff', borderRadius: 12, padding: '20px', textAlign: 'center', color: C.textLight }}>No active assignments</div>
            ) : (
              <div style={{ display: 'grid', gap: '8px' }}>
                {active.map(a => (
                  <div key={a.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', boxShadow: C.shadow, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '12px' }}>
                    <div>
                      <div style={{ fontWeight: 600, color: C.navy }}>{a.room_name}</div>
                      <div style={{ fontSize: '13px', color: '#666' }}>User: {a.first_name || a.username} {a.last_name || ''} ({a.email})</div>
                      <div style={{ fontSize: '12px', color: '#888' }}>Dates: {a.check_in} to {a.check_out}</div>
                      {a.notes && <div style={{ fontSize: '12px', color: '#666', fontStyle: 'italic', marginTop: '4px' }}>Note: {a.notes}</div>}
                    </div>
                    <Btn variant="danger" size="sm" onClick={() => deleteAssignment(a.id)}>Remove</Btn>
                  </div>
                ))}
              </div>
            )}
          </div>

          {upcoming.length > 0 && (
            <div>
              <h3 style={{ margin: '0 0 12px', fontSize: '16px', fontWeight: 600, color: C.navy }}>Upcoming ({upcoming.length})</h3>
              <div style={{ display: 'grid', gap: '8px' }}>
                {upcoming.map(a => (
                  <div key={a.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', boxShadow: C.shadow, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '12px' }}>
                    <div>
                      <div style={{ fontWeight: 600, color: C.navy }}>{a.room_name}</div>
                      <div style={{ fontSize: '13px', color: '#666' }}>User: {a.first_name || a.username} {a.last_name || ''}</div>
                      <div style={{ fontSize: '12px', color: '#888' }}>Dates: {a.check_in} to {a.check_out}</div>
                    </div>
                    <Btn variant="danger" size="sm" onClick={() => deleteAssignment(a.id)}>Remove</Btn>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function RoomsSection({ rooms, setRooms, images, onToast }: any) {
  const [editing, setEditing] = useState<Room | null>(null);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  const save = async (room: Room) => {
    try {
      const url = room.id ? `/api/rooms/${room.id}` : '/api/rooms';
      const res = await fetch(url, {
        method: room.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(room),
      });
      if (res.ok) {
        const data = await res.json();
        setEditing(null);
        setRooms((r: any) => room.id ? r.map((x: Room) => x.id === room.id ? data.data : x) : [...r, data.data]);
        onToast('Room saved!', 'success');
      }
    } catch { onToast('Error', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/rooms/${id}`, { method: 'DELETE' });
    setRooms((r: any) => r.filter((x: Room) => x.id !== id));
    onToast('Room deleted', 'success');
    setConfirmDel(null);
  };

  return (
    <div>
      <SecHead title="🏨 Rooms" count={rooms.length}
        action={<Btn onClick={() => setEditing({ id: 0, name: '', description: '', price: '', photos: [], featured_photo: null, active: true, sort_order: rooms.length })} size="sm">+ New Room</Btn>} />
      {rooms.length === 0 ? <Empty icon="🏨" title="No rooms" /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px' }}>
          {rooms.map((r: Room) => (
            <EntityCard key={r.id} title={r.name} desc={r.description || ''} meta={r.price}
              thumb={r.featured_photo || r.photos?.[0]}
              photoUrls={r.photos}
              actions={
                <>
                  <Btn size="sm" variant="secondary" onClick={() => setEditing(r)}>Edit</Btn>
                  <Btn size="sm" variant="danger" onClick={() => setConfirmDel(r.id)}>Del</Btn>
                </>
              } />
          ))}
        </div>
      )}
      {editing && <RoomEditor room={editing} setRoom={setEditing} images={images} onSave={save} onCancel={() => setEditing(null)} />}
      {confirmDel !== null && <Confirm message="Delete this room?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

/* ─── Room Status Section ─── */
type StaffMember = { id: number; first_name: string | null; last_name: string | null; username: string };
type RoomStatus = {
  id: number;
  name: string;
  price: string;
  clean_status: 'clean' | 'dirty' | 'maintenance';
  notes: string | null;
  active: boolean;
  last_cleaned: string | null;
  assigned_staff_id: number | null;
  assigned_staff: { id: number; first_name: string | null; last_name: string | null } | null;
  priority: 'urgent' | 'normal' | 'low';
  issues_count: number;
  is_vip: boolean;
  checkout_time: string | null;
  checkout_date: string | null;
  occupancy_status: 'available' | 'occupied';
  current_guest: string | null;
  reservation_id: number | null;
  payment_status: 'pending' | 'paid' | 'partial' | null;
  upcoming_reservations: Array<{
    id: number;
    guest_name: string | null;
    check_in: string;
    check_out: string;
    status: string;
    payment_status: string;
    first_name: string | null;
    last_name: string | null;
  }>;
};

function RoomStatusSection({ onToast }: { onToast: (msg: string, type: 'success' | 'error') => void }) {
  const [rooms, setRooms] = useState<RoomStatus[]>([]);
  const [staff, setStaff] = useState<StaffMember[]>([]);
  const [loading, setLoading] = useState(true);
  const [editingRoom, setEditingRoom] = useState<number | null>(null);
  const [editData, setEditData] = useState<{
    clean_status: 'clean' | 'dirty' | 'maintenance';
    notes: string;
    priority: 'urgent' | 'normal' | 'low';
    assigned_staff_id: number | null;
    issues_count: number;
    is_vip: boolean;
    checkout_time: string;
    checkout_date: string;
  }>({
    clean_status: 'clean',
    notes: '',
    priority: 'normal',
    assigned_staff_id: null,
    issues_count: 0,
    is_vip: false,
    checkout_time: '',
    checkout_date: '',
  });

  useEffect(() => { loadRooms(); }, []);

  const loadRooms = async () => {
    setLoading(true);
    try {
      const res = await fetch('/api/admin/room-status');
      const data = await res.json();
      setRooms(data.rooms || []);
      setStaff(data.staff || []);
    } catch { onToast('Error loading room status', 'error'); }
    setLoading(false);
  };

  const updateRoomStatus = async () => {
    if (editingRoom === null) return;
    try {
      const res = await fetch('/api/admin/room-status', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          id: editingRoom,
          clean_status: editData.clean_status,
          notes: editData.notes || null,
          priority: editData.priority,
          assigned_staff_id: editData.assigned_staff_id,
          issues_count: editData.issues_count,
          is_vip: editData.is_vip,
          checkout_time: editData.checkout_time || null,
          checkout_date: editData.checkout_date || null,
        }),
      });
      if (res.ok) {
        await loadRooms();
        onToast('Room status updated', 'success');
      }
    } catch { onToast('Error updating status', 'error'); }
    setEditingRoom(null);
  };

  const startEdit = (room: RoomStatus) => {
    setEditingRoom(room.id);
    setEditData({
      clean_status: room.clean_status,
      notes: room.notes || '',
      priority: room.priority,
      assigned_staff_id: room.assigned_staff_id,
      issues_count: room.issues_count,
      is_vip: room.is_vip,
      checkout_time: room.checkout_time || '',
      checkout_date: room.checkout_date || '',
    });
  };

  const getStatusIcon = (status: string) => {
    switch (status) {
      case 'clean': return '✨';
      case 'dirty': return '🧹';
      case 'maintenance': return '🔧';
      default: return '❓';
    }
  };

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'clean': return { bg: '#d1fae5', color: '#047857', border: '#10b981' };
      case 'dirty': return { bg: '#fef3c7', color: '#b45309', border: '#f59e0b' };
      case 'maintenance': return { bg: '#fee2e2', color: '#b91c1c', border: '#ef4444' };
      default: return { bg: '#f3f4f6', color: '#6b7280', border: '#d1d5db' };
    }
  };

  const getPriorityStyle = (priority: string) => {
    switch (priority) {
      case 'urgent': return { bg: '#fee2e2', color: '#b91c1c', icon: '🔴' };
      case 'normal': return { bg: '#dbeafe', color: '#1d4ed8', icon: '🔵' };
      case 'low': return { bg: '#f3f4f6', color: '#6b7280', icon: '⚪' };
      default: return { bg: '#f3f4f6', color: '#6b7280', icon: '⚪' };
    }
  };

  const getPaymentBadge = (status: string | null) => {
    if (!status) return null;
    const colors: Record<string, { bg: string; color: string }> = {
      pending: { bg: '#fef3c7', color: '#b45309' },
      partial: { bg: '#dbeafe', color: '#1d4ed8' },
      paid: { bg: '#d1fae5', color: '#047857' },
    };
    const c = colors[status] || colors.pending;
    return (
      <span style={{ padding: '2px 8px', borderRadius: 12, fontSize: '11px', fontWeight: 600, background: c.bg, color: c.color }}>
        {status}
      </span>
    );
  };

  const formatDate = (d: string) => new Date(d).toLocaleDateString();
  const formatDateTime = (d: string) => new Date(d).toLocaleString();
  const formatTime = (t: string) => t ? t.substring(0, 5) : '';

  return (
    <div>
      <SecHead title="🧹 Room Status" count={rooms.length} />
      {loading ? (
        <Empty icon="⏳" title="Loading..." />
      ) : rooms.length === 0 ? (
        <Empty icon="🏨" title="No rooms" desc="Add rooms in the Rooms section" />
      ) : (
        <div style={{ display: 'grid', gap: '12px' }}>
          {rooms.map(room => {
            const statusColors = getStatusColor(room.clean_status);
            const priorityStyle = getPriorityStyle(room.priority);
            const isEditing = editingRoom === room.id;
            
            return (
              <div key={room.id} style={{ background: '#fff', borderRadius: 12, border: `1px solid ${C.border}`, overflow: 'hidden' }}>
                {/* Header Row */}
                <div style={{ display: 'flex', alignItems: 'center', padding: '12px 16px', background: room.is_vip ? '#fef3c7' : room.occupancy_status === 'occupied' ? '#f0fdf4' : '#fafafa', gap: '12px' }}>
                  {/* Room Name & Status */}
                  <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: '10px', flexWrap: 'wrap' }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>
                      <span style={{ fontSize: '20px' }}>{getStatusIcon(room.clean_status)}</span>
                      <span style={{ fontWeight: 600, fontSize: '16px', color: C.navy }}>{room.name}</span>
                    </div>
                    {room.is_vip && (
                      <span style={{ padding: '2px 8px', borderRadius: 12, fontSize: '11px', fontWeight: 700, background: '#fbbf24', color: '#78350f' }}>
                        ⭐ VIP
                      </span>
                    )}
                    <span style={{
                      padding: '4px 10px',
                      borderRadius: 12,
                      fontSize: '12px',
                      fontWeight: 600,
                      background: statusColors.bg,
                      color: statusColors.color,
                      border: `1px solid ${statusColors.border}`
                    }}>
                      {room.clean_status}
                    </span>
                    <span style={{
                      padding: '4px 10px',
                      borderRadius: 12,
                      fontSize: '12px',
                      fontWeight: 600,
                      background: room.occupancy_status === 'occupied' ? '#d1fae5' : '#e0e7ff',
                      color: room.occupancy_status === 'occupied' ? '#047857' : '#4338ca'
                    }}>
                      {room.occupancy_status === 'occupied' ? '🛏️ Occupied' : '🚪 Available'}
                    </span>
                    <span style={{
                      padding: '4px 10px',
                      borderRadius: 12,
                      fontSize: '12px',
                      fontWeight: 600,
                      background: priorityStyle.bg,
                      color: priorityStyle.color
                    }}>
                      {priorityStyle.icon} {room.priority}
                    </span>
                    {room.issues_count > 0 && (
                      <span style={{ padding: '2px 8px', borderRadius: 12, fontSize: '11px', fontWeight: 600, background: '#fee2e2', color: '#b91c1c' }}>
                        ⚠️ {room.issues_count} issue{room.issues_count > 1 ? 's' : ''}
                      </span>
                    )}
                  </div>
                  
                  {/* Price */}
                  <div style={{ fontWeight: 600, color: C.gold, fontSize: '15px' }}>
                    ${parseFloat(room.price).toFixed(2)}/night
                  </div>
                  
                  {/* Edit Button */}
                  <Btn size="sm" variant="secondary" onClick={() => isEditing ? setEditingRoom(null) : startEdit(room)}>
                    {isEditing ? 'Cancel' : 'Edit'}
                  </Btn>
                </div>
                
                {/* Details Row */}
                <div style={{ padding: '12px 16px', borderTop: `1px solid ${C.border}` }}>
                  {/* Quick Info Grid */}
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '8px', marginBottom: '12px' }}>
                    {/* Current Guest */}
                    {room.current_guest && (
                      <div style={{ fontSize: '13px' }}>
                        <span style={{ color: '#666' }}>Guest: </span>
                        <span style={{ fontWeight: 600, color: C.navy }}>{room.current_guest}</span>
                        {getPaymentBadge(room.payment_status)}
                      </div>
                    )}
                    
                    {/* Checkout */}
                    {room.checkout_date && (
                      <div style={{ fontSize: '13px' }}>
                        <span style={{ color: '#666' }}>Checkout: </span>
                        <span style={{ fontWeight: 500 }}>{formatDate(room.checkout_date)}</span>
                        {room.checkout_time && <span> at {formatTime(room.checkout_time)}</span>}
                      </div>
                    )}
                    
                    {/* Last Cleaned */}
                    {room.last_cleaned && (
                      <div style={{ fontSize: '13px' }}>
                        <span style={{ color: '#666' }}>Last cleaned: </span>
                        <span style={{ fontWeight: 500 }}>{formatDateTime(room.last_cleaned)}</span>
                      </div>
                    )}
                    
                    {/* Assigned Staff */}
                    {room.assigned_staff && (
                      <div style={{ fontSize: '13px' }}>
                        <span style={{ color: '#666' }}>Staff: </span>
                        <span style={{ fontWeight: 500 }}>{room.assigned_staff.first_name || ''} {room.assigned_staff.last_name || ''}</span>
                      </div>
                    )}
                  </div>
                  
                  {/* Upcoming Reservations */}
                  {room.upcoming_reservations && room.upcoming_reservations.length > 0 && (
                    <div style={{ marginBottom: '8px' }}>
                      <div style={{ fontSize: '12px', color: '#888', marginBottom: '4px' }}>Upcoming:</div>
                      {room.upcoming_reservations.map((res, i) => (
                        <div key={res.id || i} style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '13px', marginBottom: '2px' }}>
                          <span>📅 {formatDate(res.check_in)} → {formatDate(res.check_out)}</span>
                          <span style={{ fontWeight: 500 }}>{res.guest_name || res.first_name || 'Guest'}</span>
                          {getPaymentBadge(res.payment_status)}
                        </div>
                      ))}
                    </div>
                  )}
                  
                  {/* Notes */}
                  {room.notes && !isEditing && (
                    <div style={{ fontSize: '13px', color: '#666', fontStyle: 'italic' }}>
                      📝 {room.notes}
                    </div>
                  )}
                  
                  {/* Edit Form */}
                  {isEditing && (
                    <div style={{ marginTop: '12px', display: 'flex', flexDirection: 'column', gap: '12px' }}>
                      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '12px' }}>
                        <S
                          label="Clean Status"
                          value={editData.clean_status}
                          onChange={(v: any) => setEditData(prev => ({ ...prev, clean_status: v }))}
                          options={[
                            { value: 'clean', label: '✨ Clean' },
                            { value: 'dirty', label: '🧹 Dirty' },
                            { value: 'maintenance', label: '🔧 Maintenance' },
                          ]}
                        />
                        <S
                          label="Priority"
                          value={editData.priority}
                          onChange={(v: any) => setEditData(prev => ({ ...prev, priority: v }))}
                          options={[
                            { value: 'urgent', label: '🔴 Urgent' },
                            { value: 'normal', label: '🔵 Normal' },
                            { value: 'low', label: '⚪ Low' },
                          ]}
                        />
                        <S
                          label="Assigned Staff"
                          value={editData.assigned_staff_id?.toString() || ''}
                          onChange={(v: any) => setEditData(prev => ({ ...prev, assigned_staff_id: v ? parseInt(v) : null }))}
                          options={[
                            { value: '', label: '— Unassigned —' },
                            ...staff.map(s => ({ value: s.id.toString(), label: `${s.first_name || ''} ${s.last_name || ''}`.trim() || s.username }))
                          ]}
                        />
                      </div>
                      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: '12px' }}>
                        <I
                          label="Issues Count"
                          type="number"
                          value={editData.issues_count.toString()}
                          onChange={(v: string) => setEditData(prev => ({ ...prev, issues_count: parseInt(v) || 0 }))}
                          placeholder="0"
                        />
                        <I
                          label="Checkout Date"
                          type="date"
                          value={editData.checkout_date}
                          onChange={(v: string) => setEditData(prev => ({ ...prev, checkout_date: v }))}
                        />
                        <I
                          label="Checkout Time"
                          type="time"
                          value={editData.checkout_time}
                          onChange={(v: string) => setEditData(prev => ({ ...prev, checkout_time: v }))}
                        />
                      </div>
                      <label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
                        <input
                          type="checkbox"
                          checked={editData.is_vip}
                          onChange={(e) => setEditData(prev => ({ ...prev, is_vip: e.target.checked }))}
                          style={{ width: 18, height: 18 }}
                        />
                        <span style={{ fontWeight: 500 }}>⭐ VIP Guest</span>
                      </label>
                      <TA
                        label="Notes"
                        value={editData.notes}
                        onChange={(v: string) => setEditData(prev => ({ ...prev, notes: v }))}
                        rows={2}
                        placeholder="e.g., Need extra towels, AC broken..."
                      />
                      <div style={{ display: 'flex', gap: '8px' }}>
                        <Btn onClick={updateRoomStatus} size="sm">Save</Btn>
                        <Btn variant="secondary" onClick={() => setEditingRoom(null)} size="sm">Cancel</Btn>
                      </div>
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

function RoomEditor({ room, setRoom, images, onSave, onCancel }: any) {
  const [showPicker, setShowPicker] = useState(false);
  const [roomImages, setRoomImages] = useState<{id: number; data: string; thumbnail: string}[]>([]);
  const [allAmenities, setAllAmenities] = useState<Amenity[]>([]);
  const [selectedAmenities, setSelectedAmenities] = useState<number[]>(room.amenity_ids || []);
  const r = { ...room, photos: roomImages.map(img => img.thumbnail || img.data), amenity_ids: selectedAmenities };

  useEffect(() => {
    fetch('/api/amenities')
      .then(res => res.json())
      .then(d => setAllAmenities(d.data || []))
      .catch(() => {});
    
    // Load existing images for this room from images table
    if (room.id) {
      fetch(`/api/admin/images?room_id=${room.id}`)
        .then(res => res.json())
        .then(d => setRoomImages(d.data || []))
        .catch(() => {});
    }
  }, [room.id]);

  const toggleAmenity = (id: number) => {
    setSelectedAmenities(prev => 
      prev.includes(id) ? prev.filter(a => a !== id) : [...prev, id]
    );
  };

  const addPhotos = async (files: FileList) => {
    const newImages: {id: number; data: string; thumbnail: string}[] = [];
    for (const f of Array.from(files)) {
      const b64 = await readFileBase64(f);
      try {
        const res = await fetch('/api/admin/images', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ filename: f.name, data: b64, category: 'rooms', room_id: r.id || null, location_target: `room-${r.id || 'new'}` }),
        });
        if (res.ok) { 
          const d = await res.json(); 
          newImages.push({ id: d.data.id, data: d.data.data, thumbnail: d.data.thumbnail || d.data.data });
        }
      } catch { /* ignore */ }
    }
    setRoomImages(prev => [...prev, ...newImages]);
  };

  const removeImage = async (imageId: number) => {
    try {
      await fetch(`/api/admin/images?id=${imageId}`, { method: 'DELETE' });
      setRoomImages(prev => prev.filter(img => img.id !== imageId));
    } catch { /* ignore */ }
  };

  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 500, width: '90%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{r.id ? 'Edit Room' : 'New Room'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Name" value={r.name} onChange={(v: string) => setRoom({ ...r, name: v })} />
          <TA label="Description" value={r.description || ''} onChange={(v: string) => setRoom({ ...r, description: v })} />
          <I label="Price" value={r.price} onChange={(v: string) => setRoom({ ...r, price: v })} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Photos</label>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
              <Btn onClick={() => document.getElementById(`room-photos-${r.id || 'new'}`)?.click()} size="sm" variant="secondary">+ Add Photos</Btn>
              <input id={`room-photos-${r.id || 'new'}`} type="file" accept="image/*" multiple style={{ display: 'none' }}
                onChange={e => { addPhotos(e.target.files!); e.target.value = ''; }} />
            </div>
            <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
              {roomImages.map((img, i) => (
                <div key={img.id || i} style={{ position: 'relative' }}>
                  <img src={img.thumbnail || img.data} alt="" style={{ width: 64, height: 48, objectFit: 'cover', borderRadius: 6, border: '1px solid #eee' }} />
                  <button onClick={() => removeImage(img.id)}
                    style={{ position: 'absolute', top: -4, right: -4, width: 18, height: 18, borderRadius: '50%', background: C.danger, color: '#fff', border: 'none', cursor: 'pointer', fontSize: '11px', lineHeight: 18, padding: 0 }}>×</button>
                </div>
              ))}
            </div>
          </div>
          <Tgl label="Active" checked={r.active} onChange={(v: boolean) => setRoom({ ...r, active: v })} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Amenities</label>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px' }}>
              {allAmenities.map(a => (
                <button key={a.id} onClick={() => toggleAmenity(a.id)}
                  style={{ 
                    display: 'flex', alignItems: 'center', gap: '4px', 
                    padding: '6px 10px', borderRadius: 6, border: `1px solid ${selectedAmenities.includes(a.id) ? C.gold : C.border}`,
                    background: selectedAmenities.includes(a.id) ? C.goldLight : '#fff',
                    cursor: 'pointer', fontSize: '12px', transition: 'all 150ms',
                    color: selectedAmenities.includes(a.id) ? C.gold : C.text
                  }}>
                  <span style={{ width: 16, height: 16, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }} dangerouslySetInnerHTML={{ __html: a.icon_svg.replace(/width="[^"]*"/g, '').replace(/height="[^"]*"/g, '').replace(/stroke="currentColor"/g, `stroke="${C.navy}"`).replace(/<svg/, '<svg style="width:100%;height:100%"') }} />
                  {a.name}
                </button>
              ))}
            </div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(r)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Amenities Section ─── */
function AmenitiesSection({ onToast }: { onToast: (msg: string, type: string) => void }) {
  const [amenities, setAmenities] = useState<Amenity[]>([]);
  const [editing, setEditing] = useState<Amenity | null>(null);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  useEffect(() => {
    fetch('/api/amenities')
      .then(r => r.json())
      .then(d => setAmenities(d.data || []))
      .catch(() => onToast('Failed to load amenities', 'error'));
  }, []);

  const save = async (amenity: Amenity) => {
    try {
      const url = amenity.id ? `/api/amenities?id=${amenity.id}` : '/api/amenities';
      const res = await fetch(url, {
        method: amenity.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(amenity),
      });
      if (res.ok) {
        const data = await res.json();
        if (amenity.id) {
          setAmenities(prev => prev.map(a => a.id === amenity.id ? data.data : a));
        } else {
          setAmenities(prev => [...prev, data.data]);
        }
        setEditing(null);
        onToast('Amenity saved!', 'success');
      } else {
        const err = await res.json();
        onToast(err.error || 'Failed to save', 'error');
      }
    } catch { onToast('Error', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/amenities?id=${id}`, { method: 'DELETE' });
    setAmenities(prev => prev.filter(a => a.id !== id));
    onToast('Amenity deleted', 'success');
    setConfirmDel(null);
  };

  return (
    <div>
      <SecHead title="✨ Room Amenities" count={amenities.length}
        action={<Btn onClick={() => setEditing({ id: 0, name: '', icon_svg: '', sort_order: amenities.length })} size="sm">+ New Amenity</Btn>} />
      {amenities.length === 0 ? <Empty icon="✨" title="No amenities" subtitle="Add icons for room features like Wi-Fi, TV, etc." /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))', gap: '12px' }}>
          {amenities.sort((a, b) => a.sort_order - b.sort_order).map((a: Amenity) => (
            <div key={a.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', boxShadow: C.shadow, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '10px' }}>
              <div style={{ width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center', color: C.navy }}
                dangerouslySetInnerHTML={{ __html: a.icon_svg
                  .replace(/width="[^"]*"/g, '')
                  .replace(/height="[^"]*"/g, '')
                  .replace(/stroke="currentColor"/g, `stroke="${C.navy}"`)
                  .replace(/<svg/, '<svg style="width:100%;height:100%"') }} />
              <div style={{ fontWeight: 600, color: C.navy, textAlign: 'center' }}>{a.name}</div>
              <div style={{ display: 'flex', gap: '8px' }}>
                <Btn size="sm" variant="secondary" onClick={() => setEditing(a)}>Edit</Btn>
                <Btn size="sm" variant="danger" onClick={() => setConfirmDel(a.id)}>Del</Btn>
              </div>
            </div>
          ))}
        </div>
      )}
      {editing && <AmenityEditor amenity={editing} setAmenity={setEditing} onSave={save} onCancel={() => setEditing(null)} />}
      {confirmDel !== null && <Confirm message="Delete this amenity?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

function AmenityEditor({ amenity, setAmenity, onSave, onCancel }: any) {
  const defaultIcons = [
    { name: 'Wi-Fi', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M1.42 9a16 16 0 0 1 21.16 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/></svg>' },
    { name: 'TV', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="7" width="20" height="15" rx="2" ry="2"/><polyline points="17 2 12 7 7 2"/></svg>' },
    { name: 'Shower', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4v5a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5V4"/><path d="M4 9h4"/><path d="M6 9v12"/><path d="M10 4h10a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2H10"/><circle cx="6" cy="14" r="1"/><circle cx="6" cy="18" r="1"/><circle cx="10" cy="14" r="1"/><circle cx="10" cy="18" r="1"/></svg>' },
    { name: 'Bathtub', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12h16a1 1 0 0 1 1 1v3a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4v-3a1 1 0 0 1 1-1z"/><path d="M6 12V5a2 2 0 0 1 2-2h3v2.25"/><circle cx="12" cy="5" r=".5"/></svg>' },
    { name: 'Fireplace', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.14-4.052 1.5-5 .5 2 2 4 2 6a2.5 2.5 0 0 0 5 0c0-1.38-.5-2-1-3-.5-1-1-2-1-3.5 1.5 1 3 2.5 3 5a4 4 0 1 1-8 0"/><path d="M4 19h16a2 2 0 0 0 2-2v-2H2v2a2 2 0 0 0 2 2z"/></svg>' },
    { name: 'Minibar', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3h18v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3z"/><path d="M5 9v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9"/><line x1="10" y1="13" x2="14" y2="13"/></svg>' },
    { name: 'Coffee', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 8h1a4 4 0 1 1 0 8h-1"/><path d="M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z"/><line x1="6" y1="2" x2="6" y2="4"/><line x1="10" y1="2" x2="10" y2="4"/><line x1="14" y1="2" x2="14" y2="4"/></svg>' },
    { name: 'Safe', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><circle cx="12" cy="16" r="1"/></svg>' },
    { name: 'Heating', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z"/></svg>' },
    { name: 'Balcony', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><line x1="3" y1="17" x2="21" y2="17"/><line x1="7" y1="11" x2="7" y2="21"/><line x1="12" y1="11" x2="12" y2="21"/><line x1="17" y1="11" x2="17" y2="21"/></svg>' },
    { name: 'King Bed', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 18v-4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4"/><path d="M2 14v-2a2 2 0 0 1 2-2h1"/><path d="M22 14v-2a2 2 0 0 0-2-2h-1"/><path d="M5 4h14a2 2 0 0 1 2 2v2H3V6a2 2 0 0 1 2-2z"/><rect x="3" y="10" width="18" height="4" rx="1"/></svg>' },
    { name: 'Mountain View', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m8 3 4 8 5-5 5 15H2L8 3z"/></svg>' },
    { name: 'Parking', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><path d="M9 17V7h4a3 3 0 0 1 0 6H9"/></svg>' },
    { name: 'Restaurant', svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2"/><path d="M7 2v20"/><path d="M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7"/></svg>' },
  ];

  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 600, width: '90%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{amenity.id ? 'Edit Amenity' : 'New Amenity'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Name" value={amenity.name} onChange={(v: string) => setAmenity({ ...amenity, name: v })} placeholder="e.g., Wi-Fi, TV, Shower" />
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Icon (SVG)</label>
            <textarea value={amenity.icon_svg} onChange={e => setAmenity({ ...amenity, icon_svg: e.target.value })}
              rows={4} placeholder="<svg>...</svg>"
              style={{ padding: '8px 12px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: '13px', fontFamily: 'monospace', outline: 'none', background: '#FAFAFA', resize: 'vertical' }} />
            {amenity.icon_svg && (
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 64, height: 64, background: C.bg, borderRadius: 8, marginTop: '8px' }}
                dangerouslySetInnerHTML={{ __html: amenity.icon_svg.replace(/width="[^"]*"/g, '').replace(/height="[^"]*"/g, '').replace(/stroke="currentColor"/g, `stroke="${C.navy}"`).replace(/<svg/, '<svg style="width:100%;height:100%"') }} />
            )}
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Quick Icons</label>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px' }}>
              {defaultIcons.map(icon => (
                <button key={icon.name} onClick={() => setAmenity({ ...amenity, name: icon.name, icon_svg: icon.svg })}
                  style={{ padding: '6px 10px', borderRadius: 6, border: `1px solid ${C.border}`, background: '#fff', cursor: 'pointer', fontSize: '12px', display: 'flex', alignItems: 'center', gap: '4px', transition: 'all 150ms' }}
                  onMouseEnter={e => { e.currentTarget.style.borderColor = C.gold; e.currentTarget.style.background = C.goldLight; }}
                  onMouseLeave={e => { e.currentTarget.style.borderColor = C.border; e.currentTarget.style.background = '#fff'; }}>
                  <span style={{ width: 18, height: 18, display: 'flex', alignItems: 'center', justifyContent: 'center' }} dangerouslySetInnerHTML={{ __html: icon.svg.replace(/width="[^"]*"/g, '').replace(/height="[^"]*"/g, '').replace(/stroke="currentColor"/g, `stroke="${C.navy}"`).replace(/<svg/, '<svg style="width:100%;height:100%"') }} />
                  {icon.name}
                </button>
              ))}
            </div>
          </div>
          <I label="Sort Order" type="number" value={amenity.sort_order} onChange={(v: string) => setAmenity({ ...amenity, sort_order: parseInt(v) || 0 })} />
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(amenity)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Trips Section ─── */
type Trip = { id: number; user_id: number; username: string; room_id: number | null; room_name: string | null; check_in: string; check_out: string; notes: string | null; status: string };

function TripsSection({ onToast }: { onToast: (msg: string, type: string) => void }) {
  const [trips, setTrips] = useState<Trip[]>([]);
  const [users, setUsers] = useState<{id: number; username: string}[]>([]);
  const [rooms, setRooms] = useState<{id: number; name: string}[]>([]);
  const [editing, setEditing] = useState<Trip | null>(null);
  const [creating, setCreating] = useState(false);

  useEffect(() => {
    const load = async () => {
      const [tripsRes, usersRes, roomsRes] = await Promise.all([
        fetch('/api/admin/trips'),
        fetch('/api/admin/users'),
        fetch('/api/rooms'),
      ]);
      if (tripsRes.ok) { const d = await tripsRes.json(); setTrips(d.trips || []); }
      if (usersRes.ok) { const d = await usersRes.json(); setUsers(d.users || []); }
      if (roomsRes.ok) { const d = await roomsRes.json(); setRooms(Array.isArray(d) ? d : (d.data || [])); }
    };
    load();
  }, []);

  const save = async (trip: Trip) => {
    try {
      const method = trip.id ? 'PUT' : 'POST';
      const res = await fetch('/api/admin/trips', {
        method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(trip),
      });
      if (res.ok) {
        const d = await res.json();
        if (trip.id) {
          setTrips(prev => prev.map(t => t.id === trip.id ? d.trip : t));
        } else {
          setTrips(prev => [...prev, d.trip]);
        }
        setEditing(null);
        setCreating(false);
        onToast('Trip saved', 'success');
      } else {
        const err = await res.json();
        onToast(err.error || 'Failed to save trip', 'error');
      }
    } catch { onToast('Error saving trip', 'error'); }
  };

  const del = async (id: number) => {
    if (!confirm('Delete this trip?')) return;
    try {
      await fetch('/api/admin/trips', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id }) });
      setTrips(prev => prev.filter(t => t.id !== id));
      onToast('Trip deleted', 'success');
    } catch { onToast('Error deleting trip', 'error'); }
  };

  const emptyTrip: Trip = { id: 0, user_id: 0, username: '', room_id: null, room_name: null, check_in: '', check_out: '', notes: '', status: 'confirmed' };

  return (
    <div>
      <SecHead title="✈️ Trips" count={trips.length} onAdd={() => { setCreating(true); setEditing(emptyTrip); }} />
      {creating && editing && !editing.id && (
        <div style={{ background: '#fff', borderRadius: 12, padding: '20px', marginBottom: '20px', boxShadow: C.shadow }}>
          <h3 style={{ margin: '0 0 16px', fontSize: '16px' }}>New Trip</h3>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '12px' }}>
            <S label="User" value={editing.user_id} onChange={(v: string) => setEditing({ ...editing, user_id: Number(v) })} options={[{ value: 0, label: 'Select user' }, ...users.map(u => ({ value: u.id, label: u.username }))]} />
            <S label="Room" value={editing.room_id || ''} onChange={(v: string) => setEditing({ ...editing, room_id: v ? Number(v) : null })} options={[{ value: '', label: 'No room' }, ...rooms.map(r => ({ value: r.id, label: r.name }))]} />
            <I label="Check-in" type="date" value={editing.check_in} onChange={(v: string) => setEditing({ ...editing, check_in: v })} />
            <I label="Check-out" type="date" value={editing.check_out} onChange={(v: string) => setEditing({ ...editing, check_out: v })} />
            <S label="Status" value={editing.status} onChange={(v: string) => setEditing({ ...editing, status: v })} options={['pending', 'confirmed', 'checked_in', 'checked_out', 'cancelled'].map(s => ({ value: s, label: s.replace('_', ' ') }))} />
          </div>
          <TA label="Notes" value={editing.notes || ''} onChange={(v: string) => setEditing({ ...editing, notes: v })} rows={2} />
          <div style={{ display: 'flex', gap: '8px', marginTop: '16px' }}>
            <Btn onClick={() => save(editing)}>Save Trip</Btn>
            <Btn variant="secondary" onClick={() => { setCreating(false); setEditing(null); }}>Cancel</Btn>
          </div>
        </div>
      )}
      <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
        {trips.map(t => (
          <div key={t.id} style={{ background: '#fff', borderRadius: 12, padding: '16px', boxShadow: C.shadow, display: 'flex', alignItems: 'center', gap: '16px', flexWrap: 'wrap' }}>
            <div style={{ flex: '1 1 200px' }}>
              <div style={{ fontWeight: 600, color: C.navy }}>{t.username || `User ${t.user_id}`}</div>
              <div style={{ fontSize: '13px', color: C.textLight }}>{t.room_name || 'No room assigned'}</div>
            </div>
            <div style={{ fontSize: '13px', color: C.text }}>
              <strong>In:</strong> {formatDisplayDate(t.check_in)} · <strong>Out:</strong> {formatDisplayDate(t.check_out)}
            </div>
            <Badge color={t.status === 'confirmed' ? C.success : t.status === 'checked_in' ? '#1976d2' : t.status === 'cancelled' ? C.danger : '#666'}>{t.status.replace('_', ' ')}</Badge>
            <div style={{ display: 'flex', gap: '8px' }}>
              <Btn size="sm" onClick={() => { setCreating(false); setEditing(t); }}>Edit</Btn>
              <Btn size="sm" variant="danger" onClick={() => del(t.id)}>Delete</Btn>
            </div>
          </div>
        ))}
      </div>
      {!creating && editing && editing.id && (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000 }} onClick={() => setEditing(null)}>
          <div style={{ background: '#fff', borderRadius: 12, padding: '24px', maxWidth: '500px', width: '90%' }} onClick={e => e.stopPropagation()}>
            <h3 style={{ margin: '0 0 16px' }}>Edit Trip</h3>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
              <S label="User" value={editing.user_id} onChange={(v: string) => setEditing({ ...editing, user_id: Number(v) })} options={[{ value: 0, label: 'Select user' }, ...users.map(u => ({ value: u.id, label: u.username }))]} />
              <S label="Room" value={editing.room_id || ''} onChange={(v: string) => setEditing({ ...editing, room_id: v ? Number(v) : null })} options={[{ value: '', label: 'No room' }, ...rooms.map(r => ({ value: r.id, label: r.name }))]} />
              <I label="Check-in" type="date" value={editing.check_in} onChange={(v: string) => setEditing({ ...editing, check_in: v })} />
              <I label="Check-out" type="date" value={editing.check_out} onChange={(v: string) => setEditing({ ...editing, check_out: v })} />
              <S label="Status" value={editing.status} onChange={(v: string) => setEditing({ ...editing, status: v })} options={['pending', 'confirmed', 'checked_in', 'checked_out', 'cancelled'].map(s => ({ value: s, label: s.replace('_', ' ') }))} />
            </div>
            <TA label="Notes" value={editing.notes || ''} onChange={(v: string) => setEditing({ ...editing, notes: v })} rows={2} />
            <div style={{ display: 'flex', gap: '8px', marginTop: '16px' }}>
              <Btn onClick={() => save(editing)}>Save</Btn>
              <Btn variant="secondary" onClick={() => setEditing(null)}>Cancel</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* ─── Messages Section ─── */
type MsgThread = { user_id: number; username: string; message: string; created_at: string };
type Msg = { id: number; sender_role: string; message: string; created_at: string };

function MessagesSection({ onToast }: { onToast: (msg: string, type: string) => void }) {
  const [threads, setThreads] = useState<MsgThread[]>([]);
  const [selectedUser, setSelectedUser] = useState<number | null>(null);
  const [messages, setMessages] = useState<Msg[]>([]);
  const [reply, setReply] = useState('');
  const messagesEndRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const load = async () => {
      const res = await fetch('/api/admin/messages');
      if (res.ok) { const d = await res.json(); setThreads(d.threads || []); }
    };
    load();
  }, []);

  useEffect(() => {
    if (selectedUser) {
      const load = async () => {
        const res = await fetch(`/api/admin/messages?user_id=${selectedUser}`);
        if (res.ok) { const d = await res.json(); setMessages(d.messages || []); }
      };
      load();
    }
  }, [selectedUser]);

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const sendReply = async () => {
    if (!reply.trim() || !selectedUser) return;
    try {
      const res = await fetch('/api/admin/messages', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ user_id: selectedUser, message: reply.trim() }),
      });
      if (res.ok) {
        const d = await res.json();
        setMessages(prev => [...prev, d.message]);
        setReply('');
        onToast('Reply sent', 'success');
      }
    } catch { onToast('Error sending reply', 'error'); }
  };

  return (
    <div style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: '20px', minHeight: '400px' }}>
      <div style={{ background: '#fff', borderRadius: 12, overflow: 'hidden', boxShadow: C.shadow }}>
        <div style={{ padding: '16px', borderBottom: `1px solid ${C.border}`, fontWeight: 600, color: C.navy }}>Conversations</div>
        <div style={{ maxHeight: '400px', overflowY: 'auto' }}>
          {threads.length === 0 ? (
            <div style={{ padding: '20px', textAlign: 'center', color: C.textLight }}>No conversations yet</div>
          ) : (
            threads.map(t => (
              <div key={t.user_id} onClick={() => setSelectedUser(t.user_id)} style={{ padding: '12px 16px', cursor: 'pointer', background: selectedUser === t.user_id ? C.goldLight : 'transparent', borderBottom: `1px solid ${C.border}` }}
                onMouseEnter={e => { if (selectedUser !== t.user_id) (e.currentTarget.style as any).background = '#f5f5f5'; }}
                onMouseLeave={e => { if (selectedUser !== t.user_id) (e.currentTarget.style as any).background = 'transparent'; }}>
                <div style={{ fontWeight: 500, color: C.navy }}>{t.username}</div>
                <div style={{ fontSize: '12px', color: C.textLight, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{t.message}</div>
              </div>
            ))
          )}
        </div>
      </div>
      <div style={{ background: '#fff', borderRadius: 12, overflow: 'hidden', boxShadow: C.shadow, display: 'flex', flexDirection: 'column' }}>
        {selectedUser ? (
          <>
            <div style={{ padding: '16px', borderBottom: `1px solid ${C.border}`, fontWeight: 600, color: C.navy }}>
              {threads.find(t => t.user_id === selectedUser)?.username || `User ${selectedUser}`}
            </div>
            <div style={{ flex: 1, overflowY: 'auto', padding: '16px', maxHeight: '300px' }}>
              {messages.map(m => (
                <div key={m.id} style={{ display: 'flex', justifyContent: m.sender_role === 'admin' ? 'flex-start' : 'flex-end', marginBottom: '12px' }}>
                  <div style={{ maxWidth: '70%', padding: '10px 14px', borderRadius: 12, background: m.sender_role === 'admin' ? C.gold : '#f0f0f0', color: m.sender_role === 'admin' ? '#fff' : C.navy }}>
                    <div style={{ fontSize: '12px', fontWeight: 500, marginBottom: '4px' }}>{m.sender_role === 'admin' ? 'Staff' : 'Guest'}</div>
                    <div style={{ fontSize: '14px' }}>{m.message}</div>
                    <div style={{ fontSize: '11px', opacity: 0.7, marginTop: '4px' }}>{formatDisplayDateTime(m.created_at)}</div>
                  </div>
                </div>
              ))}
              <div ref={messagesEndRef} />
            </div>
            <div style={{ padding: '12px', borderTop: `1px solid ${C.border}`, display: 'flex', gap: '8px' }}>
              <input value={reply} onChange={e => setReply(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') sendReply(); }} placeholder="Type a reply..." style={{ flex: 1, padding: '10px 14px', borderRadius: 8, border: `1px solid ${C.border}`, fontSize: '14px', outline: 'none' }} />
              <Btn onClick={sendReply} disabled={!reply.trim()}>Send</Btn>
            </div>
          </>
        ) : (
          <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', color: C.textLight }}>Select a conversation to view messages</div>
        )}
      </div>
    </div>
  );
}

/* ─── Menu Section ─── */
function MenuSection({ items, setItems, images, onToast }: any) {
  const [editing, setEditing] = useState<MenuItem | null>(null);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);
  const [dragIdx, setDragIdx] = useState<number | null>(null);
  const [overIdx, setOverIdx] = useState<number | null>(null);

  const save = async (item: MenuItem) => {
    if (!item.category || !item.name || !item.price) {
      onToast('Category, name, and price are required', 'error');
      return;
    }
    try {
      const url = item.id ? `/api/menu/${item.id}` : '/api/menu/';
      const res = await fetch(url, {
        method: item.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(item),
      });
      if (res.ok) {
        const data = await res.json();
        setEditing(null);
        if (item.id) {
          setItems((i: any) => i.map((x: any) => x.id === item.id ? data.data : x));
        } else {
          setItems((i: any) => [...i, data.data]);
        }
        onToast('Menu item saved!', 'success');
      } else {
        const err = await res.json().catch(() => ({}));
        onToast(err.error || 'Failed to save menu item', 'error');
      }
    } catch { onToast('Error', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/menu/${id}`, { method: 'DELETE' });
    setItems((i: any) => i.filter((x: any) => x.id !== id));
    onToast('Item deleted', 'success');
    setConfirmDel(null);
  };

  const toggleVisible = async (item: MenuItem) => {
    const updated = { ...item, active: !item.active };
    try {
      await fetch(`/api/menu/${item.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...item, active: updated.active }),
      });
      setItems((i: any) => i.map((x: any) => x.id === item.id ? updated : x));
    } catch { onToast('Error', 'error'); }
  };

  // ─── Drag-and-drop reordering ───
  const handleDragStart = (idx: number) => { setDragIdx(idx); };

  const handleDragOver = (e: any, idx: number) => {
    e.preventDefault();
    if (dragIdx !== null && dragIdx !== idx) setOverIdx(idx);
  };

  const handleDragEnd = () => {
    if (dragIdx !== null && overIdx !== null && dragIdx !== overIdx) {
      // Use sorted array for correct index mapping
      const reordered = [...sorted];
      const [moved] = reordered.splice(dragIdx, 1);
      reordered.splice(overIdx, 0, moved);
      // Update sort_order based on new position
      const updated = reordered.map((it: MenuItem, i: number) => ({ ...it, sort_order: i }));
      console.log('Drag end:', { dragIdx, overIdx, oldOrder: sorted.map((it: MenuItem) => it.name), newOrder: updated.map((it: MenuItem) => it.name) });
      setItems(updated);
    }
    setDragIdx(null);
    setOverIdx(null);
  };

  const saveOrder = async () => {
    try {
      // Use items state (which has updated sort_order from drag)
      const currentItems = [...items].sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));
      const order = currentItems.map((it: MenuItem, i: number) => ({ id: it.id, sort_order: i }));
      console.log('Saving order:', order);
      const res = await fetch('/api/menu/reorder', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ order }),
      });
      if (res.ok) {
        onToast('Order saved!', 'success');
      } else {
        const err = await res.json().catch(() => ({}));
        console.error('Save order error:', err);
        onToast(err.error || 'Error saving order', 'error');
      }
    } catch (e) { 
      console.error('Save order exception:', e);
      onToast('Error reordering', 'error'); 
    }
  };

  const sorted = [...items].sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));

  return (
    <div>
      <SecHead title="🍽️ Menu" count={items.length}
        action={<Btn onClick={() => setEditing({ id: 0, category: '', name: '', description: '', price: '', is_daily_special: false, active: true, sort_order: items.length, photos: [], featured_photo: null })} size="sm">+ New Item</Btn>} />
      {sorted.length === 0 ? <Empty icon="🍽️" title="No menu items" /> : (
        <div style={{ background: C.card, borderRadius: 16, overflow: 'hidden', boxShadow: C.shadow }}>
          {/* Drag handle instruction */}
          <div style={{ padding: '8px 16px', background: C.goldLight, fontSize: '12px', color: C.textLight, display: 'flex', alignItems: 'center', gap: '8px' }}>
            <span>⠿</span> Drag items to reorder · Toggle visibility to hide from the public site
          </div>

          {sorted.map((item: MenuItem, idx: number) => {
            const isDragging = dragIdx === idx;
            const isOver = overIdx === idx && dragIdx !== idx;
            return (
              <div
                key={item.id}
                draggable
                onDragStart={(e: any) => { e.dataTransfer!.effectAllowed = 'move'; handleDragStart(idx); }}
                onDragOver={(e) => handleDragOver(e, idx)}
                onDragEnd={handleDragEnd}
                onDragEnter={() => setOverIdx(idx)}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: '12px',
                  padding: '12px 16px',
                  border: isOver ? `2px dashed ${C.gold}` : idx === 0 ? 'none' : `1px solid ${C.border}`,
                  borderTop: isDragging ? `2px dashed ${C.gold}` : 'none',
                  background: isDragging ? 'rgba(212,168,83,0.06)' : isOver ? C.goldLight : idx % 2 === 0 ? '#fff' : '#FAFAFA',
                  opacity: isDragging ? 0.5 : 1,
                  cursor: 'grab',
                  transition: 'all 150ms ease',
                  borderRadius: idx === 0 ? '0' : '0',
                }}
                onMouseEnter={(e) => {
                  if (!isDragging) e.currentTarget.style.background = C.goldLight;
                }}
                onMouseLeave={(e) => {
                  if (!isDragging && !isOver) e.currentTarget.style.background = idx % 2 === 0 ? '#fff' : '#FAFAFA';
                }}
              >
                {/* Drag handle */}
                <span style={{ fontSize: '18px', color: C.textLight, userSelect: 'none', flexShrink: 0, cursor: 'grab' }}
                  onMouseDown={() => {}}>⠿</span>

                {/* Position number */}
                <span style={{ fontSize: '13px', fontWeight: 700, color: C.textLight, width: '22px', textAlign: 'center', flexShrink: 0 }}>
                  {idx + 1}
                </span>

                {/* Visible/invisible toggle */}
                <label style={{ display: 'flex', alignItems: 'center', gap: '6px', cursor: 'pointer', flexShrink: 0 }}
                  onClick={(e) => { e.stopPropagation(); toggleVisible(item); }}>
                  <div style={{
                    width: '42px', height: '24px', borderRadius: '12px', position: 'relative',
                    background: item.active ? C.success : '#ccc',
                    transition: 'background 200ms',
                    flexShrink: 0,
                  }}>
                    <div style={{
                      width: '20px', height: '20px', borderRadius: '50%', background: '#fff',
                      position: 'absolute', top: '2px',
                      left: item.active ? '20px' : '2px',
                      transition: 'left 200ms',
                      boxShadow: '0 1px 3px rgba(0,0,0,0.2)',
                    }} />
                  </div>
                  <span style={{ fontSize: '12px', color: item.active ? C.success : C.textLight, fontWeight: 600, minWidth: '24px' }}>
                    {item.active ? 'On' : 'Off'}
                  </span>
                </label>

                {/* Category badge */}
                <span style={{
                  fontSize: '11px', fontWeight: 700, padding: '3px 8px', borderRadius: 6,
                  background: C.navy, color: '#fff', flexShrink: 0,
                }}>{item.category}</span>

                {/* Photo thumbnail */}
                {(item.photos && item.photos.length > 0) && (
                  <div style={{ width: 40, height: 30, borderRadius: 6, overflow: 'hidden', flexShrink: 0, border: `1px solid ${C.border}` }}>
                    <img
                      src={item.featured_photo || item.photos[0]}
                      alt=""
                      style={{ width: '100%', height: '100%', objectFit: 'cover' }}
                    />
                  </div>
                )}

                {/* Name & Description */}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 600, color: C.navy, fontSize: '14px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                    {item.name}
                  </div>
                  {item.description && (
                    <div style={{ fontSize: '12px', color: C.textLight, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {item.description}
                    </div>
                  )}
                </div>

                {/* Price */}
                <span style={{ fontWeight: 700, color: C.warm, fontSize: '14px', flexShrink: 0 }}>
                  {item.price}
                </span>

                {/* Actions */}
                <div style={{ display: 'flex', gap: '6px', flexShrink: 0 }}>
                  <Btn size="sm" variant="secondary" onClick={() => setEditing(item)} style={{ fontSize: '11px', padding: '3px 8px' }}>✏️</Btn>
                  <Btn size="sm" variant="danger" onClick={() => setConfirmDel(item.id)} style={{ fontSize: '11px', padding: '3px 8px' }}>🗑️</Btn>
                </div>
              </div>
            );
          })}

          {/* Save order button */}
          <div style={{ padding: '12px 16px', borderTop: `1px solid ${C.border}`, display: 'flex', justifyContent: 'flex-end' }}>
            <Btn onClick={saveOrder} size="sm">💾 Save Order</Btn>
          </div>
        </div>
      )}
      {editing && <MenuEditor item={editing} setItem={setEditing} onSave={save} onCancel={() => setEditing(null)} />}
      {confirmDel !== null && <Confirm message="Delete this menu item?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

function MenuEditor({ item, setItem, onSave, onCancel }: any) {
  const [localPhotos, setLocalPhotos] = useState<string[]>(item.photos || []);
  const [featuredPhoto, setFeaturedPhoto] = useState<string | null>(item.featured_photo || null);
  const i = { ...item, photos: localPhotos, featured_photo: featuredPhoto };

  const addPhotos = async (files: FileList) => {
    const newPhotos: string[] = [];
    for (const f of Array.from(files)) {
      const b64 = await readFileBase64(f);
      try {
        const res = await fetch('/api/admin/images', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ filename: f.name, data: b64, category: 'menu', room_id: null, location_target: `menu-${i.id || 'new'}` }),
        });
        if (res.ok) { const d = await res.json(); newPhotos.push(d.data.data); }
      } catch { const b = await readFileBase64(f); newPhotos.push(b); }
    }
    setLocalPhotos(prev => [...prev, ...newPhotos]);
  };

  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 500, width: '90%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{i.id ? 'Edit Item' : 'New Item'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Category" value={i.category} onChange={(v: string) => setItem({ ...i, category: v })} />
          <I label="Name" value={i.name} onChange={(v: string) => setItem({ ...i, name: v })} />
          <TA label="Description" value={i.description || ''} onChange={(v: string) => setItem({ ...i, description: v })} />
          <I label="Price" value={i.price} onChange={(v: string) => setItem({ ...i, price: v })} />
          
          {/* Photo upload */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Photos</label>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
              <Btn onClick={() => document.getElementById(`menu-photos-${i.id}`)?.click()} size="sm" variant="secondary">+ Add Photos</Btn>
              <input id={`menu-photos-${i.id}`} type="file" accept="image/*" multiple style={{ display: 'none' }}
                onChange={e => { addPhotos(e.target.files!); e.target.value = ''; }} />
            </div>
            <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
              {localPhotos.map((ph, idx) => (
                <div key={idx} style={{ position: 'relative' }}>
                  <img
                    src={ph}
                    alt=""
                    onClick={() => setFeaturedPhoto(ph)}
                    style={{
                      width: 64, height: 48, objectFit: 'cover', borderRadius: 6, border: featuredPhoto === ph ? `2px solid ${C.gold}` : '1px solid #eee',
                      cursor: 'pointer',
                    }}
                  />
                  <button onClick={() => { setLocalPhotos(prev => prev.filter((_, j) => j !== idx)); if (featuredPhoto === ph) setFeaturedPhoto(null); }}
                    style={{ position: 'absolute', top: -4, right: -4, width: 18, height: 18, borderRadius: '50%', background: C.danger, color: '#fff', border: 'none', cursor: 'pointer', fontSize: '11px', lineHeight: 18, padding: 0 }}>×</button>
                </div>
              ))}
            </div>
            {localPhotos.length > 0 && <div style={{ fontSize: '11px', color: C.textLight }}>Click a photo to set as featured</div>}
          </div>

          <Tgl label="Daily Special" checked={i.is_daily_special} onChange={(v: boolean) => setItem({ ...i, is_daily_special: v })} />
          <Tgl label="Active" checked={i.active} onChange={(v: boolean) => setItem({ ...i, active: v })} />
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(i)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Places Section ─── */
function PlacesSection({ places, setPlaces, images, onToast }: any) {
  const [editing, setEditing] = useState<Place | null>(null);
  const [confirmDel, setConfirmDel] = useState<number | null>(null);

  const save = async (place: Place) => {
    try {
      const url = place.id ? `/api/places/${place.id}` : '/api/places';
      const res = await fetch(url, {
        method: place.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(place),
      });
      if (res.ok) {
        const data = await res.json();
        setEditing(null);
        setPlaces((p: any) => place.id ? p.map((x: Place) => x.id === place.id ? data.data : x) : [...p, data.data]);
        onToast('Place saved!', 'success');
      }
    } catch { onToast('Error', 'error'); }
  };

  const del = async (id: number) => {
    await fetch(`/api/places/${id}`, { method: 'DELETE' });
    setPlaces((p: any) => p.filter((x: Place) => x.id !== id));
    onToast('Place deleted', 'success');
    setConfirmDel(null);
  };

  return (
    <div>
      <SecHead title="🗺️ Landscape Places" count={places.length}
        action={<Btn onClick={() => setEditing({ id: 0, name: '', description: '', photos: [], featured_photo: null, distance_km: '', visit_time: '', suggestion: '', active: true, sort_order: places.length })} size="sm">+ New Place</Btn>} />
      {places.length === 0 ? <Empty icon="🗺️" title="No places" /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px' }}>
          {places.map((p: Place) => (
            <EntityCard key={p.id} title={p.name} desc={p.description || ''} meta={`${p.distance_km || ''} ${p.visit_time ? '• ' + p.visit_time : ''}`}
              thumb={p.featured_photo || p.photos?.[0]}
              photoUrls={p.photos}
              actions={
                <>
                  <Btn size="sm" variant="secondary" onClick={() => setEditing(p)}>Edit</Btn>
                  <Btn size="sm" variant="danger" onClick={() => setConfirmDel(p.id)}>Del</Btn>
                </>
              } />
          ))}
        </div>
      )}
      {editing && <PlaceEditor place={editing} setPlace={setEditing} images={images} onSave={save} onCancel={() => setEditing(null)} />}
      {confirmDel !== null && <Confirm message="Delete this place?" onCancel={() => setConfirmDel(null)} onConfirm={() => del(confirmDel)} />}
    </div>
  );
}

function PlaceEditor({ place, setPlace, images, onSave, onCancel }: any) {
  const [localPhotos, setLocalPhotos] = useState<string[]>(place.photos || []);
  const p = { ...place, photos: localPhotos };

  const addPhotos = async (files: FileList) => {
    const newPhotos: string[] = [];
    for (const f of Array.from(files)) {
      const b64 = await readFileBase64(f);
      try {
        const res = await fetch('/api/admin/images', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ filename: f.name, data: b64, category: 'landscape', room_id: null, location_target: `place-${p.id || 'new'}` }),
        });
        if (res.ok) { const d = await res.json(); newPhotos.push(d.data.data); }
      } catch { const b = await readFileBase64(f); newPhotos.push(b); }
    }
    setLocalPhotos(prev => [...prev, ...newPhotos]);
  };

  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
      <div style={{ background: '#FFFFFF', borderRadius: 16, padding: '24px 28px', maxWidth: 500, width: '90%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 20px', fontSize: '18px', fontWeight: 700, color: C.navy }}>{p.id ? 'Edit Place' : 'New Place'}</h3>
        <div style={{ display: 'grid', gap: '14px' }}>
          <I label="Name" value={p.name} onChange={(v: string) => setPlace({ ...p, name: v })} />
          <TA label="Description" value={p.description || ''} onChange={(v: string) => setPlace({ ...p, description: v })} />
          <I label="Distance (km)" value={p.distance_km} onChange={(v: string) => setPlace({ ...p, distance_km: v })} />
          <I label="Visit Time" value={p.visit_time} onChange={(v: string) => setPlace({ ...p, visit_time: v })} />
          <TA label="Suggestion" value={p.suggestion || ''} onChange={(v: string) => setPlace({ ...p, suggestion: v })} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
            <label style={{ fontSize: '13px', fontWeight: 600, color: C.text }}>Photos</label>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
              <Btn onClick={() => document.getElementById(`place-photos-${p.id}`)?.click()} size="sm" variant="secondary">+ Add Photos</Btn>
              <input id={`place-photos-${p.id}`} type="file" accept="image/*" multiple style={{ display: 'none' }}
                onChange={e => { addPhotos(e.target.files!); e.target.value = ''; }} />
            </div>
            <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap' }}>
              {localPhotos.map((ph, i) => (
                <div key={i} style={{ position: 'relative' }}>
                  <img src={ph} alt="" style={{ width: 64, height: 48, objectFit: 'cover', borderRadius: 6, border: '1px solid #eee' }} />
                  <button onClick={() => setLocalPhotos(prev => prev.filter((_, j) => j !== i))}
                    style={{ position: 'absolute', top: -4, right: -4, width: 18, height: 18, borderRadius: '50%', background: C.danger, color: '#fff', border: 'none', cursor: 'pointer', fontSize: '11px', lineHeight: 18, padding: 0 }}>×</button>
                </div>
              ))}
            </div>
          </div>
          <Tgl label="Active" checked={p.active} onChange={(v: boolean) => setPlace({ ...p, active: v })} />
        </div>
        <div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '24px' }}>
          <Btn onClick={onCancel} variant="secondary">Cancel</Btn>
          <Btn onClick={() => onSave(p)}>Save</Btn>
        </div>
      </div>
    </div>
  );
}

/* ─── Reviews Section ─── */
function ReviewsSection({ reviews, setReviews, onToast }: any) {
  const approve = async (id: number) => {
    try {
      await fetch(`/api/reviews/${id}`, {
        method: 'PUT', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ approved: true }),
      });
      setReviews((r: any) => r.map((x: Review) => x.id === id ? { ...x, approved: true } : x));
      onToast('Review approved!', 'success');
    } catch { onToast('Error', 'error'); }
  };

  const reject = async (id: number) => {
    try {
      await fetch(`/api/reviews/${id}`, {
        method: 'PUT', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ approved: false }),
      });
      setReviews((r: any) => r.map((x: Review) => x.id === id ? { ...x, approved: false } : x));
      onToast('Review hidden', 'success');
    } catch { onToast('Error', 'error'); }
  };

  return (
    <div>
      <SecHead title="⭐ Reviews" count={reviews.length} />
      {reviews.length === 0 ? <Empty icon="⭐" title="No reviews" /> : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', gap: '16px' }}>
          {reviews.map((r: Review) => (
            <div key={r.id} style={{ background: C.card, borderRadius: 16, padding: '16px 20px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
                <span style={{ fontWeight: 700, color: C.navy }}>{r.author_name}</span>
                <Badge color={r.approved ? C.success : '#FF9800'}>{r.approved ? 'Approved' : 'Pending'}</Badge>
              </div>
              <div style={{ fontSize: '14px', color: '#FFB400', marginBottom: '8px', letterSpacing: 2 }}>
                {'★'.repeat(r.rating)}{'☆'.repeat(5 - r.rating)}
              </div>
              <p style={{ margin: '0 0 12px', fontSize: '13px', color: C.text, lineHeight: 1.5 }}>{r.text}</p>
              <div style={{ display: 'flex', gap: '8px' }}>
                {!r.approved && <Btn size="sm" variant="secondary" onClick={() => approve(r.id)}>Approve</Btn>}
                {r.approved && <Btn size="sm" variant="secondary" onClick={() => reject(r.id)}>Hide</Btn>}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

/* ─── Brand Section ─── */
function BrandSection({ images, onToast }: { images: Image[]; onToast: (m: string, t: string) => void }) {
  const [config, setConfig] = useState<FooterConfig>({
    logo: '', favicon: '', tagline: 'Tu refugio en la naturaleza',
    facebook_url: '', instagram_url: '', whatsapp_url: '',
    address: '', phone: '', email: '',
  });
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    loadConfig();
  }, []);

  const loadConfig = async () => {
    try {
      const res = await fetch('/api/site-assets');
      if (res.ok) {
        const data = await res.json();
        if (data.data) {
          setConfig(prev => ({ ...prev, ...data.data }));
        }
      }
    } catch (err) {
      console.error('Failed to load config:', err);
    } finally {
      setLoading(false);
    }
  };

  const handleUpload = async (key: keyof FooterConfig) => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = 'image/*';
    input.onchange = async (e) => {
      const file = (e.target as HTMLInputElement).files?.[0];
      if (!file) return;
      const b64 = await readFileBase64(file);
      try {
        const res = await fetch('/api/admin/images', {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ filename: file.name, data: b64, category: 'other', room_id: null, location_target: key }),
        });
        if (res.ok) {
          const d = await res.json();
          setConfig(prev => ({ ...prev, [key]: d.data.data }));
          onToast('Image uploaded!', 'success');
        }
      } catch { onToast('Upload failed', 'error'); }
    };
    input.click();
  };

  const saveConfig = async () => {
    setSaving(true);
    try {
      const res = await fetch('/api/site-assets', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ values: config }),
      });
      if (res.ok) {
        onToast('Configuration saved!', 'success');
      } else {
        onToast('Failed to save', 'error');
      }
    } catch {
      onToast('Failed to save', 'error');
    } finally {
      setSaving(false);
    }
  };

  if (loading) return <div style={{ padding: 20, color: C.textLight }}>Loading...</div>;

  return (
    <div>
      <SecHead title="🎨 Brand & Identity" />
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))', gap: '20px' }}>
        {(['logo', 'favicon'] as (keyof FooterConfig)[]).map(key => (
          <div key={key} style={{ background: C.card, borderRadius: 16, padding: '20px', boxShadow: C.shadow, textAlign: 'center', border: `1px solid ${C.border}` }}>
            <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '12px', textTransform: 'capitalize' }}>{key}</div>
            {config[key] ? (
              <img src={config[key] as string} alt={key} style={{ width: 120, height: 80, objectFit: 'contain', borderRadius: 8, marginBottom: '12px' }} />
            ) : (
              <div style={{ width: 120, height: 80, background: '#EEE', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#BBB', margin: '0 auto 12px' }}>
                No {key}
              </div>
            )}
            <Btn onClick={() => handleUpload(key)} size="sm" variant="secondary">Upload</Btn>
          </div>
        ))}
        <div style={{ background: C.card, borderRadius: 16, padding: '20px', boxShadow: C.shadow, border: `1px solid ${C.border}`, gridColumn: 'span 2' }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '12px' }}>Tagline</div>
          <I value={config.tagline} onChange={(v: string) => setConfig(prev => ({ ...prev, tagline: v }))} placeholder="Your hotel tagline" />
        </div>
      </div>

      <SecHead title="📞 Contact & Social" />
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '16px', marginBottom: 20 }}>
        <div style={{ background: C.card, borderRadius: 16, padding: '16px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '8px' }}>📍 Address</div>
          <I value={config.address} onChange={(v: string) => setConfig(prev => ({ ...prev, address: v }))} placeholder="Full address" />
        </div>
        <div style={{ background: C.card, borderRadius: 16, padding: '16px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '8px' }}>📞 Phone</div>
          <I value={config.phone} onChange={(v: string) => setConfig(prev => ({ ...prev, phone: v }))} placeholder="+593 99 999 9999" />
        </div>
        <div style={{ background: C.card, borderRadius: 16, padding: '16px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '8px' }}>✉️ Email</div>
          <I value={config.email} onChange={(v: string) => setConfig(prev => ({ ...prev, email: v }))} placeholder="contact@lahuasca.com" />
        </div>
        <div style={{ background: C.card, borderRadius: 16, padding: '16px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '8px' }}>📘 Facebook URL</div>
          <I value={config.facebook_url} onChange={(v: string) => setConfig(prev => ({ ...prev, facebook_url: v }))} placeholder="https://facebook.com/..." />
        </div>
        <div style={{ background: C.card, borderRadius: 16, padding: '16px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '8px' }}>📷 Instagram URL</div>
          <I value={config.instagram_url} onChange={(v: string) => setConfig(prev => ({ ...prev, instagram_url: v }))} placeholder="https://instagram.com/..." />
        </div>
        <div style={{ background: C.card, borderRadius: 16, padding: '16px', boxShadow: C.shadow, border: `1px solid ${C.border}` }}>
          <div style={{ fontSize: '13px', fontWeight: 600, color: C.text, marginBottom: '8px' }}>💬 WhatsApp URL</div>
          <I value={config.whatsapp_url} onChange={(v: string) => setConfig(prev => ({ ...prev, whatsapp_url: v }))} placeholder="https://wa.me/..." />
        </div>
      </div>

      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '16px' }}>
        <Btn onClick={saveConfig} disabled={saving}>{saving ? 'Saving...' : '💾 Save Configuration'}</Btn>
      </div>
    </div>
  );
}

/* ─── Dashboard (stats cards) ─── */
function Dashboard({ rooms, slides, events, reviews, places }: any) {
  return (
    <div>
      <h2 style={{ margin: '0 0 20px', fontSize: '22px', fontWeight: 700, color: C.navy }}>Dashboard</h2>
      <div style={{ display: 'flex', gap: '14px', flexWrap: 'wrap', marginBottom: '24px' }}>
        <StatCard icon="🏨" value={rooms?.length || 0} label="Rooms" />
        <StatCard icon="🎞️" value={slides?.length || 0} label="Slides" />
        <StatCard icon="📅" value={events?.length || 0} label="Events" />
        <StatCard icon="🗺️" value={places?.length || 0} label="Places" />
        <StatCard icon="⭐" value={reviews?.filter((r: Review) => r.approved)?.length || 0} label="Approved Reviews" />
      </div>
    </div>
  );
}

/* ─── Users Section ─── */
function UsersSection({ onToast }: { onToast: (msg: string, type: string) => void }) {
  const [users, setUsers] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<any | null>(null);
  const [newUser, setNewUser] = useState({ username: '', password: '', role: 'user', first_name: '', last_name: '', email: '', phone: '', country: '', preferred_language: 'es' });
  const [showAdd, setShowAdd] = useState(false);

  useEffect(() => {
    loadUsers();
  }, []);

  const loadUsers = async () => {
    try {
      const res = await fetch('/api/admin/users');
      if (res.ok) {
        const data = await res.json();
        setUsers(data.data || []);
      }
    } catch (err) {
      console.error('Failed to load users:', err);
    } finally {
      setLoading(false);
    }
  };

  const createUser = async () => {
    if (!newUser.username || !newUser.password) {
      onToast('Username and password required', 'error');
      return;
    }
    try {
      const res = await fetch('/api/admin/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(newUser),
      });
      if (res.ok) {
        onToast('User created!', 'success');
        setNewUser({ username: '', password: '', role: 'user', first_name: '', last_name: '', email: '', phone: '', country: '', preferred_language: 'es' });
        setShowAdd(false);
        loadUsers();
      } else {
        const err = await res.json();
        onToast(err.error || 'Failed to create user', 'error');
      }
    } catch {
      onToast('Error creating user', 'error');
    }
  };

  const updateUser = async (user: any) => {
    try {
      const res = await fetch('/api/admin/users', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(user),
      });
      if (res.ok) {
        onToast('User updated!', 'success');
        setEditing(null);
        loadUsers();
      } else {
        const err = await res.json();
        onToast(err.error || 'Failed to update user', 'error');
      }
    } catch {
      onToast('Error updating user', 'error');
    }
  };

  const deleteUser = async (id: number) => {
    if (!confirm('Delete this user?')) return;
    try {
      const res = await fetch(`/api/admin/users?id=${id}`, { method: 'DELETE' });
      if (res.ok) {
        onToast('User deleted', 'success');
        loadUsers();
      }
    } catch {
      onToast('Error deleting user', 'error');
    }
  };

  if (loading) {
    return <div style={{ textAlign: 'center', padding: '40px' }}>Loading...</div>;
  }

  return (
    <div>
      <SecHead title="👥 Users" count={users.length} action={<Btn onClick={() => setShowAdd(!showAdd)} size="sm">+ Add User</Btn>} />
      {showAdd && (
        <div style={{ background: C.card, borderRadius: 12, padding: 16, marginBottom: 16 }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 12 }}>
            <I label="Username" value={newUser.username} onChange={(v: string) => setNewUser({ ...newUser, username: v })} />
            <I label="Password" type="password" value={newUser.password} onChange={(v: string) => setNewUser({ ...newUser, password: v })} />
            <S label="Role" value={newUser.role} onChange={(v: string) => setNewUser({ ...newUser, role: v })} options={[{ value: 'user', label: 'User' }, { value: 'admin', label: 'Admin' }]} />
            <I label="First Name" value={newUser.first_name} onChange={(v: string) => setNewUser({ ...newUser, first_name: v })} />
            <I label="Last Name" value={newUser.last_name} onChange={(v: string) => setNewUser({ ...newUser, last_name: v })} />
            <I label="Email" type="email" value={newUser.email} onChange={(v: string) => setNewUser({ ...newUser, email: v })} />
            <I label="Phone" value={newUser.phone} onChange={(v: string) => setNewUser({ ...newUser, phone: v })} />
            <I label="Country" value={newUser.country} onChange={(v: string) => setNewUser({ ...newUser, country: v })} />
            <S label="Language" value={newUser.preferred_language} onChange={(v: string) => setNewUser({ ...newUser, preferred_language: v })} options={[{ value: 'es', label: '🇪🇨 Español' }, { value: 'en', label: '🇬🇧 English' }]} />
          </div>
          <div style={{ marginTop: 12, display: 'flex', gap: 8 }}>
            <Btn onClick={createUser} size="sm">Create User</Btn>
            <Btn variant="secondary" onClick={() => setShowAdd(false)} size="sm">Cancel</Btn>
          </div>
        </div>
      )}
      <div style={{ display: 'grid', gap: '12px' }}>
        {users.map((u: any) => (
          <div key={u.id} style={{ background: C.card, borderRadius: 12, padding: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div style={{ fontWeight: 600, color: C.text }}>
                {u.username} <span style={{ fontSize: 12, background: u.role === 'admin' ? '#dc2626' : '#059669', color: '#fff', padding: '2px 8px', borderRadius: 4, marginLeft: 8 }}>{u.role}</span>
                {u.preferred_language && <span style={{ fontSize: 11, background: '#6366f1', color: '#fff', padding: '2px 6px', borderRadius: 4, marginLeft: 8 }}>{u.preferred_language === 'es' ? '🇪🇨 ES' : '🇬🇧 EN'}</span>}
              </div>
              <div style={{ fontSize: 12, color: C.textLight }}>
                {u.first_name || ''} {u.last_name || ''} {u.email ? `• ${u.email}` : ''} {u.country ? `• ${u.country}` : ''}
                {u.terms_accepted_at ? `• Terms: ${formatDisplayDate(u.terms_accepted_at)}` : '• Terms not accepted'}
                {u.comments_disabled ? '• Comments disabled' : ''}
              </div>
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <Btn size="sm" variant="secondary" onClick={() => setEditing(u)}>Edit</Btn>
              {u.role !== 'admin' && <Btn size="sm" variant="danger" onClick={() => deleteUser(u.id)}>Delete</Btn>}
            </div>
          </div>
        ))}
      </div>
      {editing && (
        <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
          <div style={{ background: '#fff', borderRadius: 16, padding: 24, maxWidth: 500, width: '90%', maxHeight: '90vh', overflow: 'auto' }}>
            <h3 style={{ margin: '0 0 20px', fontSize: 18, fontWeight: 700 }}>Edit User</h3>
            <div style={{ display: 'grid', gap: 12 }}>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <I label="First Name" value={editing.first_name || ''} onChange={(v: string) => setEditing({ ...editing, first_name: v })} />
                <I label="Last Name" value={editing.last_name || ''} onChange={(v: string) => setEditing({ ...editing, last_name: v })} />
              </div>
              <I label="Email" type="email" value={editing.email || ''} onChange={(v: string) => setEditing({ ...editing, email: v })} />
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <I label="Phone" value={editing.phone || ''} onChange={(v: string) => setEditing({ ...editing, phone: v })} />
                <I label="Country" value={editing.country || ''} onChange={(v: string) => setEditing({ ...editing, country: v })} />
              </div>
              <S label="Language" value={editing.preferred_language || 'es'} onChange={(v: string) => setEditing({ ...editing, preferred_language: v })} options={[{ value: 'es', label: '🇪🇨 Español' }, { value: 'en', label: '🇬🇧 English' }]} />
              <I label="New Password (leave blank to keep)" type="password" value={editing.password || ''} onChange={(v: string) => setEditing({ ...editing, password: v })} />
              <Tgl label="Disable comments" checked={editing.comments_disabled || false} onChange={(v: boolean) => setEditing({ ...editing, comments_disabled: v })} />
              {editing.terms_accepted_at && (
                <div style={{ fontSize: 12, color: C.textLight }}>
                  Terms accepted: {formatDisplayDateTime(editing.terms_accepted_at)}
                </div>
              )}
            </div>
            <div style={{ marginTop: 16, display: 'flex', gap: 8 }}>
              <Btn onClick={() => updateUser(editing)} size="sm">Save</Btn>
              <Btn variant="secondary" onClick={() => setEditing(null)} size="sm">Cancel</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* ─── Terms Section ─── */
function TermsSection({ onToast }: { onToast: (msg: string, type: string) => void }) {
  const [terms, setTerms] = useState<{ es: any; en: any }>({ es: null, en: null });
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<any | null>(null);

  useEffect(() => {
    loadTerms();
  }, []);

  const loadTerms = async () => {
    try {
      const [esRes, enRes] = await Promise.all([
        fetch('/api/terms?language=es'),
        fetch('/api/terms?language=en'),
      ]);
      const esData = await esRes.json();
      const enData = await enRes.json();
      setTerms({
        es: esData.data || null,
        en: enData.data || null,
      });
    } catch (err) {
      console.error('Failed to load terms:', err);
    } finally {
      setLoading(false);
    }
  };

  const saveTerm = async (term: any) => {
    try {
      const res = await fetch('/api/admin/terms', {
        method: term.id ? 'PUT' : 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(term),
      });
      if (res.ok) {
        onToast('Terms saved!', 'success');
        setEditing(null);
        loadTerms();
      } else {
        const err = await res.json();
        onToast(err.error || 'Failed to save terms', 'error');
      }
    } catch {
      onToast('Error saving terms', 'error');
    }
  };

  if (loading) {
    return <div style={{ textAlign: 'center', padding: '40px' }}>Loading...</div>;
  }

  return (
    <div>
      <SecHead title="📜 Terms of Service" count={0} />
      <p style={{ fontSize: 13, color: C.textLight, marginBottom: 16 }}>
        Manage terms of service and disclaimers shown to users. One version per language.
      </p>

      <div style={{ display: 'grid', gap: 16 }}>
        {/* Spanish Terms */}
        <div style={{ background: C.card, borderRadius: 12, padding: 16 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
            <h3 style={{ margin: 0, fontSize: 16 }}>🇪🇨 Español</h3>
            {terms.es && (
              <span style={{ fontSize: 12, color: C.textLight }}>
                Version: {terms.es.version}
              </span>
            )}
          </div>
          {terms.es ? (
            <div>
              <div style={{ fontWeight: 600, marginBottom: 8 }}>{terms.es.title}</div>
              <div style={{ fontSize: 13, color: C.textLight, maxHeight: 120, overflow: 'auto', whiteSpace: 'pre-wrap' }}>
                {terms.es.content?.substring(0, 300)}...
              </div>
              <Btn size="sm" variant="secondary" onClick={() => setEditing({ ...terms.es })} style={{ marginTop: 12 }}>Edit</Btn>
            </div>
          ) : (
            <Btn size="sm" onClick={() => setEditing({ language: 'es', title: '', content: '', version: '1.0' })}>Create Spanish Terms</Btn>
          )}
        </div>

        {/* English Terms */}
        <div style={{ background: C.card, borderRadius: 12, padding: 16 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
            <h3 style={{ margin: 0, fontSize: 16 }}>🇬🇧 English</h3>
            {terms.en && (
              <span style={{ fontSize: 12, color: C.textLight }}>
                Version: {terms.en.version}
              </span>
            )}
          </div>
          {terms.en ? (
            <div>
              <div style={{ fontWeight: 600, marginBottom: 8 }}>{terms.en.title}</div>
              <div style={{ fontSize: 13, color: C.textLight, maxHeight: 120, overflow: 'auto', whiteSpace: 'pre-wrap' }}>
                {terms.en.content?.substring(0, 300)}...
              </div>
              <Btn size="sm" variant="secondary" onClick={() => setEditing({ ...terms.en })} style={{ marginTop: 12 }}>Edit</Btn>
            </div>
          ) : (
            <Btn size="sm" onClick={() => setEditing({ language: 'en', title: '', content: '', version: '1.0' })}>Create English Terms</Btn>
          )}
        </div>
      </div>

      {/* Edit Modal */}
      {editing && (
        <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9998 }}>
          <div style={{ background: '#fff', borderRadius: 16, padding: 24, maxWidth: 600, width: '90%', maxHeight: '90vh', overflow: 'auto' }}>
            <h3 style={{ margin: '0 0 20px', fontSize: 18, fontWeight: 700 }}>
              {editing.language === 'es' ? '🇪🇨 ' : '🇬🇧 '}Edit Terms ({editing.language.toUpperCase()})
            </h3>
            <div style={{ display: 'grid', gap: 12 }}>
              <I label="Title" value={editing.title || ''} onChange={(v: string) => setEditing({ ...editing, title: v })} placeholder="Terms of Service and Privacy Policy" />
              <TA label="Content" value={editing.content || ''} onChange={(v: string) => setEditing({ ...editing, content: v })} rows={10} placeholder="Enter the full terms of service text..." />
              <I label="Version" value={editing.version || '1.0'} onChange={(v: string) => setEditing({ ...editing, version: v })} />
            </div>
            <div style={{ marginTop: 16, display: 'flex', gap: 8 }}>
              <Btn onClick={() => saveTerm(editing)} size="sm">Save</Btn>
              <Btn variant="secondary" onClick={() => setEditing(null)} size="sm">Cancel</Btn>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* ─── Weather Section ─── */
function WeatherSection({ onToast }: { onToast: (msg: string, type: string) => void }) {
  const [enabled, setEnabled] = useState(true);
  const [cities, setCities] = useState<{ name: string; lat: string; lon: string }[]>([]);
  const [newCity, setNewCity] = useState({ name: '', lat: '', lon: '' });
  const [loading, setLoading] = useState(true);

  // Load weather config
  useEffect(() => {
    const loadConfig = async () => {
      try {
        const res = await fetch('/api/site-assets?key=weather_config');
        if (res.ok) {
          const data = await res.json();
          if (data.data) {
            const config = JSON.parse(data.data);
            setEnabled(config.enabled ?? true);
            setCities(config.cities ?? []);
          }
        }
      } catch (err) {
        console.error('Failed to load weather config:', err);
      } finally {
        setLoading(false);
      }
    };
    loadConfig();
  }, []);

  const saveConfig = async () => {
    try {
      const config = { enabled, cities };
      const res = await fetch('/api/site-assets', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ key: 'weather_config', value: JSON.stringify(config) }),
      });
      
      if (res.ok) {
        onToast('Weather settings saved', 'success');
      } else {
        throw new Error('Failed to save');
      }
    } catch (err) {
      onToast('Error saving weather settings', 'error');
    }
  };

  const addCity = () => {
    if (newCity.name && newCity.lat && newCity.lon) {
      setCities([...cities, newCity]);
      setNewCity({ name: '', lat: '', lon: '' });
    }
  };

  const removeCity = (index: number) => {
    setCities(cities.filter((_, i) => i !== index));
  };

  if (loading) {
    return (
      <div>
        <SecHead title="🌤️ Weather Widget" />
        <div style={{ textAlign: 'center', padding: '40px', color: C.textLight }}>
          Loading...
        </div>
      </div>
    );
  }

  return (
    <div>
      <SecHead title="🌤️ Weather Widget" />
      <div style={{ background: C.card, borderRadius: 12, padding: '24px', marginBottom: '24px', border: `1px solid ${C.border}` }}>
        <p style={{ color: C.text, marginBottom: '24px' }}>
          Configure the weather widget displayed on the homepage
        </p>
        
        <div style={{ marginBottom: '24px' }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
            <input 
              type="checkbox" 
              checked={enabled} 
              onChange={(e) => setEnabled(e.target.checked)}
              style={{ width: '18px', height: '18px' }}
            />
            <span style={{ fontWeight: 500, color: C.text }}>Enable Weather Widget</span>
          </label>
        </div>
        
        <h3 style={{ margin: '0 0 16px', color: C.text, fontSize: '16px' }}>Cities</h3>
        <div style={{ marginBottom: '16px' }}>
          {cities.map((city, index) => (
            <div key={index} style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '8px', padding: '8px', background: C.bg, borderRadius: '8px' }}>
              <span style={{ flex: 1, color: C.text }}>{city.name} ({city.lat}, {city.lon})</span>
              <button 
                onClick={() => removeCity(index)}
                style={{ 
                  background: C.danger, 
                  color: 'white', 
                  border: 'none', 
                  borderRadius: '4px', 
                  padding: '4px 8px', 
                  cursor: 'pointer',
                  fontSize: '12px'
                }}
              >
                Remove
              </button>
            </div>
          ))}
        </div>
        
        <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', padding: '16px', background: C.bg, borderRadius: '8px' }}>
          <h4 style={{ margin: '0 0 8px', color: C.text, fontSize: '14px' }}>Add City</h4>
          <I label="City Name" value={newCity.name} onChange={(v: string) => setNewCity({...newCity, name: v})} />
          <div style={{ display: 'flex', gap: '12px' }}>
            <I label="Latitude" value={newCity.lat} onChange={(v: string) => setNewCity({...newCity, lat: v})} />
            <I label="Longitude" value={newCity.lon} onChange={(v: string) => setNewCity({...newCity, lon: v})} />
          </div>
          <button 
            onClick={addCity}
            style={{ 
              alignSelf: 'flex-start',
              background: C.gold, 
              color: 'white', 
              border: 'none', 
              borderRadius: '6px', 
              padding: '8px 16px', 
              cursor: 'pointer',
              fontWeight: 500
            }}
          >
            Add City
          </button>
        </div>
        
        <div style={{ marginTop: '24px' }}>
          <button 
            onClick={saveConfig}
            style={{ 
              background: C.gold, 
              color: 'white', 
              border: 'none', 
              borderRadius: '6px', 
              padding: '12px 24px', 
              cursor: 'pointer',
              fontWeight: 600,
              fontSize: '14px'
            }}
          >
            Save Settings
          </button>
        </div>
      </div>
    </div>
  );
}

/* ═══════════════════════════════════════════════════
   MAIN PAGE
   ═══════════════════════════════════════════════════ */
export default function AdminPage() {
  const [activeSection, setActiveSection] = useState('dashboard');
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [toasts, setToasts] = useState<{ id: number; message: string; type: string }[]>([]);
  const [authChecked, setAuthChecked] = useState(false);
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  const [slides, setSlides] = useState<Slide[]>([]);
  const [rooms, setRooms] = useState<Room[]>([]);
  const [events, setEvents] = useState<CalendarEvent[]>([]);
  const [socialEvents, setSocialEvents] = useState<SocialEvent[]>([]);
  const [menuItems, setMenuItems] = useState<MenuItem[]>([]);
  const [places, setPlaces] = useState<Place[]>([]);
  const [reviews, setReviews] = useState<Review[]>([]);
  const [images, setImages] = useState<Image[]>([]);

  const [imageFilter, setImageFilter] = useState('all');
  const [galleryLoading, setGalleryLoading] = useState(false);

  const toastId = useRef(0);
  const showToast = useCallback((message: string, type: string) => {
    const id = ++toastId.current;
    setToasts(prev => [...prev, { id, message, type }]);
  }, []);

  const removeToast = useCallback((id: number) => {
    setToasts(prev => prev.filter(t => t.id !== id));
  }, []);

  /* ── Auth check ── */
  useEffect(() => {
    fetch('/api/auth/me', { credentials: 'include' })
      .then(r => r.json())
      .then(data => {
        if (data.authenticated) setIsAuthenticated(true);
        setAuthChecked(true);
      })
      .catch(() => setAuthChecked(true));
  }, []);

  /* ── Data fetching ── */
  const loadImages = async () => {
    try {
      const res = await fetch('/api/admin/images');
      if (res.ok) { const d = await res.json(); setImages(Array.isArray(d) ? d : (d.images || [])); }
    } catch (err) { console.error('Failed to load images:', err); }
  };

  useEffect(() => {
    if (!isAuthenticated) return;
    const fetchAll = async () => {
      try {
        const [slidesRes, roomsRes, calRes, socialRes, menuRes, placesRes, reviewsRes, imagesRes] = await Promise.all([
          fetch('/api/slides'),
          fetch('/api/rooms'),
          fetch('/api/calendar_events'),
          fetch('/api/social_events?includePrivate=true'),
          fetch('/api/admin/menu'),
          fetch('/api/places'),
          fetch('/api/reviews'),
          fetch('/api/admin/images').catch(() => null),
        ]);
        if (slidesRes.ok) { const d = await slidesRes.json(); setSlides(Array.isArray(d) ? d : (d.data || [])); }
        if (roomsRes.ok) { const d = await roomsRes.json(); setRooms(Array.isArray(d) ? d : (d.data || [])); }
        if (calRes.ok) { const d = await calRes.json(); setEvents(Array.isArray(d) ? d : (d.data || [])); }
        if (socialRes.ok) { const d = await socialRes.json(); setSocialEvents(Array.isArray(d) ? d : (d.data || [])); }
        if (menuRes.ok) { const d = await menuRes.json(); setMenuItems(Array.isArray(d) ? d : (d.data || [])); }
        if (placesRes.ok) { const d = await placesRes.json(); setPlaces(Array.isArray(d) ? d : (d.data || [])); }
        if (reviewsRes.ok) { const d = await reviewsRes.json(); setReviews(Array.isArray(d) ? d : (d.data || [])); }
        if (imagesRes?.ok) { const d = await imagesRes.json(); setImages(Array.isArray(d) ? d : (d.data || d.images || [])); }
      } catch (err) { console.error('Failed to load admin data:', err); }
    };
    fetchAll();
  }, [isAuthenticated]);

  const deleteImage = async (id: number) => {
    try {
      await fetch(`/api/admin/images/${id}`, { method: 'DELETE' });
      setImages(prev => prev.filter(img => img.id !== id));
      showToast('Image deleted', 'success');
    } catch { showToast('Error deleting image', 'error'); }
  };

  const renderSection = () => {
    switch (activeSection) {
      case 'dashboard': return <Dashboard rooms={rooms} slides={slides} events={events} reviews={reviews} places={places} />;
      case 'brand': return <BrandSection images={images} onToast={showToast} />;
      case 'gallery': return (
        <div>
          <SecHead title="🖼️ Image Gallery" count={images.length} />
          <WebPMigration onToast={showToast} onRefresh={loadImages} />
          <ImageGallery images={images} onDelete={deleteImage} />
        </div>
      );
      case 'slides': return <SlidesSection slides={slides} setSlides={setSlides} images={images} onToast={showToast} onRefreshImages={loadImages} />;
      case 'calendar': return <CalendarSection events={events} setEvents={setEvents} images={images} onToast={showToast} />;
      case 'social': return <SocialSection events={socialEvents} setEvents={setSocialEvents} images={images} onToast={showToast} />;
      case 'rooms': return <RoomsSection rooms={rooms} setRooms={setRooms} images={images} onToast={showToast} />;
      case 'room-status': return <RoomStatusSection onToast={showToast} />;
      case 'room-reservations': return <RoomReservationsSection onToast={showToast} />;
      case 'restaurant-reservations': return <RestaurantReservationsSection onToast={showToast} />;
      case 'orders': return <OrdersSection onToast={showToast} />;
      case 'kitchen': return <KitchenSection onToast={showToast} />;
      case 'room-assignments': return <RoomAssignmentsSection onToast={showToast} />;
      case 'amenities': return <AmenitiesSection onToast={showToast} />;
      case 'menu': return <MenuSection items={menuItems} setItems={setMenuItems} images={images} onToast={showToast} />;
      case 'places': return <PlacesSection places={places} setPlaces={setPlaces} images={images} onToast={showToast} />;
      case 'reviews': return <ReviewsSection reviews={reviews} setReviews={setReviews} onToast={showToast} />;
      case 'users': return <UsersSection onToast={showToast} />;
      case 'terms': return <TermsSection onToast={showToast} />;
      case 'weather': return <WeatherSection onToast={showToast} />;
      case 'trips': return <TripsSection onToast={showToast} />;
      case 'messages': return <MessagesSection onToast={showToast} />;
      default: return <Dashboard rooms={rooms} slides={slides} events={events} reviews={reviews} places={places} />;
    }
  };

  return (
    <div style={{ minHeight: '100vh', background: C.bg, display: 'flex' }}>
      {/* Toasts */}
      {toasts.map(t => <Toast key={t.id} message={t.message} type={t.type} onClose={() => removeToast(t.id)} />)}

      {/* Auth loading */}
      {!authChecked && (
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ textAlign: 'center' }}>
            <div style={{ fontSize: '32px', marginBottom: '16px' }}>⏳</div>
            <div style={{ fontSize: '16px', color: C.text }}>Checking authentication...</div>
          </div>
        </div>
      )}

      {/* Not authenticated - show login prompt */}
      {authChecked && !isAuthenticated && (
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <div style={{ textAlign: 'center', maxWidth: 400, padding: '40px', background: '#fff', borderRadius: 16, boxShadow: C.shadow }}>
            <div style={{ fontSize: '48px', marginBottom: '16px' }}>🔒</div>
            <h2 style={{ margin: '0 0 12px', fontSize: '24px', color: C.navy }}>Admin Access Required</h2>
            <p style={{ margin: '0 0 24px', fontSize: '14px', color: C.textLight }}>
              Please log in to access the admin panel.
            </p>
            <a href="/login" style={{ display: 'inline-block', padding: '12px 32px', background: C.gold, color: '#fff', borderRadius: 8, textDecoration: 'none', fontWeight: 600, fontSize: '15px' }}>
              Go to Login
            </a>
          </div>
        </div>
      )}

      {/* Authenticated - show admin panel */}
      {authChecked && isAuthenticated && (
        <>
          {/* Mobile sidebar toggle */}
          <div style={{ display: 'none' }} /> {/* placeholder */}

          {/* Sidebar */}
          <aside style={{
            width: 260, background: C.navy, height: '100vh', position: 'sticky', top: 0, overflowY: 'auto',
            display: 'flex', flexDirection: 'column', transition: 'transform 300ms',
            borderRight: '1px solid rgba(255,255,255,0.06)',
          }}>
            <div style={{ padding: '24px 20px', borderBottom: '1px solid rgba(255,255,255,0.06)' }}>
              <h1 style={{ margin: 0, fontSize: '18px', fontWeight: 700, color: C.gold }}>
                🏨 Hosteria La Huasca
              </h1>
              <p style={{ margin: '4px 0 0', fontSize: '11px', color: 'rgba(255,255,255,0.4)' }}>Admin Portal</p>
            </div>
            <nav style={{ padding: '16px 12px', flex: 1 }}>
              {NAV.map(n => (
                <button key={n.id} onClick={() => { setActiveSection(n.id); setSidebarOpen(false); }}
                  style={{ width: '100%', display: 'flex', alignItems: 'center', gap: '12px', padding: '10px 14px', marginBottom: '4px',
                    borderRadius: 10, border: 'none', cursor: 'pointer', fontSize: '14px', fontWeight: 500,
                    background: activeSection === n.id ? C.goldLight : 'transparent',
                    color: activeSection === n.id ? C.gold : 'rgba(255,255,255,0.6)',
                    transition: 'all 200ms', textAlign: 'left' }}
                  onMouseEnter={e => { if (activeSection !== n.id) { e.currentTarget.style.background = 'rgba(255,255,255,0.06)'; e.currentTarget.style.color = '#fff'; } }}
                  onMouseLeave={e => { if (activeSection !== n.id) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'rgba(255,255,255,0.6)'; } }}>
                  <span style={{ fontSize: '18px' }}>{n.icon}</span>
                  {n.label}
                </button>
              ))}
            </nav>
            <div style={{ padding: '16px 20px', borderTop: '1px solid rgba(255,255,255,0.06)', fontSize: '11px', color: 'rgba(255,255,255,0.3)' }}>
              v1.0.0
            </div>
          </aside>

          {/* Main content */}
          <main style={{ flex: 1, padding: '32px 40px', overflowY: 'auto', maxHeight: '100vh' }}>
            <div style={{ maxWidth: 1200, margin: '0 auto' }}>
              {renderSection()}
            </div>
          </main>
        </>
      )}
    </div>
  );
}
