// Modals: New booking, Booking detail, Confirmation toast/preview

const Backdrop = ({ onClose, children, width = 560 }) => (
  <div onClick={onClose} style={{
    position: 'fixed', inset: 0, background: 'rgba(20,18,14,0.4)',
    display: 'flex', alignItems: 'center', justifyContent: 'center',
    zIndex: 1000, padding: 20,
    animation: 'fadeIn 160ms ease-out',
  }}>
    <div onClick={e => e.stopPropagation()} style={{
      background: '#fff', borderRadius: 14, width: '100%', maxWidth: width,
      maxHeight: '90vh', overflow: 'auto',
      boxShadow: '0 20px 60px rgba(0,0,0,0.25)',
      animation: 'slideUp 200ms ease-out',
    }}>
      {children}
    </div>
  </div>
);

const Field = ({ label, children, required }) => (
  <label style={{ display: 'block', marginBottom: 14 }}>
    <div style={{ fontSize: 12, fontWeight: 600, color: '#4a4a44', marginBottom: 6, letterSpacing: '0.01em' }}>
      {label}{required && <span style={{ color: '#C25555' }}> *</span>}
    </div>
    {children}
  </label>
);

const inputStyle = {
  width: '100%', padding: '10px 12px',
  border: '1px solid #DDD9CE', borderRadius: 8,
  fontSize: 14, fontFamily: 'inherit',
  background: '#FBFAF6', outline: 'none',
  transition: 'border-color 120ms, background 120ms',
  boxSizing: 'border-box',
};

const TextInput = (props) => (
  <input {...props} style={{
    ...inputStyle,
    ...(props.style || {}),
  }} onFocus={e => e.target.style.borderColor = '#7B8A6B'}
     onBlur={e => e.target.style.borderColor = '#DDD9CE'} />
);

const PrimaryBtn = ({ children, onClick, disabled, ...rest }) => (
  <button onClick={onClick} disabled={disabled} {...rest} style={{
    background: disabled ? '#C5C0B0' : '#3F4A3A',
    color: '#fff', border: 'none', borderRadius: 8,
    padding: '10px 18px', fontSize: 14, fontWeight: 600,
    cursor: disabled ? 'not-allowed' : 'pointer',
    fontFamily: 'inherit',
    transition: 'background 120ms',
  }}>{children}</button>
);

const SecondaryBtn = ({ children, onClick, danger, ...rest }) => (
  <button onClick={onClick} {...rest} style={{
    background: 'transparent',
    color: danger ? '#A03838' : '#3F4A3A',
    border: `1px solid ${danger ? '#E0BFBF' : '#DDD9CE'}`,
    borderRadius: 8, padding: '10px 18px', fontSize: 14, fontWeight: 500,
    cursor: 'pointer', fontFamily: 'inherit',
  }}>{children}</button>
);

// Smart time picker showing only slots where the booking fits without conflict
const SmartTimePicker = ({ value, slots, onChange }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    if (open) document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  const current = slots.find(s => s.time === value);
  const isCurrentBlocked = current && !current.available;

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button onClick={() => setOpen(o => !o)} style={{
        ...inputStyle,
        textAlign: 'left',
        cursor: 'pointer',
        background: isCurrentBlocked ? '#FBEEEE' : '#FBFAF6',
        borderColor: isCurrentBlocked ? '#E0BFBF' : '#DDD9CE',
        color: isCurrentBlocked ? '#A03838' : '#1a1a1a',
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
      }}>
        <span>{fmtTime(value)}{isCurrentBlocked ? ' · optaget' : ''}</span>
        <span style={{ color: '#888', fontSize: 11 }}>▾</span>
      </button>
      {open && (
        <div style={{
          position: 'absolute', top: '100%', left: 0, right: 0, marginTop: 4,
          background: '#fff', border: '1px solid #DDD9CE', borderRadius: 8,
          boxShadow: '0 8px 24px rgba(0,0,0,0.12)', zIndex: 10,
          maxHeight: 280, overflow: 'auto', padding: 6,
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 4,
        }}>
          {slots.map(slot => {
            const active = slot.time === value;
            return (
              <button key={slot.time}
                disabled={!slot.available}
                onClick={() => { if (slot.available) { onChange(slot.time); setOpen(false); } }}
                style={{
                  background: active ? '#3F4A3A' : (slot.available ? '#fff' : '#F4F2EA'),
                  color: active ? '#fff' : (slot.available ? '#1a1a1a' : '#bbb'),
                  border: `1px solid ${active ? '#3F4A3A' : '#EFEDE5'}`,
                  borderRadius: 5,
                  padding: '6px 4px',
                  fontSize: 12, fontWeight: active ? 600 : 500,
                  cursor: slot.available ? 'pointer' : 'not-allowed',
                  fontFamily: 'inherit',
                  textDecoration: slot.available ? 'none' : 'line-through',
                  textDecorationColor: '#ccc',
                }}>
                {fmtTime(slot.time)}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
};

// ---------- New booking modal ----------
const NewBookingModal = ({ open, initial, onClose, onCreate, staff, bookings = [] }) => {
  const [customerSearch, setCustomerSearch] = React.useState('');
  const [selectedCustomer, setSelectedCustomer] = React.useState(null);
  const [isNewCustomer, setIsNewCustomer] = React.useState(false);
  const [name, setName] = React.useState('');
  const [phone, setPhone] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [serviceIds, setServiceIds] = React.useState(['herreklip']);
  const [staffId, setStaffId] = React.useState(initial?.staffId || staff[0]?.id);
  const [start, setStart] = React.useState(initial?.start || 9*60);
  const [note, setNote] = React.useState('');
  const [showResults, setShowResults] = React.useState(false);

  React.useEffect(() => {
    if (open) {
      setCustomerSearch(''); setSelectedCustomer(null); setIsNewCustomer(false);
      setName(''); setPhone(''); setEmail(''); setNote('');
      setServiceIds(['herreklip']);
      setStaffId(initial?.staffId || staff[0]?.id);
      setStart(initial?.start ?? 9*60);
    }
  }, [open, initial]);

  // Compute available start times for selected staff + selected services.
  // MUST run on every render (before any early return) — rules of hooks.
  const availableSlots = React.useMemo(() => {
    const slots = [];
    if (!serviceIds.length) return slots;
    for (let t = 8 * 60; t <= 19 * 60; t += 15) {
      const ok = !hasConflict(staffId, t, serviceIds, bookings);
      slots.push({ time: t, available: ok });
    }
    return slots;
  }, [staffId, serviceIds, bookings, open]);

  if (!open) return null;

  const isCurrentSlotConflict = serviceIds.length > 0 &&
    hasConflict(staffId, start, serviceIds, bookings);

  const matches = customerSearch.length >= 1 && !selectedCustomer
    ? CUSTOMERS.filter(c => c.name.toLowerCase().includes(customerSearch.toLowerCase())
                         || c.phone.includes(customerSearch)).slice(0, 5)
    : [];

  const pickCustomer = (c) => {
    setSelectedCustomer(c);
    setCustomerSearch(c.name);
    setName(c.name); setPhone(c.phone); setEmail(c.email);
    setShowResults(false);
    setIsNewCustomer(false);
    // Auto-select customer's favorite stylist if they have one
    if (c.favoriteStaffId && staff.some(s => s.id === c.favoriteStaffId)) {
      setStaffId(c.favoriteStaffId);
    }
  };

  const canSubmit = serviceIds.length > 0 && !isCurrentSlotConflict && (selectedCustomer || (isNewCustomer && name));

  const submit = () => {
    if (!canSubmit) return;
    const customer = selectedCustomer || {
      id: 'cn' + Date.now(), name, phone, email, visits: 0, lastService: serviceIds[0],
    };
    if (!selectedCustomer) CUSTOMERS.push(customer);
    onCreate({
      id: 'b' + Date.now(),
      staffId, start, serviceIds: [...serviceIds],
      customerId: customer.id,
      note,
    }, customer);
  };

  const previewBooking = { start, serviceIds };
  const segs = getBookingSegments(previewBooking);
  const totalEnd = start + getBookingDuration(previewBooking);
  const totalPrice = serviceIds.reduce((s, id) => s + (SERVICE_BY_ID[id]?.price || 0), 0);
  const activeMinutes = segs.filter(s => s.kind === 'work').reduce((sum, s) => sum + (s.end - s.start), 0);

  const toggleService = (id) => {
    setServiceIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
  };
  const removeServiceAt = (i) => setServiceIds(prev => prev.filter((_, idx) => idx !== i));
  const moveService = (i, dir) => {
    setServiceIds(prev => {
      const next = [...prev];
      const j = i + dir;
      if (j < 0 || j >= next.length) return prev;
      [next[i], next[j]] = [next[j], next[i]];
      return next;
    });
  };

  return (
    <Backdrop onClose={onClose} width={620}>
      <div style={{ padding: '24px 28px', borderBottom: '1px solid #EFEDE5', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <div>
          <div style={{ fontSize: 11, color: '#888', fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase' }}>Ny booking</div>
          <div style={{ fontSize: 22, fontWeight: 600, color: '#1a1a1a', marginTop: 4 }}>Opret aftale</div>
        </div>
        <button onClick={onClose} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: '#888', padding: 6 }}>
          <IconX size={22} />
        </button>
      </div>

      <div style={{ padding: '20px 28px' }}>
        {/* Customer search */}
        <Field label="Kunde" required>
          <div style={{ position: 'relative' }}>
            <div style={{ position: 'absolute', left: 12, top: 12, color: '#999', pointerEvents: 'none' }}>
              <IconSearch size={16} />
            </div>
            <TextInput
              placeholder="Søg på navn eller telefon…"
              value={customerSearch}
              onChange={e => {
                setCustomerSearch(e.target.value);
                setSelectedCustomer(null);
                setShowResults(true);
              }}
              onFocus={() => setShowResults(true)}
              style={{ paddingLeft: 36 }}
            />
            {showResults && matches.length > 0 && (
              <div style={{
                position: 'absolute', top: '100%', left: 0, right: 0, marginTop: 4,
                background: '#fff', border: '1px solid #DDD9CE', borderRadius: 8,
                boxShadow: '0 8px 24px rgba(0,0,0,0.12)', zIndex: 10,
                maxHeight: 240, overflow: 'auto',
              }}>
                {matches.map(c => (
                  <div key={c.id} onClick={() => pickCustomer(c)} style={{
                    padding: '10px 14px', cursor: 'pointer',
                    borderBottom: '1px solid #F4F2EA',
                    display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                  }} onMouseEnter={e => e.currentTarget.style.background = '#FBFAF6'}
                     onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <div>
                      <div style={{ fontSize: 14, fontWeight: 500, color: '#1a1a1a' }}>{c.name}</div>
                      <div style={{ fontSize: 12, color: '#777' }}>{c.phone}</div>
                    </div>
                    <div style={{ fontSize: 11, color: '#888' }}>{c.visits} besøg</div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </Field>

        <label style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 14, fontSize: 13, color: '#4a4a44', cursor: 'pointer' }}>
          <input type="checkbox" checked={isNewCustomer} onChange={e => {
            setIsNewCustomer(e.target.checked);
            if (e.target.checked) { setSelectedCustomer(null); setCustomerSearch(''); }
          }} />
          Opret som ny kunde
        </label>

        {isNewCustomer && (
          <div style={{ background: '#FBFAF6', borderRadius: 10, padding: 16, marginBottom: 14, border: '1px solid #EEEBE0' }}>
            <div style={{ fontSize: 11, color: '#888', marginBottom: 10, fontStyle: 'italic' }}>Telefon og email er valgfri — men kræves for at sende SMS/email-bekræftelse.</div>
            <Field label="Navn" required>
              <TextInput value={name} onChange={e => setName(e.target.value)} placeholder="Fornavn Efternavn" />
            </Field>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <Field label="Telefon">
                <TextInput value={phone} onChange={e => setPhone(e.target.value)} placeholder="+45 ..." />
              </Field>
              <Field label="Email">
                <TextInput value={email} onChange={e => setEmail(e.target.value)} placeholder="navn@email.dk" />
              </Field>
            </div>
          </div>
        )}

        <Field label={`Services ${serviceIds.length > 1 ? `(${serviceIds.length} valgt — udføres i rækkefølge)` : ''}`}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
            {SERVICES.map(s => {
              const colors = SERVICE_COLORS.pastel[s.color];
              const active = serviceIds.includes(s.id);
              return (
                <button key={s.id} onClick={() => toggleService(s.id)} style={{
                  background: active ? colors.bg : '#fff',
                  border: `1.5px solid ${active ? colors.border : '#E5E2D5'}`,
                  borderRadius: 8, padding: '10px 12px', cursor: 'pointer',
                  textAlign: 'left', fontFamily: 'inherit', position: 'relative',
                  transition: 'all 120ms',
                }}>
                  {active && (
                    <div style={{ position: 'absolute', top: 6, right: 6, width: 16, height: 16, borderRadius: '50%', background: colors.border, color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                      <IconCheck size={10} stroke="#fff" />
                    </div>
                  )}
                  <div style={{ fontSize: 13, fontWeight: 600, color: active ? colors.text : '#1a1a1a' }}>{s.name}</div>
                  <div style={{ fontSize: 11, color: active ? colors.text : '#888', marginTop: 2, opacity: 0.85 }}>
                    {s.duration} min{s.pauseAfter ? ` + ${s.pauseAfter}m mellemrum` : ''} · {s.price} kr
                  </div>
                </button>
              );
            })}
          </div>

          {serviceIds.length > 0 && (
            <div style={{ marginTop: 12, padding: 12, background: '#FBFAF6', border: '1px solid #EFEDE5', borderRadius: 8 }}>
              <div style={{ fontSize: 11, fontWeight: 600, color: '#666', marginBottom: 8, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Forløb</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                {segs.map((seg, i) => {
                  if (seg.kind === 'gap') {
                    return (
                      <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 12, color: '#888', fontStyle: 'italic', paddingLeft: 26 }}>
                        <span style={{ width: 80 }}>{fmtTime(seg.start)}–{fmtTime(seg.end)}</span>
                        <span>↓ Mellemrum · {seg.end - seg.start} min (frisøren er fri — kan booke andre kunder ind)</span>
                      </div>
                    );
                  }
                  const c = SERVICE_COLORS.pastel[seg.color];
                  const idx = serviceIds.indexOf(seg.serviceId);
                  return (
                    <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
                      <div style={{ width: 18, height: 18, borderRadius: 4, background: c.bg, border: `1.5px solid ${c.border}`, flexShrink: 0 }} />
                      <span style={{ width: 80, color: '#666', fontSize: 12, fontWeight: 500 }}>{fmtTime(seg.start)}–{fmtTime(seg.end)}</span>
                      <span style={{ flex: 1, fontWeight: 500 }}>{seg.name}</span>
                      <button onClick={() => moveService(idx, -1)} disabled={idx === 0} style={{ background: 'transparent', border: 'none', cursor: idx === 0 ? 'default' : 'pointer', color: idx === 0 ? '#ccc' : '#888', padding: 2, fontSize: 12 }}>↑</button>
                      <button onClick={() => moveService(idx, 1)} disabled={idx === serviceIds.length - 1} style={{ background: 'transparent', border: 'none', cursor: idx === serviceIds.length - 1 ? 'default' : 'pointer', color: idx === serviceIds.length - 1 ? '#ccc' : '#888', padding: 2, fontSize: 12 }}>↓</button>
                      <button onClick={() => removeServiceAt(idx)} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: '#A03838', padding: 2 }}><IconX size={12} /></button>
                    </div>
                  );
                })}
              </div>
              <div style={{ marginTop: 10, paddingTop: 10, borderTop: '1px dashed #E5E2D5', display: 'flex', justifyContent: 'space-between', fontSize: 12, color: '#666' }}>
                <span>Aktiv tid: <strong style={{ color: '#1a1a1a' }}>{activeMinutes} min</strong> · Total: <strong style={{ color: '#1a1a1a' }}>{totalEnd - start} min</strong></span>
                <span>I alt: <strong style={{ color: '#1a1a1a' }}>{totalPrice} kr</strong></span>
              </div>
            </div>
          )}
        </Field>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
          <Field label="Medarbejder">
            <select value={staffId} onChange={e => setStaffId(e.target.value)} style={inputStyle}>
              {staff.map(s => <option key={s.id} value={s.id}>{s.name}{selectedCustomer?.favoriteStaffId === s.id ? ' — ♥ favorit' : ''}</option>)}
            </select>
            {selectedCustomer?.favoriteStaffId && staffId === selectedCustomer.favoriteStaffId && (
              <div style={{ fontSize: 11, color: '#7B8A6B', marginTop: 4, fontWeight: 500 }}>♥ Kundens foretrukne frisør er valgt</div>
            )}
          </Field>
          <Field label="Tidspunkt">
            <SmartTimePicker
              value={start}
              slots={availableSlots}
              onChange={setStart}
            />
          </Field>
          <Field label="Slut">
            <div style={{ ...inputStyle, background: '#F4F2EA', color: '#777' }}>{fmtTime(totalEnd)}</div>
          </Field>
        </div>

        <Field label="Noter">
          <textarea value={note} onChange={e => setNote(e.target.value)} rows={2}
            placeholder="Fx ønsker farvebehandling næste gang…"
            style={{ ...inputStyle, fontFamily: 'inherit', resize: 'vertical' }} />
        </Field>

        <div style={{ background: '#F4F7F0', border: '1px solid #DCE6CC', borderRadius: 8, padding: 12, marginTop: 8, fontSize: 12, color: '#3F5A30', display: 'flex', gap: 10, alignItems: 'flex-start' }}>
          <IconCheck size={16} stroke="#3F5A30" />
          <div>
            <strong>Bekræftelse sendes automatisk:</strong> SMS + email straks · påmindelse 24t og 2t før aftalen.
          </div>
        </div>
      </div>

      <div style={{ padding: '16px 28px', borderTop: '1px solid #EFEDE5', display: 'flex', justifyContent: 'flex-end', gap: 10, background: '#FBFAF6' }}>
        <SecondaryBtn onClick={onClose}>Annullér</SecondaryBtn>
        <PrimaryBtn onClick={submit} disabled={!canSubmit}>Opret booking</PrimaryBtn>
      </div>
    </Backdrop>
  );
};

// ---------- Booking detail modal ----------
const BookingDetailModal = ({ booking, onClose, onDelete, onShowMessages }) => {
  if (!booking) return null;
  const segs = getBookingSegments(booking);
  const primary = getBookingPrimary(booking);
  const customer = CUSTOMERS.find(c => c.id === booking.customerId);
  const staff = STAFF.find(s => s.id === booking.staffId);
  const colors = SERVICE_COLORS.pastel[primary.color];
  const totalDur = getBookingDuration(booking);
  const totalPrice = getBookingPrice(booking);
  const title = getBookingTitle(booking);

  return (
    <Backdrop onClose={onClose} width={480}>
      <div style={{ background: colors.bg, padding: '24px 28px', borderRadius: '14px 14px 0 0', borderBottom: `3px solid ${colors.border}` }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div>
            <div style={{ fontSize: 11, color: colors.text, opacity: 0.7, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase' }}>{title}</div>
            <div style={{ fontSize: 24, fontWeight: 600, color: colors.text, marginTop: 4 }}>{customer.name}</div>
            <div style={{ fontSize: 13, color: colors.text, opacity: 0.8, marginTop: 6 }}>
              {fmtTime(booking.start)} – {fmtTime(booking.start + totalDur)} · {totalDur} min · {totalPrice} kr
            </div>
          </div>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: colors.text, opacity: 0.7, padding: 6 }}>
            <IconX size={22} />
          </button>
        </div>
      </div>

      <div style={{ padding: '20px 28px' }}>
        {segs.length > 1 && (
          <div style={{ marginBottom: 16, padding: 12, background: '#FBFAF6', border: '1px solid #EFEDE5', borderRadius: 8 }}>
            <div style={{ fontSize: 11, fontWeight: 600, color: '#666', marginBottom: 8, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Forløb</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
              {segs.map((seg, i) => {
                if (seg.kind === 'gap') {
                  return (
                    <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12, color: '#888', fontStyle: 'italic', paddingLeft: 26 }}>
                      <span style={{ width: 80 }}>{fmtTime(seg.start)}–{fmtTime(seg.end)}</span>
                      <span>Mellemrum · {seg.end - seg.start} min</span>
                    </div>
                  );
                }
                const c = SERVICE_COLORS.pastel[seg.color];
                return (
                  <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13 }}>
                    <div style={{ width: 18, height: 18, borderRadius: 4, background: c.bg, border: `1.5px solid ${c.border}`, flexShrink: 0 }} />
                    <span style={{ width: 80, color: '#666', fontSize: 12, fontWeight: 500 }}>{fmtTime(seg.start)}–{fmtTime(seg.end)}</span>
                    <span style={{ flex: 1, fontWeight: 500 }}>{seg.name}</span>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <DetailRow icon={<IconUser size={16} />} label="Medarbejder" value={staff.name} />
          <DetailRow icon={<IconPhone size={16} />} label="Telefon" value={customer.phone} />
          <DetailRow icon={<IconMail size={16} />} label="Email" value={customer.email} />
          <DetailRow icon={<IconClock size={16} />} label="Tidligere besøg" value={`${customer.visits} aftaler`} />
        </div>

        <div style={{ marginTop: 18, padding: 12, background: '#F4F7F0', borderRadius: 8, border: '1px solid #DCE6CC', display: 'flex', alignItems: 'center', gap: 10 }}>
          <IconCheck size={16} stroke="#3F5A30" />
          <div style={{ fontSize: 12, color: '#3F5A30', flex: 1 }}>
            Bekræftelse sendt · Påmindelse planlagt 24t + 2t før
          </div>
          <button onClick={() => onShowMessages(booking)} style={{
            background: 'transparent', border: 'none', color: '#3F5A30',
            fontSize: 12, fontWeight: 600, cursor: 'pointer', textDecoration: 'underline',
          }}>Vis</button>
        </div>
      </div>

      <div style={{ padding: '16px 28px', borderTop: '1px solid #EFEDE5', display: 'flex', justifyContent: 'space-between', background: '#FBFAF6' }}>
        <SecondaryBtn onClick={() => onDelete(booking)} danger>
          <IconTrash size={14} style={{ marginRight: 6, verticalAlign: 'middle' }} />
          Slet booking
        </SecondaryBtn>
        <div style={{ display: 'flex', gap: 10 }}>
          <SecondaryBtn onClick={onClose}>Luk</SecondaryBtn>
          <PrimaryBtn>Redigér</PrimaryBtn>
        </div>
      </div>
    </Backdrop>
  );
};

const DetailRow = ({ icon, label, value }) => (
  <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
    <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>
    <div style={{ fontSize: 12, color: '#888', width: 130, flexShrink: 0 }}>{label}</div>
    <div style={{ fontSize: 14, color: '#1a1a1a', fontWeight: 500 }}>{value}</div>
  </div>
);

// ---------- Confirmation messages preview ----------
const MessagesPreviewModal = ({ booking, onClose }) => {
  if (!booking) return null;
  const customer = CUSTOMERS.find(c => c.id === booking.customerId);
  const staff = STAFF.find(s => s.id === booking.staffId);
  const totalDur = getBookingDuration(booking);
  const totalPrice = getBookingPrice(booking);
  const title = getBookingTitle(booking);
  const dateStr = 'torsdag 6. juni';
  const timeStr = `${fmtTime(booking.start)}–${fmtTime(booking.start + totalDur)}`;

  const cancelLink = 'klipperiet.dk/aflys/8a3f';
  const smsBefore = `Hej ${customer.name.split(' ')[0]}! Din tid er bekræftet: ${title} hos ${staff.name.split(' ')[0]} ${dateStr} kl. ${fmtTime(booking.start)}. Salon Klipperiet, Østerbro. Aflys/ombook: `;
  const openLink = () => {
    window.dispatchEvent(new CustomEvent('open-customer-link', { detail: booking }));
    onClose();
  };

  return (
    <Backdrop onClose={onClose} width={560}>
      <div style={{ padding: '20px 24px', borderBottom: '1px solid #EFEDE5', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <div style={{ fontSize: 16, fontWeight: 600 }}>Bekræftelser sendt til {customer.name}</div>
        <button onClick={onClose} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: '#888' }}>
          <IconX size={20} />
        </button>
      </div>
      <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 16 }}>
        {/* SMS preview */}
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10, fontSize: 12, color: '#666', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
            <IconMessage size={14} /> SMS · sendt nu
          </div>
          <div style={{ background: '#E8F4FE', borderRadius: 14, padding: '12px 16px', fontSize: 14, color: '#1a3a5c', lineHeight: 1.5, maxWidth: 360 }}>
            {smsBefore}
            <a onClick={openLink} style={{ color: '#1a5cb8', textDecoration: 'underline', cursor: 'pointer', fontWeight: 500 }}>{cancelLink}</a>
          </div>
          <div style={{ fontSize: 11, color: '#888', marginTop: 6, display: 'flex', justifyContent: 'space-between', maxWidth: 360 }}>
            <span>Til {customer.phone}</span>
            <span style={{ color: '#1a5cb8', cursor: 'pointer', textDecoration: 'underline' }} onClick={openLink}>Forhåndsvis kunde-link →</span>
          </div>
        </div>

        {/* Email preview */}
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10, fontSize: 12, color: '#666', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
            <IconMail size={14} /> Email · sendt nu
          </div>
          <div style={{ border: '1px solid #EFEDE5', borderRadius: 10, overflow: 'hidden' }}>
            <div style={{ padding: '10px 14px', background: '#FBFAF6', fontSize: 12, color: '#777', borderBottom: '1px solid #EFEDE5' }}>
              <div><strong>Til:</strong> {customer.email}</div>
              <div><strong>Emne:</strong> Bekræftelse: {title} {dateStr}</div>
            </div>
            <div style={{ padding: 18, fontSize: 13, color: '#1a1a1a', lineHeight: 1.6, background: '#fff' }}>
              <div style={{ fontWeight: 600, fontSize: 16, marginBottom: 12 }}>Tak for din booking!</div>
              <div>Hej {customer.name.split(' ')[0]},</div>
              <div style={{ marginTop: 8 }}>Vi glæder os til at se dig:</div>
              <div style={{ marginTop: 12, padding: 12, background: '#FBFAF6', borderRadius: 8, fontSize: 13 }}>
                <div><strong>Service:</strong> {title}</div>
                <div><strong>Frisør:</strong> {staff.name}</div>
                <div><strong>Tidspunkt:</strong> {dateStr}, kl. {timeStr}</div>
                <div><strong>Pris:</strong> {totalPrice} kr</div>
              </div>
              <div style={{ marginTop: 12, fontSize: 12, color: '#666' }}>Du modtager påmindelse 24t og 2t før din aftale.</div>
            </div>
          </div>
        </div>

        {/* Reminders scheduled */}
        <div style={{ background: '#FBFAF6', border: '1px solid #EFEDE5', borderRadius: 10, padding: 14 }}>
          <div style={{ fontSize: 12, color: '#666', fontWeight: 600, marginBottom: 8 }}>PÅMINDELSER PLANLAGT</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <IconClock size={14} stroke="#888" />
              <span style={{ color: '#888', width: 96 }}>24 timer før</span>
              <span>SMS + email</span>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <IconClock size={14} stroke="#888" />
              <span style={{ color: '#888', width: 96 }}>2 timer før</span>
              <span>SMS</span>
            </div>
          </div>
        </div>
      </div>
      <div style={{ padding: '14px 24px', borderTop: '1px solid #EFEDE5', display: 'flex', justifyContent: 'flex-end', background: '#FBFAF6' }}>
        <PrimaryBtn onClick={onClose}>Luk</PrimaryBtn>
      </div>
    </Backdrop>
  );
};

// ---------- Service editor modal ----------
const ServiceEditorModal = ({ service, onClose, onSave, onDelete }) => {
  if (!service) return null;
  const isNew = !service.id || service._isNew;
  const [name, setName] = React.useState(service.name || '');
  const [duration, setDuration] = React.useState(service.duration ?? 30);
  const [pauseAfter, setPauseAfter] = React.useState(service.pauseAfter ?? 0);
  const [price, setPrice] = React.useState(service.price ?? 350);
  const [color, setColor] = React.useState(service.color || 'green');

  const colorOptions = ['red','green','blue','yellow','purple','pink'];
  const canSave = name.trim().length > 0 && duration > 0;

  const submit = () => {
    if (!canSave) return;
    onSave({
      id: service.id || ('svc_' + Date.now()),
      name: name.trim(),
      duration: parseInt(duration) || 0,
      pauseAfter: parseInt(pauseAfter) || 0,
      price: parseInt(price) || 0,
      color,
    });
  };

  const previewSegs = (() => {
    const segs = [];
    let t = 0;
    segs.push({ kind: 'work', start: 0, end: duration, name });
    t = duration;
    if (pauseAfter > 0) {
      segs.push({ kind: 'gap', start: t, end: t + pauseAfter });
    }
    return segs;
  })();
  const totalLen = duration + pauseAfter;
  const swatch = SERVICE_COLORS.pastel[color];

  return (
    <Backdrop onClose={onClose} width={520}>
      <div style={{ padding: '24px 28px', borderBottom: '1px solid #EFEDE5', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <div>
          <div style={{ fontSize: 11, color: '#888', fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase' }}>{isNew ? 'Ny service' : 'Redigér service'}</div>
          <div style={{ fontSize: 22, fontWeight: 600, color: '#1a1a1a', marginTop: 4 }}>{name || 'Ny service'}</div>
        </div>
        <button onClick={onClose} style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: '#888', padding: 6 }}>
          <IconX size={22} />
        </button>
      </div>

      <div style={{ padding: '20px 28px' }}>
        <Field label="Navn" required>
          <TextInput value={name} onChange={e => setName(e.target.value)} placeholder="Fx Helfarve, Dameklip…" />
        </Field>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
          <Field label="Aktiv tid (min)" required>
            <TextInput type="number" min="5" step="5" value={duration} onChange={e => setDuration(e.target.value)} />
          </Field>
          <Field label="Mellemrum efter (min)">
            <TextInput type="number" min="0" step="5" value={pauseAfter} onChange={e => setPauseAfter(e.target.value)} />
          </Field>
          <Field label="Pris (kr)">
            <TextInput type="number" min="0" step="5" value={price} onChange={e => setPrice(e.target.value)} />
          </Field>
        </div>

        <div style={{ fontSize: 12, color: '#777', marginTop: -4, marginBottom: 14, lineHeight: 1.5 }}>
          <strong style={{ color: '#4a4a44' }}>Mellemrum efter</strong> bruges fx ved farver, hvor produktet skal trække. Frisøren er fri i mellemrummet og kan tage en anden kunde.
        </div>

        <Field label="Farve i kalenderen">
          <div style={{ display: 'flex', gap: 8 }}>
            {colorOptions.map(c => {
              const cs = SERVICE_COLORS.pastel[c];
              const active = color === c;
              return (
                <button key={c} onClick={() => setColor(c)} style={{
                  width: 40, height: 40, borderRadius: 8,
                  background: cs.bg,
                  border: active ? `2.5px solid ${cs.border}` : '1px solid #DDD9CE',
                  cursor: 'pointer', padding: 0, transition: 'all 120ms',
                  outline: active ? `2px solid ${cs.border}33` : 'none',
                  outlineOffset: 2,
                }} aria-label={c} />
              );
            })}
          </div>
        </Field>

        {/* Live preview */}
        <div style={{ marginTop: 8, padding: 14, background: '#FBFAF6', border: '1px solid #EFEDE5', borderRadius: 10 }}>
          <div style={{ fontSize: 11, fontWeight: 600, color: '#666', marginBottom: 10, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Forhåndsvisning</div>
          <div style={{ display: 'flex', gap: 14, alignItems: 'stretch' }}>
            <div style={{ width: 140, position: 'relative', borderRadius: 6, overflow: 'hidden', border: `1.5px solid ${swatch.border}` }}>
              {previewSegs.map((seg, i) => {
                const len = seg.end - seg.start;
                const flex = Math.max(20, (len / Math.max(totalLen, 1)) * 100);
                if (seg.kind === 'gap') {
                  return (
                    <div key={i} style={{
                      flex: `${flex} 0 0`, height: flex * 1.2,
                      background: 'repeating-linear-gradient(45deg, rgba(180,170,140,0.1), rgba(180,170,140,0.1) 5px, rgba(180,170,140,0.22) 5px, rgba(180,170,140,0.22) 10px)',
                      borderTop: '1px dashed rgba(0,0,0,0.15)',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      fontSize: 10, color: '#888', fontStyle: 'italic',
                    }}>
                      Mellemrum {pauseAfter}m
                    </div>
                  );
                }
                return (
                  <div key={i} style={{
                    flex: `${flex} 0 0`, height: flex * 1.2,
                    background: swatch.bg, color: swatch.text,
                    padding: '6px 10px', fontSize: 12, fontWeight: 600,
                  }}>
                    {name || 'Service'}<br/>
                    <span style={{ fontWeight: 400, fontSize: 10, opacity: 0.85 }}>{duration} min</span>
                  </div>
                );
              })}
            </div>
            <div style={{ flex: 1, fontSize: 13, color: '#4a4a44', lineHeight: 1.6 }}>
              <div><strong>Aktiv:</strong> {duration} min</div>
              {pauseAfter > 0 && <div><strong>Mellemrum:</strong> {pauseAfter} min</div>}
              <div><strong>I alt:</strong> {totalLen} min</div>
              <div style={{ marginTop: 6, color: '#777', fontSize: 12 }}>
                {pauseAfter > 0
                  ? `Bookingen optager ${duration} min af frisørens tid — mellemrummet er ledigt for andre kunder.`
                  : `Bookingen optager ${totalLen} min af kalenderen.`}
              </div>
            </div>
          </div>
        </div>
      </div>

      <div style={{ padding: '16px 28px', borderTop: '1px solid #EFEDE5', display: 'flex', justifyContent: 'space-between', background: '#FBFAF6' }}>
        <div>
          {!isNew && onDelete && (
            <SecondaryBtn onClick={() => onDelete(service)} danger>
              <IconTrash size={14} style={{ marginRight: 6, verticalAlign: 'middle' }} />
              Slet
            </SecondaryBtn>
          )}
        </div>
        <div style={{ display: 'flex', gap: 10 }}>
          <SecondaryBtn onClick={onClose}>Annullér</SecondaryBtn>
          <PrimaryBtn onClick={submit} disabled={!canSave}>{isNew ? 'Opret' : 'Gem'}</PrimaryBtn>
        </div>
      </div>
    </Backdrop>
  );
};

// ---------- Toast ----------
const Toast = ({ message, onShowDetails, onClose }) => {
  React.useEffect(() => {
    const t = setTimeout(onClose, 5000);
    return () => clearTimeout(t);
  }, [message]);
  if (!message) return null;
  return (
    <div style={{
      position: 'fixed', bottom: 28, left: '50%',
      transform: 'translateX(-50%)',
      background: '#1F2A1F', color: '#fff',
      padding: '12px 16px 12px 18px', borderRadius: 10,
      display: 'flex', alignItems: 'center', gap: 14,
      boxShadow: '0 12px 32px rgba(0,0,0,0.25)',
      zIndex: 2000, fontSize: 13,
      animation: 'toastIn 240ms ease-out',
    }}>
      <div style={{ background: '#3F5A30', borderRadius: '50%', width: 24, height: 24, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
        <IconCheck size={14} stroke="#fff" />
      </div>
      <span>{message}</span>
      {onShowDetails && (
        <button onClick={onShowDetails} style={{
          background: 'transparent', border: '1px solid rgba(255,255,255,0.3)',
          color: '#fff', borderRadius: 6, padding: '4px 10px', fontSize: 12,
          cursor: 'pointer', fontFamily: 'inherit',
        }}>Vis</button>
      )}
      <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: '#fff', opacity: 0.6, cursor: 'pointer', padding: 4 }}>
        <IconX size={16} />
      </button>
    </div>
  );
};

Object.assign(window, {
  NewBookingModal, BookingDetailModal, MessagesPreviewModal, Toast,
  ServiceEditorModal,
  PrimaryBtn, SecondaryBtn, TextInput, Field, inputStyle,
});
