// components.jsx - EvryStay booking portal shared UI
// Exports to window: Icon, Logo, TEAM, PROPERTY_TIERS, PMS_OPTIONS, routeFor,
//   Person, AvatarStack, Pill, Toggle, Field, SelectField, Tiles, Stepper, Socials,
//   Calendar, SlotPicker, buildSlots, fmtDay, fmtTime

const { useState, useMemo } = React;

/* ----------------------------------------------------------- icons */
const PATHS = {
  calendar: '<rect x="3" y="4.5" width="18" height="16" rx="3"/><path d="M3 9h18M8 2.5v4M16 2.5v4"/>',
  clock: '<circle cx="12" cy="12" r="9"/><path d="M12 7.5V12l3 2"/>',
  video: '<rect x="2.5" y="6" width="13" height="12" rx="2.5"/><path d="M15.5 10l6-3.5v11l-6-3.5"/>',
  check: '<path d="M4 12.5l5 5 11-11"/>',
  checkCircle: '<circle cx="12" cy="12" r="9"/><path d="M8 12.5l2.5 2.5 5-5.5"/>',
  chevL: '<path d="M15 5l-7 7 7 7"/>',
  chevR: '<path d="M9 5l7 7-7 7"/>',
  arrowR: '<path d="M5 12h14M13 6l6 6-6 6"/>',
  user: '<circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-6 8-6s8 2 8 6"/>',
  building: '<rect x="4" y="3" width="16" height="18" rx="2"/><path d="M9 7h2M13 7h2M9 11h2M13 11h2M9 15h2M13 15h2"/>',
  layers: '<path d="M12 3l9 5-9 5-9-5 9-5z"/><path d="M3 13l9 5 9-5"/>',
  mail: '<rect x="3" y="5" width="18" height="14" rx="2.5"/><path d="M4 7l8 6 8-6"/>',
  phone: '<path d="M5 3.5h3.5l1.5 4-2 1.5a13 13 0 0 0 5.5 5.5l1.5-2 4 1.5V21a1.5 1.5 0 0 1-1.6 1.5C9 22 2.5 15.5 2 5.1A1.5 1.5 0 0 1 3.5 3.5z"/>',
  globe: '<circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c2.5 2.5 2.5 15 0 18M12 3c-2.5 2.5-2.5 15 0 18"/>',
  crown: '<path d="M3 7l4 4 5-7 5 7 4-4-1.5 12H4.5L3 7z"/>',
  spark: '<path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8L12 3z"/>',
  pin: '<path d="M12 21s7-6.3 7-11a7 7 0 1 0-14 0c0 4.7 7 11 7 11z"/><circle cx="12" cy="10" r="2.5"/>',
  shield: '<path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3z"/>',
  linkedin: '<rect x="3" y="3" width="18" height="18" rx="3"/><path d="M7 10v7M7 7v.01M11 17v-4a2 2 0 0 1 4 0v4M11 11v6" />',
  instagram: '<rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><path d="M17.5 6.5v.01"/>',
  whatsapp: '<path d="M3.5 20.5l1.3-4.2A8 8 0 1 1 8 19.4l-4.5 1.1z"/><path d="M9 9.5c.3 2.5 3 5.2 5.5 5.5.7.1 1.2-.4 1.5-1l-2-1-1 .8c-1-.5-1.8-1.3-2.3-2.3l.8-1-1-2c-.6.3-1.1.8-1 1.5z" fill="currentColor" stroke="none"/>',
};
function Icon({ name, size = 20, stroke = 2, style, fill }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill || 'none'}
         stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
         style={style} dangerouslySetInnerHTML={{ __html: PATHS[name] || '' }} />
  );
}

function Logo({ height = 26 }) {
  return <img className="wm" src="/evrystay-purple.png" alt="EvryStay" style={{ height }} />;
}

/* ----------------------------------------------------------- data */
const TEAM = {
  ivan: {
    id: 'ivan', name: 'Ivan Vargas', role: 'Head of Customer', photo: '/ivan.jpeg',
    blurb: 'Runs every onboarding personally - he’ll map EvryStay to how your portfolio actually operates.',
  },
  frazer: {
    id: 'frazer', name: 'Frazer King', role: 'Founder & CEO', photo: '/frazer.jpeg',
    blurb: 'Joins demos for larger portfolios to talk roadmap, partnership and where EvryStay is heading.',
  },
};

const PROPERTY_TIERS = [
  { id: '1-20',    k: '1–20',    s: 'properties' },
  { id: '20-50',   k: '20–50',   s: 'properties' },
  { id: '50-200',  k: '50–200',  s: 'properties' },
  { id: '200+',    k: '200+',    s: 'properties' },
  { id: 'hotel',   k: 'Hotel',   s: 'or aparthotel' },
];
const BIG_TIERS = ['50-200', '200+', 'hotel'];

const PMS_OPTIONS = [
  'Guesty', 'Hostaway', 'Hospitable', 'Lodgify', 'Uplisting', 'Smoobu',
  'OwnerRez', 'Track / TRACK HS', 'Streamline', 'Spreadsheets / none', 'Other',
];

// Routing: who you meet + which windows are open, based on portfolio size.
function routeFor(tier, ceoRequested) {
  const big = BIG_TIERS.includes(tier);
  if (big) {
    return {
      big: true,
      hosts: [TEAM.ivan, TEAM.frazer],
      windows: ['afternoon'],
      note: 'For portfolios of 50+, Frazer (CEO) personally joins alongside Ivan. These run in the afternoon.',
      canRequestCeo: false,
    };
  }
  return {
    big: false,
    hosts: ceoRequested ? [TEAM.ivan, TEAM.frazer] : [TEAM.ivan],
    windows: ['morning', 'afternoon'],
    note: ceoRequested
      ? 'We’ll ask Frazer to join. If he’s free at your chosen time, he’ll be there too.'
      : 'You’ll meet Ivan, our Head of Customer.',
    canRequestCeo: true,
    ceoRequested: !!ceoRequested,
  };
}

/* ----------------------------------------------------------- people */
function Person({ person, size = 52, sub, children }) {
  return (
    <div className="person">
      <img className="avatar" src={person.photo} alt={person.name}
           style={{ width: size, height: size }} />
      <div style={{ minWidth: 0 }}>
        <div style={{ fontWeight: 700, fontSize: 15.5, color: 'var(--ink-900)' }}>{person.name}</div>
        <div style={{ fontSize: 13, color: 'var(--ink-500)' }}>{sub || person.role}</div>
        {children}
      </div>
    </div>
  );
}

function AvatarStack({ people, size = 38 }) {
  return (
    <div className="avatar-stack">
      {people.map((p) => (
        <img key={p.id} src={p.photo} alt={p.name} style={{ width: size, height: size }} />
      ))}
    </div>
  );
}

/* ----------------------------------------------------------- primitives */
function Pill({ children, tone }) {
  return <span className={'pill' + (tone ? ' ' + tone : '')}>{children}</span>;
}

function Toggle({ checked, onChange, id }) {
  return (
    <label className="toggle" htmlFor={id}>
      <input id={id} type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} />
      <span className="track" />
      <span className="knob" />
    </label>
  );
}

function Field({ label, required, type = 'text', value, onChange, placeholder, inputMode, autoComplete }) {
  return (
    <div className="field">
      <label>{label}{required && <span className="req"> *</span>}</label>
      <input type={type} value={value} placeholder={placeholder} inputMode={inputMode}
             autoComplete={autoComplete}
             onChange={(e) => onChange(e.target.value)} />
    </div>
  );
}

function SelectField({ label, required, value, onChange, options, placeholder }) {
  return (
    <div className="field">
      <label>{label}{required && <span className="req"> *</span>}</label>
      <select value={value} onChange={(e) => onChange(e.target.value)}>
        <option value="" disabled>{placeholder || 'Select…'}</option>
        {options.map((o) => <option key={o} value={o}>{o}</option>)}
      </select>
    </div>
  );
}

function Tiles({ options, value, onChange }) {
  return (
    <div className="tiles">
      {options.map((o) => (
        <button key={o.id} type="button" className="tile" aria-pressed={value === o.id}
                onClick={() => onChange(o.id)}>
          <span className="t-k">{o.k}</span>
          <span className="t-s">{o.s}</span>
        </button>
      ))}
    </div>
  );
}

function Stepper({ step, labels }) {
  const steps = labels || ['Portfolio', 'Pick a time', 'Your details'];
  return (
    <div className="stepper">
      {steps.map((s, i) => (
        <React.Fragment key={s}>
          {i > 0 && <span className="bar" />}
          <div className={'st ' + (step === i ? 'active' : step > i ? 'done' : '')}>
            <span className="dot">{step > i ? <Icon name="check" size={14} stroke={2.6} /> : i + 1}</span>
            <span className="lbl">{s}</span>
          </div>
        </React.Fragment>
      ))}
    </div>
  );
}

const SOCIALS = [
  { name: 'linkedin', label: 'LinkedIn', href: 'https://www.linkedin.com/company/evrystay' },
  { name: 'instagram', label: 'Instagram', href: 'https://www.instagram.com/evrystay' },
  { name: 'whatsapp', label: 'WhatsApp', href: 'https://wa.me/61439758079' },
  { name: 'globe', label: 'Website', href: 'https://evrystay.com.au' },
  { name: 'mail', label: 'Email', href: 'mailto:team@evrystay.com.au' },
];
function Socials({ size = 40 }) {
  return (
    <div className="socials">
      {SOCIALS.map((s) => (
        <a key={s.name} href={s.href} target="_blank" rel="noreferrer" aria-label={s.label} title={s.label}
           style={{ width: size, height: size }}>
          <Icon name={s.name} size={19} stroke={1.9} />
        </a>
      ))}
    </div>
  );
}

/* ----------------------------------------------------------- date / slot helpers */
const DOW = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const MON = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

function ymd(d) { return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0'); }
function fmtDay(d) { return DOW[d.getDay()] + ', ' + MON[d.getMonth()] + ' ' + d.getDate(); }
function fmtTime(mins) {
  let h = Math.floor(mins / 60), m = mins % 60;
  const ap = h >= 12 ? 'pm' : 'am';
  let hh = h % 12; if (hh === 0) hh = 12;
  return hh + (m ? ':' + String(m).padStart(2, '0') : ':00') + ap;
}

// deterministic pseudo-random so availability is stable across renders
function seedRand(str) {
  let h = 2166136261;
  for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = Math.imul(h, 16777619); }
  return ((h >>> 0) % 1000) / 1000;
}

const WINDOWS = {
  morning:   { label: 'Morning',   start: 10 * 60, end: 13 * 60 },
  afternoon: { label: 'Afternoon', start: 14 * 60, end: 17 * 60 + 30 },
};

// 45-min cadence slots that fit inside the window
function windowSlots(win) {
  const out = [];
  for (let t = win.start; t + 45 <= win.end; t += 45) out.push(t);
  return out;
}

// available slots for a given date + open windows; weekends closed
function buildSlots(date, windows) {
  const dow = date.getDay();
  if (dow === 0 || dow === 6) return [];
  const key = ymd(date);
  const groups = [];
  windows.forEach((wname) => {
    const win = WINDOWS[wname];
    const slots = windowSlots(win).filter((t) => seedRand(key + '-' + t) > 0.28); // ~some taken
    if (slots.length) groups.push({ name: wname, label: win.label, slots });
  });
  return groups;
}
function dateHasSlots(date, windows) {
  return buildSlots(date, windows).length > 0;
}

/* ----------------------------------------------------------- calendar */
function Calendar({ month, onMonth, selected, onSelect, windows, minDate }) {
  const first = new Date(month.getFullYear(), month.getMonth(), 1);
  const startPad = first.getDay();
  const daysInMonth = new Date(month.getFullYear(), month.getMonth() + 1, 0).getDate();
  const today = minDate;
  const cells = [];
  for (let i = 0; i < startPad; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(month.getFullYear(), month.getMonth(), d));

  const prevDisabled = month.getFullYear() === today.getFullYear() && month.getMonth() === today.getMonth();

  return (
    <div>
      <div className="cal-head">
        <div className="cal-title">{MON[month.getMonth()]} {month.getFullYear()}</div>
        <div className="cal-nav">
          <button onClick={() => onMonth(-1)} disabled={prevDisabled} aria-label="Previous month"><Icon name="chevL" size={18} /></button>
          <button onClick={() => onMonth(1)} aria-label="Next month"><Icon name="chevR" size={18} /></button>
        </div>
      </div>
      <div className="cal-grid">
        {DOW.map((d) => <div key={d} className="cal-dow">{d[0]}</div>)}
        {cells.map((c, i) => {
          if (!c) return <div key={'p' + i} />;
          const past = c < new Date(today.getFullYear(), today.getMonth(), today.getDate());
          const has = !past && dateHasSlots(c, windows);
          const isSel = selected && ymd(c) === ymd(selected);
          const isToday = ymd(c) === ymd(today);
          return (
            <button key={ymd(c)}
                    className={'cal-cell' + (has ? ' has-slots' : '') + (isSel ? ' is-selected' : '') + (isToday ? ' is-today' : '')}
                    disabled={!has}
                    onClick={() => onSelect(c)}>
              {c.getDate()}
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ----------------------------------------------------------- slot picker */
function SlotPicker({ date, windows, value, onPick }) {
  const groups = useMemo(() => buildSlots(date, windows), [ymd(date), windows.join(',')]);
  if (!groups.length) {
    return <div className="muted" style={{ fontSize: 14, padding: '20px 2px' }}>No times left on this day - try another date.</div>;
  }
  return (
    <div className="slot-scroll">
      {groups.map((g) => (
        <React.Fragment key={g.name}>
          <div className="slot-period">{g.label}</div>
          {g.slots.map((t) => (
            <button key={t} className={'slot' + (value === t ? ' is-selected' : '')} onClick={() => onPick(t)}>
              <span>{fmtTime(t)}</span>
              <span style={{ fontSize: 12.5, color: 'var(--ink-400)', fontWeight: 600 }}>45 min</span>
            </button>
          ))}
        </React.Fragment>
      ))}
    </div>
  );
}

/* ----------------------------------------------------------- export */
Object.assign(window, {
  Icon, Logo, TEAM, PROPERTY_TIERS, PMS_OPTIONS, BIG_TIERS, routeFor,
  Person, AvatarStack, Pill, Toggle, Field, SelectField, Tiles, Stepper, Socials,
  Calendar, SlotPicker, buildSlots, dateHasSlots, fmtDay, fmtTime, ymd, MON, DOW,
});
