/* global React, portalApi, useCart, useRoute, I */
const commerceMoney=cents=>new Intl.NumberFormat('en-US',{style:'currency',currency:'USD'}).format(cents/100);
const commerceStatus={not_configured:'Delivery not enabled',queued:'Queued',sending:'Sending',accepted:'Accepted by provider',needs_review:'Delivery needs review'};

function BookingRequest(){
  const cart=useCart(),{route}=useRoute();
  const [catalog,setCatalog]=React.useState([]),[user,setUser]=React.useState(null),[ready,setReady]=React.useState(false),[error,setError]=React.useState(''),[receipt,setReceipt]=React.useState(null),[busy,setBusy]=React.useState(false);
  const [form,setForm]=React.useState({name:'',company:'',brief:'',preferredDate:'',timing:'',phone:'',smsConsent:false,answers:{}});
  const requestKey=React.useRef(crypto.randomUUID()),inFlight=React.useRef(false),initialized=React.useRef('');
  const params=new URLSearchParams(window.location.search);
  const packageId=params.get('package')||route.params?.package;
  const chosen=params.get('service')||route.params?.service;
  const tier=params.get('tier')||route.params?.tier;
  const campaignPlans={remote:{name:'Remote Campaign Desk',price:'$1,450 per month'},growth:{name:'Growth Campaign System',price:'$2,000 per month'},full:{name:'Full Community Growth',price:'$2,500 per month'}};
  const selectedPlan=chosen==='campaigns'?campaignPlans[tier]:null;
  React.useEffect(()=>{let active=true;Promise.all([portalApi('commerce-catalog'),portalApi('session').catch(e=>{if(e.status===401)return null;throw e;})]).then(([c,s])=>{if(!active)return;setCatalog(c.catalog);setUser(s?.user||null);if(s?.user)setForm(f=>({...f,name:f.name||s.user.name}));const pkg=(window.PACKAGES||[]).find(p=>p.id===packageId);const selectionKey=pkg?`package:${pkg.id}`:[chosen,tier].filter(Boolean).join(':');if(selectionKey&&initialized.current!==selectionKey){const serviceKey=pkg?(pkg.lane==='nights'||pkg.id==='pkg-birthday-recap'?'video':'photography'):chosen;const item=c.catalog.find(i=>i.kind==='service'&&(i.key===serviceKey||i.id===serviceKey));if(item)cart.add({id:item.id,name:item.name,kind:'service',price:0,variant:'Quote required',qty:1});if(pkg)setForm(f=>({...f,brief:f.brief||`Package enquiry: ${pkg.name} (${pkg.code})\n${pkg.subtitle}\n\nPlease confirm the current scope, availability and quote.`}));else if(selectedPlan)setForm(f=>({...f,brief:f.brief||`I am interested in the ${selectedPlan.name}. Our primary campaign goal is: `,timing:f.timing||`${selectedPlan.price} plus approved advertising spend`}));initialized.current=selectionKey;}}).catch(e=>{if(active)setError(e.message);}).finally(()=>{if(active)setReady(true);});return()=>{active=false;};},[chosen,packageId,tier]);
  const lines=cart.items.map(line=>{const item=catalog.find(i=>i.id===line.id);return item?{...item,variant:line.variant,qty:line.qty}:null;}).filter(Boolean);
  const invalid=ready&&cart.items.length!==lines.length;
  const services=lines.filter(i=>i.kind==='service'),productTotal=lines.reduce((n,i)=>n+(i.unitCents||0)*i.qty,0);
  function update(key,value){setForm(f=>({...f,[key]:value}));setError('');}
  async function submit(e){e.preventDefault();if(inFlight.current)return;if(!user){setError('Sign in before submitting so this request belongs to your account.');return;}inFlight.current=true;setBusy(true);setError('');try{const result=await portalApi('commerce-submit',{...form,lines:lines.map(i=>({id:i.id,variant:i.variant,qty:i.qty}))},{},undefined,{'Idempotency-Key':requestKey.current});setReceipt(result.order);cart.clear();}catch(e){setError(e.message);}finally{inFlight.current=false;setBusy(false);}}
  if(receipt)return <main className="commerce-page"><section className="commerce-success"><I name="checkCircle" size={38}/><span className="eyebrow">REQUEST SAVED</span><h1>We have your request.</h1><p>Reference {receipt.id.slice(0,8).toUpperCase()}. It is attached to {receipt.account_email}. The studio will review the scope, availability and quote. No appointment is confirmed and no payment has been taken.</p><div className="commerce-notifications">{receipt.notifications.map(n=><p key={n.id}>{n.channel==='email'?'Email confirmation':'Text confirmation'}: {commerceStatus[n.status]||n.status}</p>)}</div><a className="btn btn-gold" href="/portal?tab=billing">View requests &amp; invoices <I name="arrow" size={15}/></a></section></main>;
  const selectedPackage=(window.PACKAGES||[]).find(p=>p.id===packageId);
  return <main className="commerce-page"><header><span className="eyebrow eyebrow-gold">BOOK WITH ELEVEN VIEWS</span><h1>The right service.<br/><em>A clear next step.</em></h1><p>Build a request around what you need. Your preferred timing is a request; the studio confirms the scope, schedule and price with you.</p>{selectedPackage&&<p className="commerce-hint">Package enquiry: <strong>{selectedPackage.name}</strong>. We’ve carried its details into your brief for review.</p>}{selectedPlan&&<p className="commerce-hint">Selected plan: <strong>{selectedPlan.name}</strong> at {selectedPlan.price}, plus approved advertising spend. We’ve carried it into your request for confirmation.</p>}</header>{!ready?<p role="status">Loading offerings and your account…</p>:<div className="commerce-layout"><form id="commerce-request" onSubmit={submit}>
    <section className="commerce-panel"><h2>1. Choose your services</h2><label htmlFor="booking-service">Add a service<select id="booking-service" value="" disabled={busy} onChange={e=>{const item=catalog.find(i=>i.id===e.target.value);if(item)cart.add({id:item.id,name:item.name,kind:'service',price:0,variant:'Quote required',qty:1});}}><option value="">Choose an offering</option>{catalog.filter(i=>i.kind==='service'&&!lines.some(l=>l.id===i.id)).map(i=><option key={i.id} value={i.id}>{i.name}</option>)}</select></label><p className="commerce-hint">Products already in your cart can be included in this request. Services are quoted after review.</p>
    {services.map(s=><fieldset key={s.id}><legend>{s.name}</legend>{s.questions.map((question,index)=><label key={question}>{question}<textarea rows={2} maxLength={2000} disabled={busy} value={form.answers[s.key]?.[index]||''} onChange={e=>{const value=e.target.value;setForm(f=>({...f,answers:{...f.answers,[s.key]:s.questions.map((_,j)=>j===index?value:f.answers[s.key]?.[j]||'')}}));}}/></label>)}</fieldset>)}</section>
    <section className="commerce-panel"><h2>2. Tell us about the work</h2><label>Your name<input required maxLength={120} autoComplete="name" disabled={busy} value={form.name} onChange={e=>update('name',e.target.value)}/></label><label>Company or project<input maxLength={160} disabled={busy} value={form.company} onChange={e=>update('company',e.target.value)}/></label><label>What would you like to accomplish?<textarea required minLength={10} maxLength={10000} rows={5} disabled={busy} value={form.brief} onChange={e=>update('brief',e.target.value)}/></label><div className="commerce-field-pair"><label>Preferred date (optional)<input type="date" min={new Date().toISOString().slice(0,10)} disabled={busy} value={form.preferredDate} onChange={e=>update('preferredDate',e.target.value)}/></label><label>Timing or budget notes<input maxLength={200} disabled={busy} value={form.timing} onChange={e=>update('timing',e.target.value)} placeholder="Flexible timing, launch date or budget range"/></label></div></section>
    <section className="commerce-panel"><h2>3. Confirm your account</h2>{user?<p>Requests and invoices will appear under <strong>{user.email}</strong> in your portal.</p>:<p><a href="/login">Sign in</a> or <a href="/register">create an account</a> before submitting. Your cart stays saved on this device. Complete the brief after you sign in.</p>}<label>Phone (optional)<input type="tel" autoComplete="tel" maxLength={30} disabled={busy} placeholder="+15551234567" value={form.phone} onChange={e=>update('phone',e.target.value)}/></label><label className="commerce-consent"><input type="checkbox" disabled={busy} checked={form.smsConsent} onChange={e=>update('smsConsent',e.target.checked)}/><span>Send transactional text updates for this request and its invoice to this number. Message and data rates may apply. Reply STOP to opt out. Consent is optional.</span></label><p className="commerce-hint">We’ll email a confirmation when notifications are enabled. Your portal shows the delivery status. Submitting does not book a time or authorize a charge.</p></section>
  </form><aside className="commerce-summary"><span className="eyebrow eyebrow-gold">FINAL REVIEW</span><h2>Your request</h2>{lines.length?lines.map(i=><div className="commerce-cart-line" key={`${i.id}-${i.variant}`}><div><strong>{i.name}</strong><small>{i.kind==='service'?`Service · ${i.qty}`:`${i.variant} · ${i.qty}`}</small><span>{i.kind==='service'?'Custom quote after scope review':commerceMoney(i.unitCents*i.qty)}</span></div><button type="button" disabled={busy} aria-label={`Remove ${i.name}`} onClick={()=>cart.remove(i.id,i.variant)}><I name="close" size={15}/></button></div>):<p>Choose a service above or add a product from the store.</p>}{invalid&&<p className="commerce-error">Some cart items are no longer offered here. Open your cart and remove them before submitting.</p>}{error&&<p className="commerce-error" role="alert">{error}</p>}<div className="commerce-total"><span>Product subtotal</span><strong>{productTotal?commerceMoney(productTotal):'No products selected'}</strong></div>{services.length>0&&<p className="commerce-quote-note"><strong>Service quote:</strong> confirmed after scope review. No $0 placeholder or service charge is added.</p>}<p className="commerce-hint">Shipping and applicable tax are confirmed in the invoice. Nothing is charged now.</p>{user?<button className="btn btn-gold commerce-submit" type="submit" form="commerce-request" disabled={busy||!lines.length||invalid}>{busy?'Saving request…':'Submit request'}<I name="arrow" size={15}/></button>:<a className="btn btn-gold commerce-submit" href="/login">Sign in to submit<I name="arrow" size={15}/></a>}<a href="/store">Browse products <I name="arrow" size={14}/></a></aside></div>}</main>;
}

function CommerceHistory({operator=false}){
  const [data,setData]=React.useState(null),[error,setError]=React.useState(''),[selected,setSelected]=React.useState(null),[busy,setBusy]=React.useState(false),[editing,setEditing]=React.useState(null),[description,setDescription]=React.useState(''),[amount,setAmount]=React.useState(''),[notes,setNotes]=React.useState('');
  const invoiceKey=React.useRef(crypto.randomUUID());
  const [confirming,setConfirming]=React.useState(null),[confirmedDate,setConfirmedDate]=React.useState('');
  async function confirmSchedule(e){e.preventDefault();if(busy)return;setBusy(true);setError('');try{await portalApi('commerce-confirm',{orderId:confirming.id,confirmedDate,notes},{},undefined,{'Idempotency-Key':`confirm-${confirming.id}`});setConfirming(null);await load();}catch(e){setError(e.message);}finally{setBusy(false);}}
  async function load(){setError('');try{setData(await portalApi('commerce-history'));}catch(e){setError(e.message);}}
  React.useEffect(()=>{load();},[]);
  async function issue(e){e.preventDefault();if(busy)return;setBusy(true);setError('');try{const cents=Math.round(Number(amount)*100);await portalApi('commerce-invoice-create',{orderId:editing.id,lines:[{description,amountCents:cents}],notes},{},undefined,{'Idempotency-Key':invoiceKey.current});setEditing(null);await load();}catch(e){setError(e.message);}finally{setBusy(false);}}
  return <section className="commerce-history"><header><div><span className="portal-kicker">YOUR ACCOUNT</span><h1>Requests &amp; invoices</h1><p>Saved requests and studio-issued invoices for your account email.</p></div><button className="portal-secondary" onClick={load}>Refresh <I name="refresh" size={14}/></button></header>{error&&<p role="alert" className="commerce-error">{error}</p>}{!data?<p>Opening your account records…</p>:<><h2>{operator?'Studio requests':'Your requests'}</h2>{!data.orders.length?<p>No requests yet. <a href="/booking">Start a service request</a>.</p>:data.orders.map(order=><article className="commerce-history-card" key={order.id}><header><div><span className="portal-kicker">{order.id.slice(0,8).toUpperCase()} / {order.status}</span><h3>{order.details.company||order.details.name}</h3><p>{order.account_email} · {new Date(order.created_at).toLocaleDateString()}</p></div>{operator&&!order.details.confirmedDate&&<button className="portal-secondary" onClick={()=>{setConfirming(order);setConfirmedDate(order.details.preferredDate||"");setNotes("");}}>Confirm schedule</button>}{operator&&!data.invoices.some(i=>i.order_id===order.id)&&<button className="portal-secondary" onClick={()=>{setEditing(order);setDescription(order.lines.map(l=>l.name).join(', '));setAmount('');setNotes('');invoiceKey.current=crypto.randomUUID();}}>Create invoice</button>}</header><ul>{order.lines.map(l=><li key={`${l.id}-${l.variant}`}>{l.name} · {l.variant} · {l.qty}{l.unitCents!==null?` · ${commerceMoney(l.unitCents*l.qty)}`:' · Quote required'}</li>)}</ul><p>{order.details.brief}</p>{order.details.preferredDate&&<p>Preferred date: {order.details.preferredDate} (not confirmed)</p>}{order.details.confirmedDate&&<p><strong>Confirmed date: {order.details.confirmedDate}</strong><br/>{order.details.confirmationNotes}</p>}{order.details.timing&&<p>Timing / budget: {order.details.timing}</p>}{Object.entries(order.details.answers||{}).map(([key,answers])=><p key={key}><strong>{key}:</strong> {answers.filter(Boolean).join(' / ')}</p>)}{order.notifications.map(n=><small key={n.id}>{n.channel}: {commerceStatus[n.status]||n.status}<br/></small>)}</article>)}<h2>Invoices</h2>{!data.invoices.length?<p>No invoices issued yet. Service requests are reviewed before an invoice is created.</p>:data.invoices.map(i=><article className="commerce-invoice-row" key={i.id}><div><strong>{i.number}</strong><small>{i.account_email} · {i.status}</small></div><span>{commerceMoney(i.total_cents)}</span><button className="portal-secondary" onClick={()=>setSelected(i)}>View invoice</button></article>)}</>}
  {confirming&&<div className="portal-modal-backdrop"><section className="portal-modal commerce-invoice-form" role="dialog" aria-modal="true" aria-label="Confirm schedule"><button className="portal-icon" onClick={()=>setConfirming(null)} aria-label="Close schedule form"><I name="close"/></button><h2>Confirm the schedule</h2><p>Confirm the agreed date, time, timezone and location with {confirming.account_email}. This records the studio’s confirmation and queues the account notification.</p><form onSubmit={confirmSchedule}><label>Confirmed date<input type="date" required min={new Date().toISOString().slice(0,10)} value={confirmedDate} onChange={e=>setConfirmedDate(e.target.value)}/></label><label>Time, timezone and location<textarea required maxLength={500} rows={4} value={notes} onChange={e=>setNotes(e.target.value)}/></label>{error&&<p className="commerce-error">{error}</p>}<button className="portal-primary" disabled={busy}>{busy?'Confirming…':'Confirm schedule'}</button></form></section></div>}
  {editing&&<div className="portal-modal-backdrop"><section className="portal-modal commerce-invoice-form" role="dialog" aria-modal="true" aria-label="Create invoice"><button className="portal-icon" onClick={()=>setEditing(null)} aria-label="Close invoice form"><I name="close"/></button><h2>Issue an invoice</h2><p>For {editing.account_email}. Confirm the agreed scope and full amount, including shipping and tax where applicable. Issued invoices are immutable.</p><form onSubmit={issue}><label>Description<input required maxLength={300} value={description} onChange={e=>setDescription(e.target.value)}/></label><label>Total (USD)<input required type="number" min="0.01" max="1000000" step="0.01" value={amount} onChange={e=>setAmount(e.target.value)}/></label><label>Scope and payment instructions<textarea required maxLength={3000} value={notes} onChange={e=>setNotes(e.target.value)} rows={5}/></label>{error&&<p className="commerce-error">{error}</p>}<button className="portal-primary" disabled={busy}>{busy?'Issuing…':'Issue invoice'}</button></form></section></div>}
  {selected&&<div className="portal-modal-backdrop commerce-invoice-backdrop"><article className="portal-modal commerce-invoice" role="dialog" aria-modal="true" aria-label={`Invoice ${selected.number}`}><div className="commerce-invoice-controls"><button className="portal-secondary" onClick={()=>window.print()}>Print / Save PDF</button><button className="portal-icon" onClick={()=>setSelected(null)} aria-label="Close invoice"><I name="close"/></button></div><span>ELEVEN VIEWS</span><h2>Invoice {selected.number}</h2><p>Issued {new Date(selected.issued_at).toLocaleDateString()}<br/>Billed to {selected.account_email}<br/>Status: {selected.status}</p><table><thead><tr><th>Description</th><th>USD</th></tr></thead><tbody>{selected.lines.map((l,i)=><tr key={i}><td>{l.description}</td><td>{commerceMoney(l.amountCents)}</td></tr>)}</tbody><tfoot><tr><th>Total</th><td>{commerceMoney(selected.total_cents)}</td></tr></tfoot></table><p className="commerce-invoice-notes">{selected.notes}</p><p>Payment status is recorded only after verification. This invoice is not a payment receipt.</p></article></div>}</section>;
}
window.BookingRequest=BookingRequest;
window.CommerceHistory=CommerceHistory;
