/* Rinse n Repeat — Appointment Manager (owner dashboard).
   Month calendar + day agenda + create/edit/status over window.RNRStore.
   Field names match the database columns exactly (customer_name, scheduled_date…).
   Exposed as window.RNRAdmin (a React component). */
(function () {
  const { Button, Icon, Badge, Input, Select, Textarea } = window.RinseNRepeatDesignSystem_9f80bd;
  const D = window.RNR_DATA;

  const STATUS = {
    pending:   { label: 'Pending',   bg: 'var(--orange-050)',  fg: 'var(--orange-700)',  dot: 'var(--orange-500)' },
    confirmed: { label: 'Confirmed', bg: '#E7F0FB',            fg: 'var(--info-500)',    dot: 'var(--info-500)' },
    completed: { label: 'Completed', bg: 'var(--success-050)', fg: 'var(--success-500)', dot: 'var(--success-500)' },
    cancelled: { label: 'Cancelled', bg: 'var(--gray-100)',    fg: 'var(--gray-600)',    dot: 'var(--gray-400)' },
  };
  const MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
  const DOW = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];

  const ymd = (d) => `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
  const todayStr = () => ymd(new Date());
  const parseYmd = (s) => { const [y,m,d] = (s||'').split('-').map(Number); return new Date(y, (m||1)-1, d||1); };
  const prettyDate = (s) => { if(!s) return 'No date'; const d = parseYmd(s); return `${DOW[d.getDay()]}, ${MONTHS[d.getMonth()]} ${d.getDate()}`; };

  function monthMatrix(year, month) {
    const first = new Date(year, month, 1);
    const start = new Date(year, month, 1 - first.getDay());
    const weeks = [];
    for (let w = 0; w < 6; w++) {
      const row = [];
      for (let i = 0; i < 7; i++) { const d = new Date(start); d.setDate(start.getDate() + w*7 + i); row.push(d); }
      weeks.push(row);
    }
    return weeks;
  }

  /* Demo data only — never seeds a real database. */
  async function seedIfEmpty() {
    if (window.RNRStore.mode !== 'local') return;
    const cur = await window.RNRStore.list();
    if (cur.length) return;
    const base = new Date();
    const mk = (offset, o) => { const d = new Date(base); d.setDate(base.getDate()+offset); return Object.assign({ scheduled_date: ymd(d) }, o); };
    const seeds = [
      mk(0,  { customer_name: 'Marcus Delgado', phone: '(630) 555-0142', email: 'marcus@email.com', service: 'Concrete Pressure Washing', property_type: 'Residential', time_window: 'Morning (9am–12pm)', address: '412 Oak St, Plainfield, IL', status: 'confirmed', details: 'Driveway + front walk.' }),
      mk(1,  { customer_name: 'Priya Shah', phone: '(630) 555-0198', email: 'priya@email.com', service: 'House Soft Washing', property_type: 'Residential', time_window: 'Afternoon (3pm–6pm)', address: '87 Birchwood Ln, Naperville, IL', status: 'pending', details: 'Two-story vinyl, north wall mildew.' }),
      mk(3,  { customer_name: 'Tom Reilly', phone: '(815) 555-0110', email: 'tom@email.com', service: 'Gutter Cleaning', property_type: 'Residential', time_window: 'Midday (12pm–3pm)', address: '23 Maple Ct, Plainfield, IL', status: 'pending' }),
      mk(6,  { customer_name: 'Westfield HOA', phone: '(630) 555-0077', email: 'ops@westfield.org', service: 'Commercial Buildings Washing', property_type: 'Commercial', time_window: 'Morning (9am–12pm)', address: '1 Commons Dr, Naperville, IL', status: 'confirmed', details: 'Clubhouse exterior + entry glass.' }),
      mk(-2, { customer_name: 'Alyssa King', phone: '(815) 555-0163', email: 'alyssa@email.com', service: 'Window Washing', property_type: 'Residential', time_window: 'Afternoon (3pm–6pm)', address: '556 Cedar Ave, Plainfield, IL', status: 'completed' }),
    ];
    for (const s of seeds) await window.RNRStore.create(s);
  }

  const EMPTY = { customer_name:'', phone:'', email:'', service:'', property_type:'Residential', scheduled_date: todayStr(), time_window:'', address:'', details:'', status:'pending' };

  function Modal({ initial, onSave, onClose }) {
    const [f, setF] = React.useState(initial);
    const [busy, setBusy] = React.useState(false);
    const set = (k) => (e) => setF((p) => ({ ...p, [k]: e.target.value }));
    const save = async () => { setBusy(true); try { await onSave(f); } catch (err) { alert(err.message || 'Could not save.'); } finally { setBusy(false); } };
    return (
      <div onClick={onClose} style={{ position:'fixed', inset:0, background:'rgba(11,11,12,.55)', zIndex:100, display:'flex', alignItems:'flex-start', justifyContent:'center', padding:'24px 14px', overflow:'auto' }}>
        <div onClick={(e)=>e.stopPropagation()} style={{ background:'#fff', borderRadius:'var(--radius-2xl)', boxShadow:'var(--shadow-lg)', padding:'clamp(20px,5vw,32px)', width:'100%', maxWidth:520 }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:20 }}>
            <h2 style={{ fontFamily:'var(--font-display)', fontWeight:800, fontSize:22, margin:0, color:'var(--black-900)' }}>{initial.id ? 'Edit appointment' : 'New appointment'}</h2>
            <button onClick={onClose} style={{ background:'none', border:'none', cursor:'pointer', color:'var(--gray-500)', display:'inline-flex' }}><Icon name="x" size={22} /></button>
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
            <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(min(200px,100%),1fr))', gap:12 }}>
              <Input label="Customer name" value={f.customer_name} onChange={set('customer_name')} placeholder="Full name" />
              <Input label="Phone" value={f.phone} onChange={set('phone')} placeholder="(555) 000-0000" />
            </div>
            <Input label="Email" type="email" value={f.email} onChange={set('email')} placeholder="you@email.com" />
            <Select label="Service" placeholder="Choose a service" value={f.service} onChange={set('service')} options={D.serviceOptions} />
            <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(min(200px,100%),1fr))', gap:12 }}>
              <Input label="Date" type="date" value={f.scheduled_date} onChange={set('scheduled_date')} />
              <Select label="Time" placeholder="Any time" value={f.time_window} onChange={set('time_window')} options={['Morning (9am–12pm)','Midday (12pm–3pm)','Afternoon (3pm–6pm)','Flexible / any time']} />
            </div>
            <Input label="Address" value={f.address} onChange={set('address')} placeholder="Street, city, ZIP" />
            <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(min(200px,100%),1fr))', gap:12 }}>
              <Select label="Property type" value={f.property_type} onChange={set('property_type')} options={['Residential','Commercial']} />
              <Select label="Status" value={f.status} onChange={set('status')} options={Object.keys(STATUS).map((k)=>({value:k,label:STATUS[k].label}))} />
            </div>
            <Textarea label="Notes" rows={2} value={f.details} onChange={set('details')} placeholder="Job details…" />
            <div style={{ display:'flex', gap:10, justifyContent:'flex-end', marginTop:4 }}>
              <Button variant="ghost" onClick={onClose} style={{ color:'var(--gray-600)' }}>Cancel</Button>
              <Button variant="primary" disabled={busy} onClick={save}>{busy ? 'Saving…' : (initial.id ? 'Save changes' : 'Add appointment')}</Button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  function ApptCard({ a, onStatus, onEdit, onDelete }) {
    const s = STATUS[a.status] || STATUS.pending;
    return (
      <div style={{ background:'#fff', border:'1px solid var(--gray-100)', borderLeft:`4px solid ${s.dot}`, borderRadius:'var(--radius-md)', padding:16, boxShadow:'var(--shadow-xs)' }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:10 }}>
          <div>
            <div style={{ fontWeight:700, fontSize:15.5, color:'var(--black-900)' }}>{a.customer_name || 'Unnamed'}</div>
            <div style={{ fontSize:13.5, color:'var(--orange-600)', fontWeight:600, marginTop:2 }}>{a.service || 'Service TBD'}</div>
          </div>
          <span style={{ display:'inline-flex', alignItems:'center', gap:6, background:s.bg, color:s.fg, fontSize:11.5, fontWeight:700, padding:'5px 11px', borderRadius:'var(--radius-pill)' }}><span style={{width:6,height:6,borderRadius:'50%',background:s.dot}} />{s.label}</span>
        </div>
        <div style={{ display:'flex', flexWrap:'wrap', gap:'6px 16px', margin:'12px 0', fontSize:13, color:'var(--gray-600)' }}>
          {a.time_window ? <span style={{display:'flex',gap:6,alignItems:'center'}}><Icon name="clock" size={15} color="var(--gray-500)" />{a.time_window}</span> : null}
          {a.phone ? <span style={{display:'flex',gap:6,alignItems:'center'}}><Icon name="phone" size={15} color="var(--gray-500)" />{a.phone}</span> : null}
          {a.address ? <span style={{display:'flex',gap:6,alignItems:'center'}}><Icon name="map-pin" size={15} color="var(--gray-500)" />{a.address}</span> : null}
          {a.property_type ? <span style={{display:'flex',gap:6,alignItems:'center'}}><Icon name="home" size={15} color="var(--gray-500)" />{a.property_type}</span> : null}
          {a.source === 'online' ? <span style={{display:'flex',gap:6,alignItems:'center',color:'var(--orange-600)',fontWeight:600}}><Icon name="globe" size={15} />Booked online</span> : null}
        </div>
        {a.details ? <p style={{ margin:'0 0 12px', fontSize:13.5, color:'var(--gray-700)', background:'var(--gray-50)', padding:'8px 10px', borderRadius:'var(--radius-sm)' }}>{a.details}</p> : null}
        <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
          {a.status !== 'confirmed' && a.status !== 'completed' ? <Button size="sm" variant="dark" onClick={()=>onStatus(a,'confirmed')}>Confirm</Button> : null}
          {a.status !== 'completed' ? <Button size="sm" variant="primary" onClick={()=>onStatus(a,'completed')}>Complete</Button> : null}
          {a.status !== 'cancelled' && a.status !== 'completed' ? <Button size="sm" variant="ghost" style={{color:'var(--gray-600)'}} onClick={()=>onStatus(a,'cancelled')}>Cancel</Button> : null}
          <span style={{ marginLeft:'auto', display:'flex', gap:4 }}>
            <button onClick={()=>onEdit(a)} title="Edit" style={{ background:'none', border:'none', cursor:'pointer', color:'var(--gray-500)', padding:6, display:'inline-flex' }}><Icon name="pencil" size={17} /></button>
            <button onClick={()=>onDelete(a)} title="Delete" style={{ background:'none', border:'none', cursor:'pointer', color:'var(--gray-500)', padding:6, display:'inline-flex' }}><Icon name="trash-2" size={17} /></button>
          </span>
        </div>
      </div>
    );
  }

  const navBtn = { background:'#fff', border:'1.5px solid var(--gray-200)', borderRadius:'var(--radius-md)', cursor:'pointer', color:'var(--gray-700)', padding:'8px 9px', display:'inline-flex' };

  function Admin({ tenant, onLock }) {
    const isMobile = window.RNRUseIsMobile();
    const [items, setItems] = React.useState(null);
    const [error, setError] = React.useState(null);
    const [cursor, setCursor] = React.useState(() => { const d = new Date(); return { y: d.getFullYear(), m: d.getMonth() }; });
    const [selected, setSelected] = React.useState(todayStr());
    const [filter, setFilter] = React.useState('all');
    const [query, setQuery] = React.useState('');
    const [modal, setModal] = React.useState(null);

    const reload = React.useCallback(async () => { try { setItems(await window.RNRStore.list()); } catch (e) { setError(e.message); } }, []);
    React.useEffect(() => { let un; (async () => { try { await seedIfEmpty(); } catch (_) {} await reload(); un = window.RNRStore.subscribe(reload); })(); return () => { if (un) un(); }; }, [reload]);

    if (error) return <div style={{ padding:60, textAlign:'center', color:'var(--danger-500)', fontFamily:'var(--font-body)' }}>Couldn’t load appointments: {error}</div>;
    if (items === null) return <div style={{ padding:80, textAlign:'center', color:'var(--gray-500)', fontFamily:'var(--font-body)' }}>Loading appointments…</div>;

    const matchQ = (a) => !query || ['customer_name','address','service'].some((k)=>(a[k]||'').toLowerCase().includes(query.toLowerCase()));
    const matchF = (a) => filter === 'all' || a.status === filter;
    const visible = items.filter((a) => matchQ(a) && matchF(a));
    const byDay = {};
    visible.forEach((a) => { (byDay[a.scheduled_date] = byDay[a.scheduled_date] || []).push(a); });

    const now = new Date();
    const weekEnd = new Date(); weekEnd.setDate(now.getDate() + 7);
    const stats = {
      today: items.filter((a)=>a.scheduled_date===todayStr() && a.status!=='cancelled').length,
      week: items.filter((a)=>{ const d=parseYmd(a.scheduled_date); return d>=new Date(now.getFullYear(),now.getMonth(),now.getDate()) && d<=weekEnd && a.status!=='cancelled'; }).length,
      pending: items.filter((a)=>a.status==='pending').length,
      completedMonth: items.filter((a)=>{ const d=parseYmd(a.scheduled_date); return a.status==='completed' && d.getFullYear()===cursor.y && d.getMonth()===cursor.m; }).length,
    };

    const weeks = monthMatrix(cursor.y, cursor.m);
    const dayItems = (byDay[selected] || []).slice().sort((a,b)=>(a.time_window||'').localeCompare(b.time_window||''));

    const onStatus = (a, status) => window.RNRStore.update(a.id, { status }).catch((e)=>alert(e.message));
    const onDelete = (a) => { if (confirm('Delete this appointment?')) window.RNRStore.remove(a.id).catch((e)=>alert(e.message)); };
    const saveModal = async (f) => { if (f.id) { const {id,...patch}=f; delete patch.tenant_id; delete patch.created_at; delete patch.updated_at; delete patch.source; await window.RNRStore.update(id, patch); } else { await window.RNRStore.create(f); setSelected(f.scheduled_date); } setModal(null); };

    const StatCard = ({ n, label, color }) => (
      <div style={{ background:'#fff', borderRadius:'var(--radius-lg)', boxShadow:'var(--shadow-sm)', padding:'18px 20px', flex:'1 1 150px' }}>
        <div style={{ fontFamily:'var(--font-display)', fontWeight:900, fontSize:32, color: color||'var(--black-900)', lineHeight:1 }}>{n}</div>
        <div style={{ fontSize:13, color:'var(--gray-600)', marginTop:6, fontWeight:500 }}>{label}</div>
      </div>
    );

    return (
      <div style={{ fontFamily:'var(--font-body)', background:'var(--paper)', minHeight:'100vh' }}>
        <header style={{ background:'var(--black-950)', borderBottom:'1px solid var(--border-on-dark)' }}>
          <div style={{ maxWidth:1240, margin:'0 auto', padding:'14px var(--gutter-x)', display:'flex', alignItems:'center', gap:12, flexWrap:'wrap' }}>
            <img src="assets/logo-dark.png" alt="Rinse n Repeat" style={{ height:40 }} />
            <span style={{ color:'rgba(255,255,255,.55)', fontSize:14, fontWeight:600, borderLeft:'1px solid rgba(255,255,255,.2)', paddingLeft:16 }}>Appointment Manager{tenant && tenant.name ? ' · ' + tenant.name : ''}</span>
            <span style={{ marginLeft:'auto', display:'flex', gap:12, alignItems:'center' }}>
              <span style={{ fontSize:12, fontWeight:700, letterSpacing:'.04em', textTransform:'uppercase', color: window.RNRStore.mode==='supabase' ? 'var(--success-500)' : 'var(--orange-400)', background:'rgba(255,255,255,.06)', padding:'5px 11px', borderRadius:'var(--radius-pill)' }}>{window.RNRStore.mode==='supabase' ? '● Live database' : '● Demo (this device)'}</span>
              <Button size="sm" variant="primary" iconLeft={<Icon name="plus" size={16} />} onClick={()=>setModal({ ...EMPTY, scheduled_date: selected })}>New</Button>
              <button onClick={onLock} title="Sign out" style={{ background:'none', border:'1px solid rgba(255,255,255,.2)', borderRadius:'var(--radius-pill)', color:'#fff', cursor:'pointer', padding:'8px 10px', display:'inline-flex' }}><Icon name="log-out" size={16} /></button>
            </span>
          </div>
        </header>

        <div style={{ maxWidth:1240, margin:'0 auto', padding:'26px var(--gutter-x) 60px' }}>
          <div style={{ display:'flex', gap:12, marginBottom:22, flexWrap:'wrap' }}>
            <StatCard n={stats.today} label="Today" color="var(--orange-500)" />
            <StatCard n={stats.week} label="Next 7 days" />
            <StatCard n={stats.pending} label="Pending confirmation" color="var(--orange-600)" />
            <StatCard n={stats.completedMonth} label="Completed this month" color="var(--success-500)" />
          </div>

          <div style={{ display:'flex', gap:10, alignItems:'center', marginBottom:18, flexWrap:'wrap' }}>
            {['all','pending','confirmed','completed','cancelled'].map((k) => {
              const active = filter === k;
              const lbl = k==='all' ? 'All' : STATUS[k].label;
              return <button key={k} onClick={()=>setFilter(k)} style={{ padding:'8px 15px', borderRadius:'var(--radius-pill)', cursor:'pointer', fontFamily:'var(--font-body)', fontWeight:600, fontSize:13.5, transition:'var(--t-all)', background: active ? 'var(--black-950)' : '#fff', color: active ? '#fff' : 'var(--gray-700)', border:'1.5px solid ' + (active ? 'var(--black-950)' : 'var(--gray-200)') }}>{lbl}</button>;
            })}
            <div style={{ marginLeft:'auto', flex:'1 1 200px', maxWidth:300, minWidth:180 }}>
              <Input placeholder="Search name, address, service…" value={query} onChange={(e)=>setQuery(e.target.value)} icon={<Icon name="search" size={17} />} />
            </div>
          </div>

          <div style={{ display:'grid', gridTemplateColumns: isMobile ? '1fr' : '1.6fr 1fr', gap:22, alignItems:'start' }}>
            <div style={{ background:'#fff', borderRadius:'var(--radius-xl)', boxShadow:'var(--shadow-sm)', padding: isMobile ? 12 : 22 }}>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:16 }}>
                <h2 style={{ fontFamily:'var(--font-display)', fontWeight:800, fontSize:22, margin:0, color:'var(--black-900)' }}>{MONTHS[cursor.m]} {cursor.y}</h2>
                <div style={{ display:'flex', gap:8 }}>
                  <button onClick={()=>setCursor((c)=>{ const d=new Date(c.y,c.m-1,1); return {y:d.getFullYear(),m:d.getMonth()}; })} style={navBtn}><Icon name="chevron-left" size={18} /></button>
                  <Button size="sm" variant="outline-accent" onClick={()=>{ const d=new Date(); setCursor({y:d.getFullYear(),m:d.getMonth()}); setSelected(todayStr()); }}>Today</Button>
                  <button onClick={()=>setCursor((c)=>{ const d=new Date(c.y,c.m+1,1); return {y:d.getFullYear(),m:d.getMonth()}; })} style={navBtn}><Icon name="chevron-right" size={18} /></button>
                </div>
              </div>
              <div style={{ display:'grid', gridTemplateColumns:'repeat(7,1fr)', gap: isMobile ? 3 : 6 }}>
                {DOW.map((d)=><div key={d} style={{ textAlign:'center', fontSize:11.5, fontWeight:700, color:'var(--gray-500)', letterSpacing:'.04em', padding:'2px 0' }}>{d.toUpperCase()}</div>)}
                {weeks.map((row,wi)=>row.map((d,di)=>{
                  const inMonth = d.getMonth() === cursor.m;
                  const key = ymd(d);
                  const isToday = key === todayStr();
                  const isSel = key === selected;
                  const list = byDay[key] || [];
                  return (
                    <button key={wi+'-'+di} onClick={()=>setSelected(key)} style={{
                      textAlign:'left', cursor:'pointer', minHeight: isMobile ? 54 : 74, padding: isMobile ? '4px 3px' : '6px 7px', borderRadius:'var(--radius-md)',
                      background: isSel ? 'var(--orange-050)' : (inMonth ? '#fff' : 'var(--gray-50)'),
                      border:'1.5px solid ' + (isSel ? 'var(--orange-500)' : 'var(--gray-100)'),
                      opacity: inMonth ? 1 : .55, display:'flex', flexDirection:'column', gap:4, transition:'var(--t-all)'
                    }}>
                      <span style={{ display:'inline-flex', alignItems:'center', justifyContent:'center', width:22, height:22, borderRadius:'50%', fontSize:12.5, fontWeight:700, alignSelf:'flex-start', background: isToday ? 'var(--orange-500)' : 'transparent', color: isToday ? '#fff' : 'var(--gray-800)' }}>{d.getDate()}</span>
                      <span style={{ display:'flex', flexDirection:'column', gap:2 }}>
                        {list.slice(0,2).map((a)=>{ const s=STATUS[a.status]||STATUS.pending; return <span key={a.id} style={{ fontSize:10.5, fontWeight:600, color:s.fg, background:s.bg, borderRadius:4, padding:'1px 5px', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{(a.customer_name||'—').split(' ')[0]}</span>; })}
                        {list.length>2 ? <span style={{ fontSize:10, color:'var(--gray-500)', fontWeight:600, paddingLeft:2 }}>+{list.length-2} more</span> : null}
                      </span>
                    </button>
                  );
                }))}
              </div>
            </div>

            <div>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:14 }}>
                <h3 style={{ fontFamily:'var(--font-display)', fontWeight:800, fontSize:18, margin:0, color:'var(--black-900)' }}>{prettyDate(selected)}</h3>
                <Button size="sm" variant="ghost" style={{ color:'var(--orange-600)' }} iconLeft={<Icon name="plus" size={15} />} onClick={()=>setModal({ ...EMPTY, scheduled_date: selected })}>Add</Button>
              </div>
              <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
                {dayItems.length === 0 ? (
                  <div style={{ background:'#fff', border:'1px dashed var(--gray-200)', borderRadius:'var(--radius-lg)', padding:'34px 20px', textAlign:'center', color:'var(--gray-500)' }}>
                    <Icon name="calendar-check" size={26} color="var(--gray-300)" /><div style={{ marginTop:8, fontSize:14 }}>No appointments{filter!=='all'?' ('+STATUS[filter].label.toLowerCase()+')':''} this day.</div>
                  </div>
                ) : dayItems.map((a)=><ApptCard key={a.id} a={a} onStatus={onStatus} onEdit={(x)=>setModal(x)} onDelete={onDelete} />)}
              </div>
            </div>
          </div>
        </div>
        {modal ? <Modal initial={modal} onSave={saveModal} onClose={()=>setModal(null)} /> : null}
      </div>
    );
  }

  window.RNRAdmin = Admin;
})();
