import { BOOT, canAction, allowedView } from './runtime';
import { useState, useEffect, useRef, useId, cloneElement, isValidElement, type ReactElement, type ReactNode, type FormEvent } from 'react';
import { LayoutDashboard, CalendarDays, Users, PawPrint, Scissors, Package, Stethoscope, ShoppingBag, Wallet, Bell, Settings, Search, Plus, ChevronDown, ChevronRight, ChevronLeft, ArrowUpRight, ArrowRight, X, Check, Clock3, MoreHorizontal, MessageCircle, Droplets, Syringe, Dog, Cat, CheckCircle2, AlertTriangle, Pencil, Download, Phone, Mail, MapPin, RefreshCw, Loader2, Menu, LogOut, Heart, Leaf, Sparkles, CreditCard, FileText, Filter, Copy, CircleHelp, ExternalLink, ShieldCheck, CircleArrowUp, CircleArrowDown } from 'lucide-react';
import { today, addDays, dateLabel, money, packageStatus, reminders, type State, type Pet, type Client, type Appointment, type Reminder, type Subscription, type Action } from './model';

type View='dashboard'|'agenda'|'clients'|'services'|'packages'|'clinic'|'products'|'finance'|'reminders'|'settings';
type Modal={type:string;data?:any}|null;
const nav=[{id:'dashboard',label:'Visão geral',icon:LayoutDashboard},{id:'agenda',label:'Agenda',icon:CalendarDays},{id:'clients',label:'Tutores e pets',icon:PawPrint},{id:'services',label:'Serviços',icon:Scissors},{id:'packages',label:'Pacotes',icon:Package},{id:'clinic',label:'Veterinária',icon:Stethoscope},{id:'products',label:'Produtos e estoque',icon:ShoppingBag},{id:'finance',label:'Financeiro',icon:Wallet}];
const titles:Record<View,string>={dashboard:'Visão geral',agenda:'Agenda',clients:'Tutores e pets',services:'Serviços',packages:'Pacotes de cuidado',clinic:'Clínica veterinária',products:'Produtos e estoque',finance:'Financeiro',reminders:'Central de lembretes',settings:'Configurações'};
const subtitles:Record<View,string>={dashboard:'Um olhar para o seu negócio. Mais tempo para cuidar.',agenda:'Cada cuidado tem seu horário. Organize todos por aqui.',clients:'Uma ficha completa para cada amizade de quatro patas.',services:'Do banho ao atendimento clínico, tudo do seu jeito.',packages:'Cuidados recorrentes, vínculos que duram.',clinic:'Histórico clínico, vacinas e próximos cuidados.',products:'Sua loja organizada, da prateleira ao caixa.',finance:'Entradas, saídas e o pulso do seu negócio.',reminders:'O próximo cuidado começa com uma boa conversa.',settings:'Deixe o AupetFlow com a cara do seu negócio.'};
function Badge({children,tone='neutral'}:{children:ReactNode;tone?:string}){return <span className={'badge '+tone}>{children}</span>}
function Status({status}:{status:string}){return <Badge tone={status==='Concluído'||status==='Ativo'?'green':status==='Confirmado'?'blue':status==='Em atendimento'?'purple':status==='Vencido'||status==='Esgotado'?'red':status==='Agendado'||status==='A vencer'?'amber':'neutral'}><i/>{status}</Badge>}
function Empty({icon:Icon=PawPrint,title,description,action}:{icon?:any;title:string;description:string;action?:ReactNode}){return <div className="empty"><span><Icon size={28}/></span><h3>{title}</h3><p>{description}</p>{action}</div>}
function PetAvatar({pet,size=42}:{pet?:Pet;size?:number}){const colors=[['#f2e5d2','#cda275','#f8eddd'],['#e5e9f4','#8d93ad','#f6f4fa'],['#f3e1dd','#bf8c7c','#fff3e9'],['#e8e8da','#a6a073','#faf8e8'],['#e8dded','#b18eae','#faf0f9']];const c=colors[(pet?.color||0)%5];const cat=pet?.species==='Gato';return <span className="pet-avatar" style={{width:size,height:size,background:c[0]}}><svg viewBox="0 0 64 64" aria-hidden="true">{cat?<><path d="M15 32 11 10 29 21 39 21 54 10 50 35" fill={c[1]}/><path d="m17 26-2-10 9 8m20 1 7-9-1 11" fill="#e9b5ab"/></>:<><path d="M20 18C6 8 1 41 16 45l9-19m19-8c14-10 19 23 4 27l-9-19" fill={c[1]}/></>}<ellipse cx="33" cy="35" rx="21" ry="23" fill={c[2]}/>{!cat&&<path d="M15 23c1-10 10-13 16-10-6 3-5 14-13 19" fill={c[1]}/>}<circle cx="25" cy="32" r="2" fill="#283c35"/><circle cx="42" cy="32" r="2" fill="#283c35"/><ellipse cx="33" cy="41" rx="9" ry="8" fill="#fff"/><path d="M29 38q4-3 8 0-1 5-4 5t-4-5" fill="#31433d"/><path d="M33 43v3m0 0q-5 3-7-1m7 1q5 3 7-1" fill="none" stroke="#31433d" strokeWidth="1.7" strokeLinecap="round"/>{cat&&<path d="m20 40-12-2m12 7L9 48m37-8 12-2M46 45l11 3" stroke={c[1]} strokeWidth="1.5"/>}</svg></span>}
function WelcomeArt(){return <svg viewBox="0 0 290 145" className="welcome-art" aria-hidden="true"><circle cx="168" cy="87" r="94" fill="#e1eed7"/><path d="M258 127c-5-24 10-34 18-42-1 22-4 33-18 42m-3 3c-20-5-25-18-28-27 20 3 29 10 28 27" fill="#a7c987"/><path d="M74 145V87c0-34 19-51 47-51s45 22 45 51v58" fill="#ceb38c"/><path d="M85 57c-34-10-36 65-17 65 16 0 28-30 17-65m65 2c31-13 33 63 15 65-17 1-25-32-15-65" fill="#ad8b63"/><ellipse cx="121" cy="93" rx="32" ry="34" fill="#ecdbbf"/><circle cx="108" cy="83" r="3" fill="#264539"/><circle cx="136" cy="83" r="3" fill="#264539"/><ellipse cx="121" cy="106" rx="17" ry="14" fill="#fff3df"/><path d="M112 99q9-5 18 0-2 10-9 10t-9-10" fill="#264539"/><path d="M121 108v8m0 0q-8 6-14-1m14 1q8 6 14-1" fill="none" stroke="#264539" strokeWidth="2" strokeLinecap="round"/><path d="M176 145V99l-5-29 23 13q12-4 23 0l23-13-4 29v46" fill="#fdf8e9"/><path d="m179 88-3-11 14 9m31 0 13-9-2 11" fill="#e6bfb0"/><path d="M190 111q4-5 8 0m18 0q4-5 8 0" stroke="#365543" strokeWidth="2.5" strokeLinecap="round" fill="none"/><path d="m204 118 6 0-3 5z" fill="#c28f80"/><path d="M207 122v5m0 0q-8 5-11-1m11 1q8 5 11-1" stroke="#365543" strokeWidth="1.8" strokeLinecap="round" fill="none"/><path d="m188 119-15-3m15 9-16 2m54-8 16-3m-16 9 16 2" stroke="#c6bca5" strokeWidth="1.5"/><path d="M50 28c-12-15-27 4-1 21C77 35 62 15 50 28" fill="#9cbe7e"/><path d="m248 43 3 7 7 3-7 3-3 7-3-7-7-3 7-3z" fill="#a9c888"/></svg>}
function Field({label,children,hint,wide=false}:{label:string;children:ReactNode;hint?:string;wide?:boolean}){const fieldId=useId();const direct=isValidElement(children)&&typeof children.type==='string'&&['input','select','textarea'].includes(children.type);return <div className={'field '+(wide?'wide':'')} role={direct?undefined:'group'} aria-labelledby={direct?undefined:fieldId}><label id={direct?undefined:fieldId} htmlFor={direct?fieldId:undefined}>{label}</label>{direct?cloneElement(children as ReactElement<any>,{id:fieldId,'aria-describedby':hint?fieldId+'-hint':undefined}):children}{hint&&<small id={fieldId+'-hint'}>{hint}</small>}</div>}
function Input({name,label,defaultValue='',type='text',required=false,hint,wide=false,...props}:any){return <Field label={label} hint={hint} wide={wide}><input name={name} type={type} defaultValue={defaultValue} required={required} {...props}/></Field>}
function Textarea({name,label,defaultValue='',...props}:any){return <Field label={label} wide><textarea name={name} defaultValue={defaultValue} rows={3} {...props}/></Field>}
function Select({name,label,defaultValue='',children,required=false,...props}:any){return <Field label={label}><select name={name} {...(props.value!==undefined?{}:{defaultValue})} required={required} {...props}>{children}</select></Field>}
function Checked({name,defaultChecked=false,children,value='on'}:any){return <label className="check"><input type="checkbox" name={name} defaultChecked={defaultChecked} value={value}/><span>{children}</span></label>}
function Form({children,onSubmit,busy,label='Salvar'}:{children:ReactNode;onSubmit:(f:FormData)=>void;busy:boolean;label?:string}){return <form onSubmit={e=>{e.preventDefault();onSubmit(new FormData(e.currentTarget))}}><div className="form-grid">{children}</div><footer className="form-footer"><span><ShieldCheck size={14}/> Dados salvos com segurança</span><button type="submit" className="btn primary" disabled={busy}>{busy?<Loader2 className="spin" size={17}/>:<Check size={17}/>} {label}</button></footer></form>}
function payload(f:FormData){return Object.fromEntries(f.entries()) as Record<string,any>}
function csv(rows:any[],name:string){if(!rows.length)return;const keys=Object.keys(rows[0]);const val=(v:any)=>'"'+String(Array.isArray(v)?v.join(', '):v??'').replaceAll('"','""').replace(/^[=+\-@]/,"'$&")+'"';download('\ufeff'+[keys.map(val).join(';'),...rows.map(r=>keys.map(k=>val(r[k])).join(';'))].join('\r\n'),name,'text/csv;charset=utf-8');}
function download(data:string,name:string,type='application/json'){const url=URL.createObjectURL(new Blob([data],{type}));const a=document.createElement('a');a.href=url;a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000)}

export default function PetApp({userName}:{userName:string}){
 const [state,setState]=useState<State|null>(null),[revision,setRevision]=useState(0),[view,setView]=useState<View>('dashboard'),[busy,setBusy]=useState(false),[error,setError]=useState(''),[toast,setToast]=useState(''),[modal,setModal]=useState<Modal>(null),[search,setSearch]=useState(''),[mobile,setMobile]=useState(false);
 const [selectedDate,setSelectedDate]=useState(today()),[category,setCategory]=useState('Todos'),[clientTab,setClientTab]=useState('Pets'),[listSearch,setListSearch]=useState(''),[filter,setFilter]=useState('Todos'),[packageTab,setPackageTab]=useState('Contratados'),[financeMonth,setFinanceMonth]=useState(today().slice(0,7));
 const [profile,setProfile]=useState<{clientId:string;petId:string;tab:string}|null>(null),[schedulePet,setSchedulePet]=useState(''),[scheduleService,setScheduleService]=useState(''),[schedulePackage,setSchedulePackage]=useState(''),[clinicPet,setClinicPet]=useState(''),[reminderType,setReminderType]=useState('Todos');
 const [scheduleDate,setScheduleDate]=useState(today()),[stockProduct,setStockProduct]=useState(''),[stockKind,setStockKind]=useState('Entrada');
 const dialogRef=useRef<HTMLDivElement>(null),focusBefore=useRef<HTMLElement|null>(null),saving=useRef(false);
 async function load(){setError('');try{const r=await fetch('api.php',{cache:'no-store',headers:{'X-Store-ID':BOOT.storeId}}),d=await r.json() as any;if(!r.ok)throw new Error(d.error);setState(d.state);setRevision(d.revision);}catch(e){setError(e instanceof Error?e.message:'Erro ao carregar.')}}
 useEffect(()=>{load()},[]);
 useEffect(()=>{if(!toast)return;const t=setTimeout(()=>setToast(''),5000);return()=>clearTimeout(t)},[toast]);
 useEffect(()=>{if(!modal&&!profile)return;focusBefore.current=document.activeElement as HTMLElement;const first=dialogRef.current?.querySelector<HTMLElement>('input,select,textarea,button');first?.focus();const previous=document.body.style.overflow;document.body.style.overflow='hidden';const handler=(e:KeyboardEvent)=>{if(e.key==='Escape'&&!saving.current){setModal(null);setProfile(null);}if(e.key==='Tab'&&dialogRef.current){const all=Array.from(dialogRef.current.querySelectorAll<HTMLElement>('button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex="0"]'));if(!all.length)return;const first=all[0],last=all[all.length-1];if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus()}else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus()}}};document.addEventListener('keydown',handler);return()=>{document.body.style.overflow=previous;document.removeEventListener('keydown',handler);focusBefore.current?.focus()}},[modal?.type,modal?.data?.id,!!profile]);
 function go(v:View){if(!allowedView(v))return;setView(v);setMobile(false);setSearch('');setListSearch('');setFilter('Todos');setCategory('Todos');}
 async function act(action:Action,message='Alteração salva.',close=true){if(saving.current)return false;saving.current=true;setBusy(true);setError('');try{const r=await fetch('api.php',{method:'POST',headers:{'Content-Type':'application/json','X-CSRF-Token':BOOT.csrf,'X-Store-ID':BOOT.storeId},body:JSON.stringify({revision,action})}),d=await r.json() as any;if(d.loginRequired){window.location.href='index.php?p=login';return false;}if(d.passwordChangeRequired){window.location.href='index.php?p=password';return false;}if(d.state){setState(d.state);setRevision(d.revision)}if(!r.ok)throw new Error(d.error||'Não foi possível salvar.');setToast(message);if(close){if(action.type==='saveClient'&&!action.data?.id)setModal({type:'pet',data:{clientId:d.state.clients.at(-1).id}});else setModal(null);}return true;}catch(e){setError(e instanceof Error?e.message:'Não foi possível salvar.');return false;}finally{setBusy(false);saving.current=false}}
 function open(type:string,data?:any){const permissions:Record<string,string>={client:'saveClient',pet:'savePet',service:'saveService',template:'saveTemplate',subscribe:'subscribe',appointment:'saveAppointment',consultation:'addConsultation',vaccine:'addVaccine',product:'saveProduct',stock:'stockMove',transaction:'addTransaction',startReal:'startReal'};if(permissions[type]&&!canAction(permissions[type])){setToast('Seu perfil não permite esta operação.');return;}setError('');setModal({type,data});if(type==='stock'){setStockProduct(data?.productId||'');setStockKind(data?.kind||'Entrada')}if(type==='appointment'){setScheduleDate(data?.date||(view==='agenda'?selectedDate:today()));setSchedulePet(data?.petId||'');setScheduleService(data?.serviceId||state?.services.find(x=>x.active&&(data?.category?x.category===data.category:true))?.id||'');setSchedulePackage(data?.packageId||'')}}
 function openProfile(p:Pet,tab='Visão geral'){setProfile({clientId:p.clientId,petId:p.id,tab});setSearch('')}
 if(!state)return <div className="loading-screen"><div className="loading-logo"><PawPrint size={30}/><strong>Aupet<span>Flow</span></strong></div>{error?<><p>{error}</p><button className="btn primary" onClick={load}><RefreshCw size={17}/> Tentar novamente</button><a href="index.php?p=login" target="_top">Entrar na conta</a></>:<><Loader2 size={25} className="spin"/><p>Preparando o próximo cuidado...</p></>}</div>;
 const s=state,d=today(),petBy=(id:string)=>s.pets.find(p=>p.id===id),clientBy=(id:string)=>s.clients.find(c=>c.id===id),owner=(pet?:Pet)=>clientBy(pet?.clientId||''),rs=reminders(s),pkgReminders=rs.filter(x=>x.type==='package'),lowStock=s.products.filter(x=>x.stock<=x.minStock),dayAppointments=s.appointments.filter(x=>x.date===d&&x.status!=='Cancelado'),activePkgs=s.subscriptions.filter(x=>!x.archived&&x.expiresAt>=d&&x.used<x.total),monthTransactions=s.transactions.filter(x=>x.date.startsWith(financeMonth)||x.paidDate?.startsWith(financeMonth)),monthIncome=s.transactions.filter(x=>x.paid&&x.type==='income'&&(x.paidDate||x.date).startsWith(financeMonth)).reduce((t,x)=>t+x.amount,0),monthExpense=s.transactions.filter(x=>x.paid&&x.type==='expense'&&(x.paidDate||x.date).startsWith(financeMonth)).reduce((t,x)=>t+x.amount,0);
 const selectedPet=profile?petBy(profile.petId):undefined,selectedClient=profile?clientBy(profile.clientId):undefined;
 const brandName=s.settings.businessName;
 function WhatsApp({reminder,small=false}:{reminder:Reminder;small?:boolean}){return <button className={'btn '+(small?'compact ghost':'whatsapp')} onClick={()=>open('whatsapp',reminder)} aria-label={'Preparar mensagem para '+petBy(reminder.petId)?.name}><MessageCircle size={16}/>{!small&&'WhatsApp'}</button>}
 function AppointmentTable({rows,compact=false}:{rows:Appointment[];compact?:boolean}){return rows.length?<div className="table-scroll"><table className={'appointments-table '+(compact?'compact-table':'')}><thead><tr><th>Horário</th><th>Pet / Tutor</th><th>Serviço</th>{!compact&&<th>Profissional</th>}<th>Status</th><th><span className="sr-only">Ações</span></th></tr></thead><tbody>{rows.map(a=>{const p=petBy(a.petId);return <tr key={a.id}><td><strong className="time">{a.time}</strong><small>{a.duration} min</small></td><td><button className="pet-cell" onClick={()=>p&&openProfile(p)}><PetAvatar pet={p}/><span><strong>{p?.name||'Pet'}</strong><small>{owner(p)?.name}</small></span></button></td><td><span className="service-name">{a.category==='Clínica'?<Stethoscope size={14}/>:<Droplets size={14}/>} {a.serviceName}</span>{a.packageId&&<small className="package-hint"><Package size={11}/> No pacote</small>}</td>{!compact&&<td className="muted">{a.professional}</td>}<td><Status status={a.status}/></td><td><button className="icon-button" aria-label={'Detalhes do atendimento de '+p?.name} onClick={()=>open('appointmentDetail',a)}><MoreHorizontal size={19}/></button></td></tr>})}</tbody></table></div>:<Empty icon={CalendarDays} title="Uma agenda pronta para receber" description="Cadastre um pet e reserve o próximo horário de cuidado." action={<button className="btn primary" onClick={()=>open('appointment')}><Plus size={16}/> Novo agendamento</button>}/>}
 function ReminderRow({r}:{r:Reminder}){const p=petBy(r.petId),contact=s.contacts.filter(c=>c.refId===r.refId).at(-1);return <div className="reminder-row"><span className={'reminder-icon '+(r.urgent?'peach':'sage')}>{r.type==='package'?<Package size={19}/>:r.type==='vaccine'?<Syringe size={19}/>:<CalendarDays size={19}/>}</span><div className="reminder-text"><strong>{r.title}</strong><span>{p?.name} <b>·</b> {owner(p)?.name.split(' ').slice(0,2).join(' ')}</span><small>{r.detail}</small>{contact&&<small className="green-text">Contato registrado em {dateLabel(contact.date)}</small>}</div><WhatsApp reminder={r} small/></div>}
 function Stat({icon:Icon,label,value,sub,tone='green',action}:{icon:any;label:string;value:ReactNode;sub:ReactNode;tone?:string;action?:()=>void}){return <button className={'stat-card '+tone} onClick={action}><div className="stat-head"><span>{label}</span><Icon size={19}/></div><strong className="stat-value">{value}</strong><span className="stat-sub">{sub}</span></button>}
 function petOptions(){return <><option value="">Selecione o pet</option>{s.pets.map(p=><option key={p.id} value={p.id}>{p.name} — {owner(p)?.name}</option>)}</>}
 function clientOptions(){return <><option value="">Selecione o tutor</option>{s.clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}</>}
 function professionals(){return s.settings.professionals.split(',').map(x=>x.trim()).filter(Boolean)}
 function HeaderAction(){if(view==='clients'&&!canAction('saveClient')||view==='services'&&!canAction('saveService')||view==='packages'&&!canAction(packageTab==='Modelos'?'saveTemplate':'subscribe'))return null;switch(view){case'clients':return <button className="btn primary" onClick={()=>open('client')}><Plus size={17}/> Novo tutor</button>;case'services':return <button className="btn primary" onClick={()=>open('service')}><Plus size={17}/> Novo serviço</button>;case'packages':return <button className="btn primary" onClick={()=>open(packageTab==='Modelos'?'template':'subscribe')}><Plus size={17}/> {packageTab==='Modelos'?'Criar pacote':'Contratar pacote'}</button>;case'clinic':return <button className="btn primary" onClick={()=>open('consultation',{petId:clinicPet})}><Plus size={17}/> Registro clínico</button>;case'products':return <button className="btn primary" onClick={()=>open('product')}><Plus size={17}/> Novo produto</button>;case'finance':return <button className="btn primary" onClick={()=>open('transaction')}><Plus size={17}/> Novo lançamento</button>;case'settings':return null;case'reminders':return <button className="btn outline" onClick={()=>open('help')}><CircleHelp size={17}/> Como funciona</button>;default:return <button className="btn primary" onClick={()=>open('appointment')}><Plus size={17}/> Novo agendamento</button>}}
 const searchResults=search.trim().length>0?[...s.pets.filter(p=>(p.name+' '+p.breed+' '+owner(p)?.name).toLowerCase().includes(search.toLowerCase())).map(p=>({id:p.id,label:p.name,sub:p.breed+' · '+owner(p)?.name,pet:p,kind:'pet'})),...s.clients.filter(c=>c.name.toLowerCase().includes(search.toLowerCase())).map(c=>({id:c.id,label:c.name,sub:'Tutor · '+s.pets.filter(p=>p.clientId===c.id).length+' pets',client:c,kind:'client'})),...s.products.filter(p=>(p.name+' '+p.sku).toLowerCase().includes(search.toLowerCase())).map(p=>({id:p.id,label:p.name,sub:'Produto · '+p.sku,product:p,kind:'product'}))].slice(0,8):[];
 return <div className="app-shell">
 <aside className={'sidebar '+(mobile?'mobile-open':'')}>
 <a href="#" className="brand" onClick={e=>{e.preventDefault();go('dashboard')}}><span className="brand-icon"><PawPrint size={27} strokeWidth={2.2}/></span><span>Aupet<span className="brand-flow">Flow</span><small>GESTÃO QUE CUIDA</small></span></a>
 <div className="workspace-card"><span className="workspace-avatar"><ShoppingBag size={18}/></span><span><strong>{BOOT.accountName}</strong><small>{BOOT.storeName}</small></span><button className="icon-button" aria-label="Trocar loja" onClick={()=>{window.location.href='index.php?p=stores'}}><ChevronDown size={15}/></button></div>
 <p className="nav-label">SEU NEGÓCIO</p>
 <nav>{nav.filter(n=>allowedView(n.id)).map(n=><button key={n.id} className={'nav-item '+(view===n.id?'active':'')} onClick={()=>go(n.id as View)}><n.icon size={19}/><span>{n.label}</span>{n.id==='agenda'&&dayAppointments.length>0&&<b>{dayAppointments.length}</b>}{n.id==='products'&&lowStock.length>0&&<i className="nav-dot"/>}</button>)}</nav>
 <div className="sidebar-bottom"><p className="nav-label">ORGANIZAÇÃO</p>{BOOT.isMaster&&<a className="nav-item" href="index.php?p=master"><ShieldCheck size={19}/><span>Painel master</span></a>}{BOOT.isOwner&&<a className="nav-item" href="index.php?p=account"><Users size={19}/><span>Lojas e equipe</span></a>}<a className="nav-item" href="index.php?p=stores"><ShoppingBag size={19}/><span>Trocar loja</span></a><button hidden={!allowedView('reminders')} className={'nav-item '+(view==='reminders'?'active':'')} onClick={()=>go('reminders')}><Bell size={19}/><span>Lembretes</span>{rs.length>0&&<b className="amber-count">{rs.length}</b>}</button><button hidden={!allowedView('settings')} className={'nav-item '+(view==='settings'?'active':'')} onClick={()=>go('settings')}><Settings size={19}/><span>Configurações</span></button><div className="care-note"><span><Heart size={16}/></span><p>Mais gestão.<br/><strong>Mais tempo para cuidar.</strong></p><PawPrint size={37}/></div><button className="user-profile" onClick={()=>go('settings')}><span className="user-avatar">{userName.slice(0,1).toUpperCase()}</span><span><strong>{userName}</strong><small>{BOOT.roleLabel}</small></span><Settings size={16}/></button></div>
 </aside>
 {mobile&&<div className="mobile-shade" onClick={()=>setMobile(false)}/>}
 <div className="main-shell"><header className="topbar"><button className="icon-button mobile-toggle" aria-label="Abrir menu" onClick={()=>setMobile(true)}><Menu size={22}/></button><div className="breadcrumb">{BOOT.storeName} <ChevronRight size={13}/><strong>{titles[view]}</strong></div><div className="global-search"><Search size={17}/><input aria-label="Buscar pets, tutores ou produtos" placeholder="Buscar pet, tutor ou produto..." value={search} onChange={e=>setSearch(e.target.value)} onKeyDown={e=>{if(e.key==='Escape')setSearch('')}}/><span className="search-key">⌕</span>{search&&<div className="search-results"><div className="search-results-head">Resultados <button className="icon-button" onClick={()=>setSearch('')} aria-label="Fechar busca"><X size={15}/></button></div>{searchResults.length?searchResults.map((r:any)=><button key={r.kind+r.id} onClick={()=>{if(r.pet)openProfile(r.pet);else if(r.client){const p=s.pets.find(x=>x.clientId===r.client.id);p?openProfile(p):open('client',r.client)}else{go('products');setListSearch(r.label)}setSearch('')}}>{r.pet?<PetAvatar pet={r.pet} size={34}/>:r.product?<ShoppingBag size={20}/>:<Users size={20}/>}<span><strong>{r.label}</strong><small>{r.sub}</small></span><ArrowUpRight size={15}/></button>):<p>Nenhum resultado encontrado.</p>}</div>}</div><div className="top-actions"><span className="cloud-status"><i/> Dados sincronizados</span><button className="notification-button" aria-label={`${rs.length} lembretes`} onClick={()=>go('reminders')}><Bell size={20}/>{rs.length>0&&<i/>}</button><span className="top-avatar">{userName.slice(0,1).toUpperCase()}</span></div></header>
 <main>
{BOOT.isMaster&&<div className="demo-banner"><span><ShieldCheck size={15}/> Acesso master · {BOOT.accountName} / {BOOT.storeName}</span><a href="index.php?p=master">Voltar ao painel master →</a></div>}
 {s.demo&&<div className="demo-banner"><span><Sparkles size={15}/> Você está explorando dados de demonstração.</span><button onClick={()=>open('startReal')}>Começar com meus dados <ArrowRight size={14}/></button></div>}
 <div className="page-heading"><div><p className="eyebrow">{view==='dashboard'?'SEU NEGÓCIO EM BOAS MÃOS':'AUPETFLOW · GESTÃO INTEGRADA'}</p><h1>{titles[view]}</h1><p>{subtitles[view]}</p></div><div className="heading-actions">{view==='dashboard'&&<span className="date-chip"><CalendarDays size={15}/>{dateLabel(d,{day:'2-digit',month:'short'})}</span>}<HeaderAction/></div></div>
 {error&&!modal&&<div className="inline-error" role="alert"><AlertTriangle size={18}/>{error}<button onClick={()=>setError('')} aria-label="Fechar aviso"><X size={16}/></button></div>}
 {view==='dashboard'&&<>
 <section className="welcome-card"><div><span className="welcome-tag"><span/> Tudo começa com um bom cuidado</span><h2>Uma rotina leve.<br/>Um petshop cheio de vida.</h2><p>Agenda organizada, pets felizes e seu negócio fluindo.</p><button onClick={()=>go('agenda')}>Vamos para a agenda <ArrowRight size={16}/></button></div><WelcomeArt/></section>
 <section className="stats-grid"><Stat icon={CalendarDays} label="Agendamentos hoje" value={dayAppointments.length} sub={<><b>{dayAppointments.filter(a=>a.status==='Concluído').length} concluídos</b><span> · </span>{dayAppointments.filter(a=>a.status==='Em atendimento').length} em atendimento</>} action={()=>go('agenda')}/>{!allowedView('finance')?<Stat icon={Users} label="Tutores cadastrados" value={s.clients.length} sub="Contatos para manter os cuidados em dia" tone="cream" action={()=>go('clients')}/>:<Stat icon={Wallet} label="Recebido neste mês" value={money(s.transactions.filter(t=>t.type==='income'&&t.paid&&(t.paidDate||t.date).startsWith(d.slice(0,7))).reduce((v,t)=>v+t.amount,0))} sub={<>Recebimentos confirmados <ArrowUpRight size={13}/></>} tone="cream" action={()=>go('finance')}/> }<Stat icon={Package} label="Pacotes ativos" value={activePkgs.length} sub={<>{pkgReminders.length>0?<><b className="amber-text">{pkgReminders.length} precisam de atenção</b></>:'Todos os pacotes em dia'}</>} tone="lavender" action={()=>go('packages')}/><Stat icon={PawPrint} label="Pets cadastrados" value={s.pets.length} sub={<><b>{s.clients.length} tutores</b> fazendo parte da família</>} tone="pink" action={()=>go('clients')}/></section>
 <div className="dashboard-columns"><section className="panel agenda-panel"><div className="panel-header"><div><h2><CalendarDays size={19}/> Agenda de hoje <span className="count-pill">{dayAppointments.length}</span></h2><p>{dateLabel(d,{weekday:'long',day:'numeric',month:'long'})}</p></div><button className="text-link" onClick={()=>{setSelectedDate(d);go('agenda')}}>Ver agenda <ArrowUpRight size={15}/></button></div><div className="tab-row agenda-tabs">{['Todos','Banho e tosa','Clínica'].map(c=><button key={c} className={category===c?'selected':''} onClick={()=>setCategory(c)}>{c}{c==='Todos'&&<span>{dayAppointments.length}</span>}</button>)}</div><AppointmentTable compact rows={dayAppointments.filter(x=>category==='Todos'||x.category===category).sort((a,b)=>a.time.localeCompare(b.time)).slice(0,6)}/><div className="panel-footer"><span><i className="live-dot"/> Cada atendimento, um cuidado especial.</span><button className="text-link" onClick={()=>open('appointment')}>Agendar <Plus size={14}/></button></div></section>
 <section className="panel reminders-panel"><div className="panel-header"><div><h2><Bell size={19}/> De olho nos cuidados</h2><p>Pequenos lembretes, grandes vínculos.</p></div>{rs.filter(r=>r.urgent).length>0&&<Badge tone="amber">{rs.filter(r=>r.urgent).length}</Badge>}</div>{rs.length?rs.slice(0,4).map(r=><ReminderRow r={r} key={r.id}/>):<Empty title="Tudo em dia por aqui" description="Seus próximos lembretes aparecerão aqui." icon={CheckCircle2}/>}<button className="all-reminders" onClick={()=>go('reminders')}>Ver todos os lembretes <ArrowRight size={15}/></button><div className="whatsapp-note"><MessageCircle size={19}/><p>Um toque de carinho faz a diferença.<small>Prepare uma mensagem e fale com o tutor.</small></p></div></section></div>
 <section className="quick-section"><div className="section-title"><h2>Seu próximo passo, a um clique</h2><span>Mais facilidade no dia a dia</span></div><div className="quick-grid">{[{title:'Novo tutor e pet',sub:'Uma nova amizade começa aqui',icon:PawPrint,type:'client'},{title:'Contratar um pacote',sub:'Cuidado contínuo para cada pet',icon:Package,type:'subscribe'},{title:'Registrar uma vacina',sub:'Proteção que fica no histórico',icon:Syringe,type:'vaccine'},{title:'Registrar uma venda',sub:'Estoque e caixa sempre juntos',icon:ShoppingBag,type:'stock',data:{kind:'Venda'}}].filter(q=>canAction(({client:'saveClient',subscribe:'subscribe',vaccine:'addVaccine',stock:'stockMove'} as Record<string,string>)[q.type])).map(q=><button key={q.title} className="quick-card" onClick={()=>open(q.type,q.data)}><span><q.icon size={21}/></span><div><strong>{q.title}</strong><small>{q.sub}</small></div><ChevronRight size={16}/></button>)}</div></section>
 </>}
 {view==='agenda'&&<>
 <section className="panel"><div className="agenda-toolbar"><div className="date-navigation"><button className="icon-button" aria-label="Dia anterior" onClick={()=>setSelectedDate(addDays(selectedDate,-1))}><ChevronLeft size={19}/></button><h2>{dateLabel(selectedDate,{day:'numeric',month:'long',year:'numeric'})}</h2><button className="icon-button" aria-label="Próximo dia" onClick={()=>setSelectedDate(addDays(selectedDate,1))}><ChevronRight size={19}/></button><button className="btn compact outline" onClick={()=>setSelectedDate(d)}>Hoje</button></div><div className="toolbar-right"><input type="date" aria-label="Escolher dia da agenda" value={selectedDate} onChange={e=>e.target.value&&setSelectedDate(e.target.value)}/><select aria-label="Filtrar tipo de atendimento" value={category} onChange={e=>setCategory(e.target.value)}>{['Todos','Banho e tosa','Clínica'].map(c=><option key={c}>{c}</option>)}</select></div></div>
 <div className="week-strip">{Array.from({length:7},(_,i)=>addDays(selectedDate,i-3)).map(date=>{const count=s.appointments.filter(x=>x.date===date&&x.status!=='Cancelado').length;return <button key={date} className={date===selectedDate?'chosen':''} onClick={()=>setSelectedDate(date)}><small>{dateLabel(date,{weekday:'short'})}</small><strong>{date.slice(-2)}</strong><span>{count?`${count} ${count===1?'horário':'horários'}`:'Livre'}</span>{date===d&&<i/>}</button>})}</div>
 <AppointmentTable rows={s.appointments.filter(x=>x.date===selectedDate&&(category==='Todos'||x.category===category)).sort((a,b)=>a.time.localeCompare(b.time))}/>
 <div className="panel-footer"><span>{s.appointments.filter(x=>x.date===selectedDate&&x.status==='Concluído').length} atendimentos concluídos</span><button className="text-link" onClick={()=>csv(s.appointments.filter(x=>x.date===selectedDate).map(a=>({data:a.date,horario:a.time,pet:petBy(a.petId)?.name,tutor:owner(petBy(a.petId))?.name,servico:a.serviceName,profissional:a.professional,status:a.status})),`agenda-${selectedDate}.csv`)}><Download size={14}/> Exportar dia</button></div></section>
 <div className="info-strip"><Clock3 size={19}/><p>Ao concluir um atendimento, o histórico do pet é atualizado. Banhos no pacote consomem uma sessão; serviços avulsos geram um lançamento no financeiro.</p></div>
 </>}
 {view==='clients'&&<>
 <div className="list-toolbar"><div className="segmented">{['Pets','Tutores'].map(t=><button key={t} className={clientTab===t?'selected':''} onClick={()=>setClientTab(t)}>{t} <span>{t==='Pets'?s.pets.length:s.clients.length}</span></button>)}</div><div className="toolbar-right"><div className="local-search"><Search size={16}/><input aria-label="Buscar na lista de clientes" placeholder="Buscar por nome ou raça" value={listSearch} onChange={e=>setListSearch(e.target.value)}/></div>{clientTab==='Pets'&&<button className="btn outline" onClick={()=>open('pet')}><Plus size={16}/> Novo pet</button>}</div></div>
 {clientTab==='Pets'?<div className="pet-grid">{s.pets.filter(p=>(p.name+' '+p.breed+' '+owner(p)?.name).toLowerCase().includes(listSearch.toLowerCase())).map(p=>{const sub=s.subscriptions.find(x=>x.petId===p.id&&!x.archived);return <button className="pet-card" key={p.id} onClick={()=>openProfile(p)}><div className="pet-card-top"><PetAvatar pet={p} size={68}/><span className="pet-species">{p.species==='Gato'?<Cat size={16}/>:<Dog size={16}/>} {p.species}</span><ArrowUpRight size={18}/></div><h2>{p.name}</h2><p>{p.breed||'Raça não informada'} <b>·</b> {p.size}</p><div className="pet-owner"><Users size={15}/>{owner(p)?.name}</div><div className="pet-card-footer">{sub?<Badge tone={['Vencido','Esgotado'].includes(packageStatus(sub))?'amber':'green'}><Package size={12}/> {sub.name}</Badge>:<span>Carinho em cada atendimento</span>}{p.alerts&&<AlertTriangle size={16} className="amber-text" aria-label="Pet possui observações"/>}</div></button>})}{!s.pets.length&&<div className="panel wide-empty"><Empty title="Vamos conhecer o primeiro pet?" description="Comece pelo tutor e depois adicione os pets à ficha." action={<button className="btn primary" onClick={()=>open('client')}><Plus size={16}/> Cadastrar tutor</button>}/></div>}</div>:<section className="panel"><div className="table-scroll"><table><thead><tr><th>Tutor</th><th>WhatsApp</th><th>Pets</th><th>E-mail</th><th/></tr></thead><tbody>{s.clients.filter(c=>c.name.toLowerCase().includes(listSearch.toLowerCase())).map(c=><tr key={c.id}><td><button className="name-button" onClick={()=>{const p=s.pets.find(x=>x.clientId===c.id);p?openProfile(p):open('client',c)}}><span className="initial-avatar">{c.name[0]}</span><strong>{c.name}</strong></button></td><td>{c.phone||<span className="muted">Não cadastrado</span>}</td><td><div className="pet-tags">{s.pets.filter(p=>p.clientId===c.id).map(p=><button key={p.id} onClick={()=>openProfile(p)}>{p.name}</button>)}<button aria-label={'Adicionar pet para '+c.name} onClick={()=>open('pet',{clientId:c.id})}><Plus size={13}/></button></div></td><td className="muted">{c.email||'—'}</td><td><button className="icon-button" aria-label={'Editar tutor '+c.name} onClick={()=>open('client',c)}><Pencil size={16}/></button></td></tr>)}</tbody></table></div>{!s.clients.length&&<Empty icon={Users} title="Sua comunidade começa aqui" description="Cadastre o primeiro tutor para abrir uma ficha."/>}</section>}
 </>}
 {view==='services'&&<><div className="list-toolbar"><div className="segmented">{['Todos','Banho e tosa','Clínica'].map(c=><button key={c} className={category===c?'selected':''} onClick={()=>setCategory(c)}>{c}</button>)}</div><span className="muted">{s.services.filter(x=>x.active).length} serviços disponíveis</span></div><div className="service-grid">{s.services.filter(x=>category==='Todos'||x.category===category).map(v=><article className={'service-card '+(!v.active?'inactive':'')} key={v.id}><div className="service-card-head"><span className={'service-icon '+(v.category==='Clínica'?'purple-bg':'green-bg')}>{v.category==='Clínica'?<Stethoscope size={23}/>:v.id.includes('hidra')?<Sparkles size={23}/>:v.id.includes('tosa')?<Scissors size={23}/>:<Droplets size={23}/>}</span><button hidden={!canAction('saveService')} className="icon-button" aria-label={'Editar '+v.name} onClick={()=>open('service',v)}><Pencil size={16}/></button></div><small className="eyebrow">{v.category}</small><h2>{v.name}</h2><p>{v.description||'Personalize a descrição deste serviço.'}</p><div className="service-footer"><strong>{money(v.price)}</strong><span><Clock3 size={14}/> {v.duration} min</span>{!v.active&&<Badge>Inativo</Badge>}</div></article>)}</div></>}
 {view==='packages'&&<>
 <div className="list-toolbar"><div className="segmented">{['Contratados','Modelos'].map(t=><button key={t} className={packageTab===t?'selected':''} onClick={()=>setPackageTab(t)}>{t} <span>{t==='Modelos'?s.templates.length:s.subscriptions.filter(x=>!x.archived).length}</span></button>)}</div>{packageTab==='Contratados'&&<select value={filter} aria-label="Filtrar pacotes" onChange={e=>setFilter(e.target.value)}>{['Todos','Ativo','A vencer','Vencido','Esgotado','Renovado'].map(t=><option key={t}>{t}</option>)}</select>}</div>
 {packageTab==='Modelos'?<><div className="package-grid">{s.templates.map((t,i)=><article key={t.id} className={'package-card variant-'+(i%3)}><div className="package-card-top"><span><Package size={24}/></span><button hidden={!canAction('saveTemplate')} className="icon-button" aria-label={'Editar pacote '+t.name} onClick={()=>open('template',t)}><Pencil size={16}/></button></div><span className="eyebrow">{t.sessions} SESSÕES · {t.validityDays} DIAS</span><h2>{t.name}</h2><div className="package-price">{money(t.price)}<small>/ pacote</small></div><div className="package-features">{t.features.map((f,j)=><span key={j}><Check size={15}/>{f}</span>)}</div><div className="eligible-services"><small>SERVIÇOS INCLUÍDOS</small>{t.serviceIds.map(id=><span key={id}>{s.services.find(v=>v.id===id)?.name}</span>)}</div>{!t.active&&<Badge>Modelo inativo</Badge>}<button hidden={!canAction('subscribe')} className="btn package-choose" disabled={!t.active} onClick={()=>open('subscribe',{templateId:t.id})}>Contratar para um pet <ArrowRight size={16}/></button></article>)}</div><div className="info-strip"><Leaf size={21}/><p>Personalize os serviços, a quantidade de sessões e a validade. Cada sessão corresponde a um atendimento; os cuidados descritos são incluídos nas sessões, sem cotas separadas por adicional.</p></div></>:<section className="panel"><div className="table-scroll"><table><thead><tr><th>Pet / Tutor</th><th>Pacote</th><th>Sessões utilizadas</th><th>Validade</th><th>Status</th><th/></tr></thead><tbody>{s.subscriptions.filter(x=>filter==='Todos'?!x.archived:packageStatus(x)===filter).map(sub=>{const p=petBy(sub.petId);return <tr key={sub.id}><td><button className="pet-cell" onClick={()=>p&&openProfile(p,'Pacotes')}><PetAvatar pet={p}/><span><strong>{p?.name}</strong><small>{owner(p)?.name}</small></span></button></td><td><strong>{sub.name}</strong><small>{money(sub.price)}</small></td><td><div className="session-progress"><span><strong>{sub.used}</strong> de {sub.total}</span><div><i style={{width:sub.used/sub.total*100+'%'}}/></div></div></td><td>{dateLabel(sub.expiresAt)}<small>Início: {dateLabel(sub.startsAt)}</small></td><td><Status status={packageStatus(sub)}/></td><td>{!sub.archived&&<button className="btn compact outline" onClick={()=>open('subscribe',{petId:sub.petId,templateId:sub.templateId,renewId:sub.id})}><RefreshCw size={14}/> Renovar</button>}</td></tr>})}</tbody></table></div>{!s.subscriptions.length&&<Empty icon={Package} title="Mais cuidado, com recorrência" description="Escolha um modelo e contrate um pacote para o pet." action={<button className="btn primary" onClick={()=>open('subscribe')}><Plus size={16}/> Contratar pacote</button>}/>}</section>}
 </>}
 {view==='clinic'&&<>
 <div className="clinic-intro"><div className="clinic-intro-icon"><Stethoscope size={30}/></div><div><h2>Todo cuidado conta uma história.</h2><p>Registros clínicos e vacinas acompanham o pet em cada etapa.</p></div><button className="btn outline" onClick={()=>open('vaccine',{petId:clinicPet})}><Syringe size={17}/> Registrar vacina</button></div>
 <div className="list-toolbar"><h2 className="small-title">Histórico de atendimentos</h2><select aria-label="Filtrar paciente" value={clinicPet} onChange={e=>setClinicPet(e.target.value)}><option value="">Todos os pacientes</option>{s.pets.map(p=><option key={p.id} value={p.id}>{p.name} · {owner(p)?.name}</option>)}</select></div>
 <div className="clinic-columns"><section className="panel"><div className="panel-header"><h2><FileText size={19}/> Registros clínicos</h2><Badge>{s.consultations.filter(c=>!clinicPet||c.petId===clinicPet).length}</Badge></div>{s.consultations.filter(c=>!clinicPet||c.petId===clinicPet).sort((a,b)=>b.date.localeCompare(a.date)).map(c=>{const p=petBy(c.petId);return <article key={c.id} className="clinical-record"><div className="clinical-record-top"><button className="pet-cell" onClick={()=>p&&openProfile(p,'Veterinária')}><PetAvatar pet={p}/><span><strong>{p?.name}</strong><small>{c.professional} {c.crmv&&'· CRMV '+c.crmv}</small></span></button><time>{dateLabel(c.date)}</time></div><h3>{c.reason}</h3><p>{c.findings||'Sem observações clínicas adicionais.'}</p>{c.plan&&<div className="clinical-plan"><strong>Conduta e orientações</strong><p>{c.plan}</p></div>}{c.nextDate&&<small className="green-text"><CalendarDays size={13}/> Retorno: {dateLabel(c.nextDate)}</small>}</article>})}{!s.consultations.filter(c=>!clinicPet||c.petId===clinicPet).length&&<Empty icon={Stethoscope} title="Histórias de cuidado" description="Os registros clínicos aparecerão aqui após o atendimento."/>}</section>
 <section className="panel"><div className="panel-header"><h2><Syringe size={19}/> Vacinas aplicadas</h2><button className="icon-button" aria-label="Registrar vacina" onClick={()=>open('vaccine',{petId:clinicPet})}><Plus size={18}/></button></div>{s.vaccines.filter(v=>!clinicPet||v.petId===clinicPet).sort((a,b)=>b.date.localeCompare(a.date)).map(v=><article className="vaccine-card" key={v.id}><div><span className="vaccine-icon"><Syringe size={18}/></span><div><strong>{v.name}</strong><small>{petBy(v.petId)?.name} · Aplicada em {dateLabel(v.date)}</small></div></div><p>Lote {v.batch} <span>·</span> {v.professional}</p>{v.nextDate&&<Badge tone={v.nextDate<d?'amber':'green'}>Reforço: {dateLabel(v.nextDate)}</Badge>}</article>)}{!s.vaccines.filter(v=>!clinicPet||v.petId===clinicPet).length&&<Empty icon={Syringe} title="Proteção em dia" description="Registre as aplicações e defina a data do próximo reforço."/>}</section></div>
 </>}
 {view==='products'&&<>
 <div className="mini-stats"><div><span className="mini-icon"><ShoppingBag size={21}/></span><span>Produtos cadastrados<strong>{s.products.length}</strong></span></div><div><span className="mini-icon cream-bg"><Package size={21}/></span><span>Valor de venda em estoque<strong>{money(s.products.reduce((t,p)=>t+p.price*p.stock,0))}</strong></span></div><div><span className="mini-icon peach"><AlertTriangle size={21}/></span><span>Estoque abaixo do mínimo<strong>{lowStock.length} produtos</strong></span></div></div>
 <div className="list-toolbar"><div className="local-search"><Search size={16}/><input aria-label="Buscar produto" placeholder="Buscar produto ou código..." value={listSearch} onChange={e=>setListSearch(e.target.value)}/></div><div className="toolbar-right"><select value={filter} aria-label="Filtrar estoque" onChange={e=>setFilter(e.target.value)}><option>Todos</option><option>Estoque baixo</option>{Array.from(new Set(s.products.map(p=>p.category))).map(c=><option key={c}>{c}</option>)}</select><button className="btn outline" onClick={()=>open('stock')}><RefreshCw size={16}/> Movimentar</button><button className="btn outline" onClick={()=>open('movements')}><FileText size={16}/> Histórico</button></div></div>
 <section className="panel"><div className="table-scroll"><table><thead><tr><th>Produto</th><th>Categoria</th><th>Estoque</th><th>Custo</th><th>Preço de venda</th><th/></tr></thead><tbody>{s.products.filter(p=>(p.name+' '+p.sku).toLowerCase().includes(listSearch.toLowerCase())&&(filter==='Todos'||filter==='Estoque baixo'&&p.stock<=p.minStock||filter===p.category)).map(p=><tr key={p.id}><td><button className="product-cell" onClick={()=>open('product',p)}><span className={'product-icon '+(p.category==='Rações'?'cream-bg':p.category==='Acessórios'?'purple-bg':'green-bg')}><ShoppingBag size={22}/></span><span><strong>{p.name}</strong><small>{p.sku}</small></span></button></td><td className="muted">{p.category}</td><td><Badge tone={p.stock<=p.minStock?'amber':'green'}>{p.stock} {p.unit}</Badge><small>Mínimo: {p.minStock}</small></td><td className="muted">{money(p.cost)}</td><td><strong>{money(p.price)}</strong></td><td><div className="row-actions"><button className="btn compact outline" onClick={()=>open('stock',{productId:p.id,kind:'Venda'})}>Vender <ArrowUpRight size={13}/></button><button className="icon-button" aria-label={'Editar '+p.name} onClick={()=>open('product',p)}><Pencil size={15}/></button></div></td></tr>)}</tbody></table></div>{!s.products.length&&<Empty icon={ShoppingBag} title="Vamos organizar as prateleiras?" description="Cadastre rações, coleiras, protetores, comedouros e outros produtos." action={<button className="btn primary" onClick={()=>open('product')}><Plus size={16}/> Novo produto</button>}/>}</section>
 </>}
 {view==='finance'&&<>
 <div className="list-toolbar"><span className="period-label"><CalendarDays size={17}/> Visão mensal</span><div className="toolbar-right"><input aria-label="Mês do financeiro" type="month" value={financeMonth} onChange={e=>e.target.value&&setFinanceMonth(e.target.value)}/><button className="btn outline" onClick={()=>csv(monthTransactions.map(t=>({tipo:t.type==='income'?'Receita':'Despesa',descricao:t.description,valor:t.amount,data:t.date,pagamento:t.paidDate||'',categoria:t.category,situacao:t.paid?'Pago':'Pendente'})),`financeiro-${financeMonth}.csv`)}><Download size={16}/> Exportar</button></div></div>
 <div className="stats-grid"><Stat icon={CircleArrowDown} label="Entradas recebidas" value={money(monthIncome)} sub="Recebimentos confirmados no mês" action={()=>setFilter('Receitas')}/><Stat icon={CircleArrowUp} label="Despesas pagas" value={money(monthExpense)} sub="Pagamentos confirmados no mês" tone="pink" action={()=>setFilter('Despesas')}/><Stat icon={Wallet} label="Saldo realizado" value={money(monthIncome-monthExpense)} sub="Entradas recebidas menos despesas pagas" tone="cream" action={()=>setFilter('Todos')}/><Stat icon={Clock3} label="A receber" value={money(monthTransactions.filter(t=>t.type==='income'&&!t.paid).reduce((v,t)=>v+t.amount,0))} sub="Receitas com pagamento pendente" tone="lavender" action={()=>setFilter('Pendentes')}/></div>
 <section className="panel"><div className="panel-header"><h2>Movimentações do mês</h2><div className="segmented small">{['Todos','Receitas','Despesas','Pendentes'].map(t=><button className={filter===t?'selected':''} key={t} onClick={()=>setFilter(t)}>{t}</button>)}</div></div><div className="table-scroll"><table><thead><tr><th>Descrição</th><th>Categoria</th><th>Data / vencimento</th><th>Valor</th><th>Situação</th><th/></tr></thead><tbody>{monthTransactions.filter(t=>filter==='Todos'||filter==='Receitas'&&t.type==='income'||filter==='Despesas'&&t.type==='expense'||filter==='Pendentes'&&!t.paid).sort((a,b)=>b.date.localeCompare(a.date)).map(t=><tr key={t.id}><td><span className="transaction-description"><i className={t.type==='income'?'income':'expense'}>{t.type==='income'?<ArrowRight size={16}/>:<ArrowUpRight size={16}/>}</i><strong>{t.description}</strong></span></td><td className="muted">{t.category}</td><td>{dateLabel(t.date)}{t.paidDate&&t.paidDate!==t.date&&<small>Pago em {dateLabel(t.paidDate)}</small>}</td><td className={t.type==='income'?'green-text':'red-text'}><strong>{t.type==='income'?'+':'−'} {money(t.amount)}</strong></td><td><Badge tone={t.paid?'green':t.date<d?'red':'amber'}>{t.paid?'Pago':t.date<d?'Vencido':'Pendente'}</Badge></td><td><button className="btn compact ghost" disabled={busy} onClick={()=>act({type:'markPaid',data:{id:t.id,paid:!t.paid}},t.paid?'Lançamento marcado como pendente.':'Pagamento registrado.',false)}>{t.paid?'Marcar pendente':'Dar baixa'}</button></td></tr>)}</tbody></table></div>{!monthTransactions.length&&<Empty icon={Wallet} title="Tudo começa com o primeiro lançamento" description="Serviços avulsos, pacotes e vendas alimentam o financeiro. Você também pode registrar entradas e despesas."/>}</section>
 </>}
 {view==='reminders'&&<>
 <div className="reminders-summary"><span><MessageCircle size={26}/></span><div><h2>Presença também é cuidado.</h2><p>Prepare a mensagem, revise os dados e envie pelo seu WhatsApp.</p></div><Badge tone="green">Envio manual</Badge></div>
 <div className="list-toolbar"><div className="segmented">{['Todos','Pacotes','Vacinas','Agenda'].map(t=><button key={t} className={reminderType===t?'selected':''} onClick={()=>setReminderType(t)}>{t}</button>)}</div><span className="muted">Antecedência: {s.settings.reminderDays} dias</span></div>
 <div className="reminder-grid">{rs.filter(r=>reminderType==='Todos'||reminderType==='Pacotes'&&r.type==='package'||reminderType==='Vacinas'&&r.type==='vaccine'||reminderType==='Agenda'&&r.type==='appointment').map(r=>{const p=petBy(r.petId),c=owner(p),contact=s.contacts.filter(x=>x.refId===r.refId).at(-1);return <article className="reminder-card" key={r.id}><div className="reminder-card-top"><span className={'reminder-icon '+(r.urgent?'peach':'sage')}>{r.type==='package'?<Package size={22}/>:r.type==='vaccine'?<Syringe size={22}/>:<CalendarDays size={22}/>}</span><Badge tone={r.urgent?'amber':'green'}>{r.urgent?'Precisa de atenção':'Próximo cuidado'}</Badge></div><h2>{r.title}</h2><p>{r.detail}</p><button className="pet-cell" onClick={()=>p&&openProfile(p)}><PetAvatar pet={p} size={39}/><span><strong>{p?.name}</strong><small>{c?.name}</small></span></button><div className="reminder-card-footer"><WhatsApp reminder={r}/>{contact?<small className="green-text"><Check size={13}/> Contato em {dateLabel(contact.date)}</small>:<button className="text-link" disabled={busy} onClick={()=>act({type:'logContact',data:{refId:r.refId}},'Contato registrado no lembrete.',false)}>Registrar contato</button>}</div></article>})}</div>{rs.length===0&&<section className="panel"><Empty icon={CheckCircle2} title="Tudo em dia. Pode respirar." description="Os lembretes aparecem conforme os pacotes vencem, as vacinas precisam de reforço e os atendimentos se aproximam."/></section>}
 <div className="info-strip"><Bell size={19}/><p>Os lembretes são calculados ao abrir o sistema. O envio é manual e não acontece em segundo plano. O envio automático depende de uma integração com a API oficial do WhatsApp.</p></div>
 </>}
 {view==='settings'&&<div className="settings-columns"><section className="panel"><div className="panel-header"><div><h2><Settings size={19}/> Seu estabelecimento</h2><p>Informações específicas desta loja, usadas nas fichas e nas mensagens.</p></div></div><div className="panel-body"><Form busy={busy} onSubmit={f=>{const v=payload(f);act({type:'saveSettings',data:{...v,reminderDays:Number(v.reminderDays)}},'Configurações salvas.')}}><Input label="Nome do estabelecimento *" name="businessName" defaultValue={s.settings.businessName} required/><Input label="Nome da unidade *" name="unitName" defaultValue={s.settings.unitName} required/><Input label="WhatsApp do estabelecimento" name="phone" defaultValue={s.settings.phone} placeholder="(61) 99999-9999"/><Input label="Endereço" name="address" defaultValue={s.settings.address}/><Textarea label="Profissionais *" name="professionals" defaultValue={s.settings.professionals} required/><p className="form-help wide">Separe os nomes por vírgulas. Eles aparecerão na agenda.</p><Input name="reminderDays" label="Lembrar com quantos dias de antecedência?" type="number" min={0} max={30} defaultValue={s.settings.reminderDays} required/><Textarea name="messageTemplate" label="Mensagem de renovação de pacote *" defaultValue={s.settings.messageTemplate} required/><p className="form-help wide">Campos disponíveis: {'{tutor}, {pet}, {pacote}, {vencimento}, {empresa}'}. Para pacotes ainda válidos ou esgotados, a mensagem se adapta à situação.</p></Form></div></section><div className="settings-side"><section className="panel brand-panel"><img src="assets/aupetflow-logo.jpeg" alt="AupetFlow — Tecnologia que cuida do seu pet"/><p>Tecnologia que cuida do seu pet.</p></section><section className="panel"><div className="panel-header"><h2><ShieldCheck size={19}/> Dados e acesso</h2></div><div className="panel-body settings-info"><p>Esta loja tem acesso por e-mail e senha. Os cadastros são salvos no seu servidor MySQL, separados por loja, e as permissões são conferidas a cada operação.</p><button className="btn outline full" onClick={()=>download(JSON.stringify({exportedAt:new Date().toISOString(),version:1,state:s},null,2),`aupetflow-backup-${d}.json`)}><Download size={17}/> Exportar todos os dados</button><small>Exportação em JSON para guardar uma cópia dos seus registros. Esta versão não emite notas fiscais.</small><a className="btn ghost full" href="index.php?p=password"><ShieldCheck size={16}/> Minha senha</a><form method="post" action="index.php?p=logout"><input type="hidden" name="csrf" value={BOOT.csrf}/><button className="btn ghost full"><LogOut size={16}/> Sair da conta</button></form></div></section></div></div>}
 <footer className="app-footer"><span><PawPrint size={13}/> AupetFlow <b>·</b> Tecnologia que cuida</span><span><ShieldCheck size={12}/> Ambiente privado {s.demo&&'· Demonstração'}</span></footer>
 </main></div>
 {toast&&<div className="toast" role="status"><CheckCircle2 size={19}/><span>{toast}</span><button aria-label="Fechar notificação" onClick={()=>setToast('')}><X size={16}/></button></div>}
 {profile&&selectedPet&&selectedClient&&<div className="overlay profile-overlay" onMouseDown={e=>{if(e.target===e.currentTarget&&!busy)setProfile(null)}}><section className="profile-drawer" ref={!modal?dialogRef:undefined} role="dialog" aria-modal="true" aria-labelledby="profile-title"><div className="drawer-top"><span><FileText size={17}/> Ficha do cliente</span><div><button hidden={!canAction('saveClient')} className="icon-button" aria-label="Editar tutor" onClick={()=>open('client',selectedClient)}><Pencil size={17}/></button><button className="icon-button" aria-label="Fechar ficha" onClick={()=>setProfile(null)}><X size={22}/></button></div></div><div className="profile-content"><div className="tutor-profile"><span className="initial-avatar large">{selectedClient.name[0]}</span><div><span className="eyebrow">TUTOR RESPONSÁVEL</span><h2 id="profile-title">{selectedClient.name}</h2><div className="contact-inline"><span><Phone size={13}/>{selectedClient.phone||'WhatsApp não cadastrado'}</span>{selectedClient.email&&<span><Mail size={13}/>{selectedClient.email}</span>}</div></div></div>{selectedClient.address&&<p className="profile-address"><MapPin size={14}/>{selectedClient.address}</p>}{selectedClient.notes&&<p className="tutor-note">{selectedClient.notes}</p>}
 <div className="pet-picker">{s.pets.filter(p=>p.clientId===selectedClient.id).map(p=><button key={p.id} className={selectedPet.id===p.id?'selected':''} onClick={()=>setProfile({...profile,petId:p.id})}><PetAvatar pet={p} size={28}/>{p.name}</button>)}<button onClick={()=>open('pet',{clientId:selectedClient.id})}><Plus size={15}/> Adicionar pet</button></div>
 <section className="profile-pet-summary"><PetAvatar pet={selectedPet} size={76}/><div><h2>{selectedPet.name} <span>{selectedPet.sex==='Fêmea'?'♀':selectedPet.sex==='Macho'?'♂':''}</span></h2><p>{selectedPet.breed||selectedPet.species} <b>·</b> {selectedPet.size} <b>·</b> {selectedPet.weight?selectedPet.weight+' kg':'Peso não informado'}</p>{selectedPet.birthdate&&<small>Nascimento: {dateLabel(selectedPet.birthdate)}</small>}</div><button hidden={!canAction('savePet')} className="icon-button" aria-label="Editar pet" onClick={()=>open('pet',selectedPet)}><Pencil size={17}/></button></section>
 {selectedPet.alerts&&<div className="pet-alert"><AlertTriangle size={18}/><p><strong>Atenção aos cuidados</strong>{selectedPet.alerts}</p></div>}
 <div className="tab-row profile-tabs">{['Visão geral','Histórico','Veterinária','Pacotes'].filter(t=>(t!=='Veterinária'||allowedView('clinic'))&&(t!=='Pacotes'||allowedView('packages'))).map(t=><button key={t} className={profile.tab===t?'selected':''} onClick={()=>setProfile({...profile,tab:t})}>{t}</button>)}</div>
 {profile.tab==='Visão geral'&&<><div className="profile-quick-actions"><button className="btn primary" onClick={()=>open('appointment',{petId:selectedPet.id,category:'Banho e tosa'})}><Droplets size={16}/> Agendar banho</button><button className="btn outline" onClick={()=>open('appointment',{petId:selectedPet.id,category:'Clínica'})}><Stethoscope size={16}/> Agendar consulta</button></div><h3 className="profile-section-title">Próximos encontros</h3>{s.appointments.filter(a=>a.petId===selectedPet.id&&!['Concluído','Cancelado'].includes(a.status)).sort((a,b)=>(a.date+a.time).localeCompare(b.date+b.time)).map(a=><button className="upcoming-card" key={a.id} onClick={()=>open('appointmentDetail',a)}><span className="upcoming-date"><strong>{a.date.slice(-2)}</strong><small>{dateLabel(a.date,{month:'short'})}</small></span><span><strong>{a.serviceName}</strong><small>{a.time} · {a.professional}</small></span><Status status={a.status}/><ChevronRight size={16}/></button>)}{!s.appointments.some(a=>a.petId===selectedPet.id&&!['Concluído','Cancelado'].includes(a.status))&&<div className="light-empty">Nenhum próximo atendimento. Que tal reservar um horário?</div>}<h3 className="profile-section-title">Resumo de cuidados</h3><div className="profile-counters"><div><Scissors size={20}/><strong>{s.appointments.filter(a=>a.petId===selectedPet.id&&a.category==='Banho e tosa'&&a.status==='Concluído').length}</strong><span>banhos e tosas</span></div><div><Stethoscope size={20}/><strong>{s.consultations.filter(c=>c.petId===selectedPet.id).length}</strong><span>registros clínicos</span></div><div><Syringe size={20}/><strong>{s.vaccines.filter(v=>v.petId===selectedPet.id).length}</strong><span>vacinas aplicadas</span></div></div></>}
 {profile.tab==='Histórico'&&<><div className="history-heading"><h3>Banhos, tosas e atendimentos</h3><button className="text-link" onClick={()=>csv(s.appointments.filter(a=>a.petId===selectedPet.id&&a.status==='Concluído').map(a=>({data:a.date,horario:a.time,servico:a.serviceName,profissional:a.professional,observacoes:a.notes,adicionais:a.addons,pacote:a.packageId?s.subscriptions.find(x=>x.id===a.packageId)?.name:'Avulso'})),`historico-${selectedPet.name}.csv`)}><Download size={14}/> Exportar</button></div><div className="timeline">{s.appointments.filter(a=>a.petId===selectedPet.id&&a.status==='Concluído').sort((a,b)=>(b.date+b.time).localeCompare(a.date+a.time)).map(a=><article key={a.id} className="timeline-item"><span className="timeline-dot">{a.category==='Clínica'?<Stethoscope size={16}/>:<Droplets size={16}/>}</span><div><time>{dateLabel(a.date)} <span>às {a.time}</span></time><h3>{a.serviceName}</h3><p>{a.professional}</p>{a.notes&&<p className="history-notes">{a.notes}</p>}<div className="pet-tags">{a.addons.map(x=><span key={x}>{x}</span>)}{a.packageId&&<span><Package size={11}/>{s.subscriptions.find(x=>x.id===a.packageId)?.name}</span>}</div></div><Badge tone="green"><Check size={11}/> Realizado</Badge></article>)}</div>{!s.appointments.some(a=>a.petId===selectedPet.id&&a.status==='Concluído')&&<Empty icon={Clock3} title="Uma história para começar" description="Os dias de banho, tosa e atendimento aparecem aqui assim que você concluir o agendamento."/>}</>}
 {profile.tab==='Veterinária'&&<><div className="profile-quick-actions"><button className="btn primary" onClick={()=>open('consultation',{petId:selectedPet.id})}><Plus size={16}/> Registro clínico</button><button className="btn outline" onClick={()=>open('vaccine',{petId:selectedPet.id})}><Syringe size={16}/> Aplicar vacina</button></div><h3 className="profile-section-title">Carteira de vacinação</h3>{s.vaccines.filter(v=>v.petId===selectedPet.id).sort((a,b)=>b.date.localeCompare(a.date)).map(v=><div className="vaccine-card bordered" key={v.id}><div><span className="vaccine-icon"><Syringe size={18}/></span><div><strong>{v.name}</strong><small>Aplicação: {dateLabel(v.date)} · Lote: {v.batch}</small></div></div><p>{v.professional} {v.crmv&&'· CRMV '+v.crmv} {v.manufacturer&&'· '+v.manufacturer}</p>{v.nextDate&&<Badge tone={v.nextDate<d?'amber':'green'}>Próximo reforço: {dateLabel(v.nextDate)}</Badge>}</div>)}{!s.vaccines.some(v=>v.petId===selectedPet.id)&&<div className="light-empty">Nenhuma vacina registrada nesta ficha.</div>}<h3 className="profile-section-title">Histórico clínico</h3>{s.consultations.filter(c=>c.petId===selectedPet.id).sort((a,b)=>b.date.localeCompare(a.date)).map(c=><article className="clinical-record bordered" key={c.id}><div className="clinical-record-top"><strong>{dateLabel(c.date)}</strong><span>{c.professional} {c.crmv&&'· '+c.crmv}</span></div><h3>{c.reason}</h3><p>{c.findings}</p>{c.plan&&<div className="clinical-plan"><strong>Conduta / orientações</strong><p>{c.plan}</p></div>}{c.nextDate&&<small className="green-text">Retorno agendado: {dateLabel(c.nextDate)}</small>}</article>)}{!s.consultations.some(c=>c.petId===selectedPet.id)&&<div className="light-empty">Nenhum registro clínico nesta ficha.</div>}</>}
 {profile.tab==='Pacotes'&&<><div className="history-heading"><h3>Pacotes do pet</h3><button className="btn compact primary" onClick={()=>open('subscribe',{petId:selectedPet.id})}><Plus size={14}/> Contratar</button></div>{s.subscriptions.filter(x=>x.petId===selectedPet.id).sort((a,b)=>b.startsAt.localeCompare(a.startsAt)).map(sub=><article className="profile-package" key={sub.id}><div><span className="service-icon green-bg"><Package size={22}/></span><div><h3>{sub.name}</h3><p>{dateLabel(sub.startsAt)} até {dateLabel(sub.expiresAt)}</p></div><Status status={packageStatus(sub)}/></div><div className="session-progress"><span><strong>{sub.used} de {sub.total}</strong> sessões utilizadas</span><div><i style={{width:sub.used/sub.total*100+'%'}}/></div></div><div className="package-session-list">{Array.from({length:sub.total},(_,i)=><span key={i} className={i<sub.used?'used':''} title={'Sessão '+(i+1)}>{i<sub.used?<Check size={15}/>:i+1}</span>)}</div><p className="form-help">Serviços: {sub.serviceIds.map(id=>s.services.find(v=>v.id===id)?.name).join(', ')}.</p>{!sub.archived&&<button className="btn compact outline" onClick={()=>open('subscribe',{petId:sub.petId,templateId:sub.templateId,renewId:sub.id})}><RefreshCw size={14}/> Renovar pacote</button>}</article>)}{!s.subscriptions.some(x=>x.petId===selectedPet.id)&&<Empty icon={Package} title="Cuidado com continuidade" description="Contrate um pacote para acompanhar sessões e validade."/>}</>}
 </div><div className="drawer-footer"><PawPrint size={14}/> Cada cuidado fica guardado nesta história.</div></section></div>}
 {modal&&<div className="overlay modal-overlay" onMouseDown={e=>{if(e.target===e.currentTarget&&!busy){setModal(null);setError('')}}}><section key={modal.type+(modal.data?.id||'')} className={'modal '+(['appointmentDetail','movements'].includes(modal.type)?'modal-wide':'')} role="dialog" aria-modal="true" aria-labelledby="modal-title" ref={dialogRef}><div className="modal-header"><div><span className="eyebrow">AUPETFLOW · CADA DETALHE IMPORTA</span><h2 id="modal-title">{({client:modal.data?.id?'Editar tutor':'Uma nova amizade',pet:modal.data?.id?'Editar pet':'Vamos conhecer seu pet?',service:modal.data?.id?'Editar serviço':'Novo serviço',template:modal.data?.id?'Personalizar pacote':'Criar pacote',subscribe:modal.data?.renewId?'Renovar pacote':'Contratar pacote',appointment:modal.data?.id?'Editar agendamento':'Reserve um momento de cuidado',appointmentDetail:'Detalhes do atendimento',finishAppointment:'Concluir atendimento',cancelAppointment:'Cancelar agendamento',consultation:'Registro clínico',vaccine:'Registrar vacina aplicada',product:modal.data?.id?'Editar produto':'Novo produto',stock:'Movimentar estoque',transaction:'Novo lançamento',whatsapp:'Uma mensagem de cuidado',startReal:'Pronto para começar?',help:'Seus lembretes, sempre por perto',movements:'Histórico do estoque'} as Record<string,string>)[modal.type]}</h2></div><button className="icon-button" aria-label="Fechar janela" disabled={busy} onClick={()=>{setModal(null);setError('')}}><X size={21}/></button></div><div className="modal-body">
 {error&&<div className="inline-error" role="alert"><AlertTriangle size={17}/>{error}</div>}
 {modal.type==='startReal'&&<><div className="start-icon"><PawPrint size={32}/></div><p className="modal-intro">Os tutores, pets, agendamentos e lançamentos de exemplo serão removidos. Os modelos de serviços e pacotes continuam disponíveis para você personalizar.</p><p className="form-help">Se você adicionou registros durante a demonstração, exporte uma cópia antes de continuar.</p><div className="modal-actions"><button className="btn outline" onClick={()=>download(JSON.stringify({exportedAt:new Date().toISOString(),version:1,state:s},null,2),`aupetflow-demonstracao-${d}.json`)}><Download size={16}/> Exportar cópia</button><button disabled={busy} className="btn primary" onClick={async()=>{if(await act({type:'startReal'},'Seu espaço está pronto. Cadastre o primeiro tutor.')){go('clients');setProfile(null);open('client')}}}>{busy?<Loader2 className="spin" size={17}/>:<ArrowRight size={17}/>} Começar a usar</button></div></>}
 {modal.type==='client'&&<Form busy={busy} label={modal.data?.id?'Salvar tutor':'Salvar e cadastrar pet'} onSubmit={f=>act({type:'saveClient',data:{...payload(f),id:modal.data?.id}},'Tutor salvo.')}><Input label="Nome completo *" name="name" defaultValue={modal.data?.name} required wide maxLength={150}/><Input label="WhatsApp com DDD" name="phone" type="tel" defaultValue={modal.data?.phone} placeholder="(61) 99999-9999" hint="Usado para lembretes e renovações."/><Input label="E-mail" name="email" type="email" defaultValue={modal.data?.email}/><Input label="Endereço" name="address" defaultValue={modal.data?.address} wide/><Textarea label="Observações do tutor" name="notes" defaultValue={modal.data?.notes} placeholder="Preferências de contato, horários e outras informações."/></Form>}
 {modal.type==='pet'&&<Form busy={busy} label="Salvar pet" onSubmit={f=>{const v=payload(f);act({type:'savePet',data:{...v,id:modal.data?.id,weight:Number(v.weight)}},'Pet salvo na ficha do tutor.')}}><Select name="clientId" label="Tutor responsável *" defaultValue={modal.data?.clientId||''} required>{clientOptions()}</Select><Input label="Nome do pet *" name="name" defaultValue={modal.data?.name} required/><Select label="Espécie *" name="species" defaultValue={modal.data?.species||'Cachorro'}>{['Cachorro','Gato','Outro'].map(x=><option key={x}>{x}</option>)}</Select><Input label="Raça" name="breed" defaultValue={modal.data?.breed} placeholder="Ex.: Shih-tzu, sem raça definida"/><Select label="Porte *" name="size" defaultValue={modal.data?.size||'Pequeno'}>{['Pequeno','Médio','Grande','Gigante'].map(x=><option key={x}>{x}</option>)}</Select><Select label="Sexo" name="sex" defaultValue={modal.data?.sex||'Não informado'}>{['Não informado','Fêmea','Macho'].map(x=><option key={x}>{x}</option>)}</Select><Input label="Nascimento" name="birthdate" type="date" max={d} defaultValue={modal.data?.birthdate}/><Input label="Peso (kg)" name="weight" type="number" min="0" max="1500" step="0.01" defaultValue={modal.data?.weight||''}/><Textarea label="Alertas e cuidados especiais" name="alerts" defaultValue={modal.data?.alerts} placeholder="Alergias, comportamento, sensibilidade, produtos orientados pelo veterinário..."/>{!s.clients.length&&<p className="form-help wide">Cadastre um tutor antes de salvar o pet. <button type="button" className="text-link" onClick={()=>open('client')}>Cadastrar tutor</button></p>}</Form>}
 {modal.type==='service'&&<Form busy={busy} onSubmit={f=>{const v=payload(f);act({type:'saveService',data:{...v,id:modal.data?.id,price:Number(v.price),duration:Number(v.duration),active:f.has('active')}},'Serviço salvo.')}}><Input label="Nome do serviço *" name="name" defaultValue={modal.data?.name} placeholder="Ex.: Banho com hidratação" required wide/><Select name="category" label="Área de atendimento *" defaultValue={modal.data?.category||'Banho e tosa'}><option>Banho e tosa</option><option>Clínica</option></Select><Input name="duration" label="Duração (minutos) *" type="number" min="5" max="720" step="5" defaultValue={modal.data?.duration||60} required/><Input name="price" label="Preço (R$) *" type="number" min="0" step="0.01" defaultValue={modal.data?.price??65} required/><div className="field check-field"><Checked name="active" defaultChecked={modal.data?.active??true}>Disponível para agendamento</Checked></div><Textarea name="description" label="O que está incluído?" defaultValue={modal.data?.description} placeholder="Tipo de banho, produtos, hidratação ou tratamentos conforme orientação veterinária."/></Form>}
 {modal.type==='template'&&<Form busy={busy} label="Salvar pacote" onSubmit={f=>{const v=payload(f);act({type:'saveTemplate',data:{id:modal.data?.id,name:v.name,sessions:Number(v.sessions),validityDays:Number(v.validityDays),price:Number(v.price),serviceIds:f.getAll('serviceIds'),features:String(v.features).split('\n').map(x=>x.trim()).filter(Boolean),active:f.has('active')}},'Modelo de pacote salvo.')}}><Input name="name" label="Nome do pacote *" defaultValue={modal.data?.name} required wide/><Input name="sessions" label="Quantidade de sessões *" type="number" min="1" max="365" defaultValue={modal.data?.sessions||4} required/><Input name="validityDays" label="Validade em dias *" type="number" min="1" max="730" defaultValue={modal.data?.validityDays||30} required/><Input name="price" label="Valor do pacote (R$) *" type="number" min="0" step="0.01" defaultValue={modal.data?.price||0} required/><div className="field check-field"><Checked name="active" defaultChecked={modal.data?.active??true}>Modelo ativo para contratação</Checked></div><Field label="Serviços permitidos no pacote *" wide><div className="checkbox-grid">{s.services.filter(x=>x.category==='Banho e tosa').map(x=><Checked name="serviceIds" key={x.id} value={x.id} defaultChecked={modal.data?.serviceIds?.includes(x.id)}>{x.name}</Checked>)}</div></Field><Textarea name="features" label="Cuidados incluídos (um por linha)" defaultValue={modal.data?.features?.join('\n')||''} placeholder={'Banho com hidratação\nTosa higiênica\nProdutos para pele conforme orientação'}/><p className="form-help wide">Cada atendimento utiliza uma sessão, independentemente dos cuidados incluídos. Alterações no modelo valem para novas contratações; pacotes já contratados preservam suas condições.</p></Form>}
 {modal.type==='subscribe'&&<Form busy={busy} label={modal.data?.renewId?'Renovar pacote':'Confirmar contratação'} onSubmit={f=>act({type:'subscribe',data:{...payload(f),renewId:modal.data?.renewId,paid:f.has('paid')}},'Pacote contratado. Receita registrada no financeiro.')}><Select label="Pet *" name="petId" defaultValue={modal.data?.petId||''} required>{petOptions()}</Select><Select label="Modelo de pacote *" name="templateId" defaultValue={modal.data?.templateId||''} required><option value="">Selecione um pacote</option>{s.templates.filter(x=>x.active).map(t=><option key={t.id} value={t.id}>{t.name} · {t.sessions} sessões · {money(t.price)}</option>)}</Select><Input name="startsAt" label="Data de início *" type="date" defaultValue={d} required/><div className="field check-field"><Checked name="paid">Pagamento já recebido</Checked></div><p className="form-help wide">A validade começa na data escolhida, de acordo com o número de dias do modelo. A contratação gera uma receita no financeiro.</p>{modal.data?.renewId&&<div className="form-warning wide"><RefreshCw size={18}/><p>O pacote anterior será arquivado, preservando o histórico. Conclua ou cancele os agendamentos dele antes de renovar. As sessões não utilizadas não são transferidas.</p></div>}</Form>}
 {modal.type==='appointment'&&(()=>{const svc=s.services.find(x=>x.id===scheduleService),available=s.subscriptions.filter(x=>x.petId===schedulePet&&!x.archived&&x.expiresAt>=scheduleDate&&x.startsAt<=scheduleDate&&x.used<x.total&&x.serviceIds.includes(scheduleService));return <Form busy={busy} label="Salvar agendamento" onSubmit={f=>{const v=payload(f);act({type:'saveAppointment',data:{id:modal.data?.id,petId:schedulePet,serviceId:scheduleService,date:v.date,time:v.time,professional:v.professional,packageId:schedulePackage,price:Number(v.price||0),notes:v.notes,addons:[...f.getAll('addons').map(String),...String(v.extraCare||'').split(',').map(x=>x.trim()).filter(Boolean)]}},'Agendamento salvo.')}}><Field label="Pet *"><select name="petId" required value={schedulePet} onChange={e=>{setSchedulePet(e.target.value);setSchedulePackage('')}}>{petOptions()}</select></Field><Field label="Serviço *"><select name="serviceId" value={scheduleService} required onChange={e=>{setScheduleService(e.target.value);setSchedulePackage('')}}><option value="">Selecione o serviço</option>{s.services.filter(x=>x.active).map(x=><option key={x.id} value={x.id}>{x.name}</option>)}</select></Field><Field label="Dia do atendimento *"><input type="date" name="date" value={scheduleDate} onChange={e=>setScheduleDate(e.target.value)} required/></Field><Input name="time" label="Horário *" type="time" defaultValue={modal.data?.time||'09:00'} required/><Input label="Profissional *" name="professional" defaultValue={modal.data?.professional||(svc?.category==='Clínica'?professionals().find(x=>x.startsWith('Dr')):professionals()[0])||''} list="professionals" required/><datalist id="professionals">{professionals().map(p=><option value={p} key={p}/>)}</datalist><Field label="Cobrança"><select name="packageId" value={schedulePackage} onChange={e=>setSchedulePackage(e.target.value)}><option value="">Avulso</option>{available.map(p=><option key={p.id} value={p.id}>{p.name} · {p.total-p.used} sessões restantes</option>)}</select></Field><Input key={scheduleService+schedulePackage} name="price" label={schedulePackage?'Valor coberto pelo pacote':'Valor do atendimento (R$) *'} type="number" min="0" step="0.01" defaultValue={schedulePackage?0:modal.data?.serviceId===scheduleService?modal.data.price:svc?.price||0} readOnly={!!schedulePackage} required/><div className="duration-preview"><Clock3 size={17}/><span>Duração prevista<strong>{svc?.duration||0} minutos</strong></span></div><Field label="Cuidados deste atendimento" wide><div className="checkbox-grid">{['Hidratação','Tratamento de pele','Tosa higiênica','Corte de unhas','Limpeza de ouvidos'].map(t=><Checked name="addons" value={t} key={t} defaultChecked={modal.data?.addons?.includes(t)}>{t}</Checked>)}</div></Field><Input label="Outros cuidados (separados por vírgula)" name="extraCare" wide defaultValue={modal.data?.addons?.filter((x:string)=>!['Hidratação','Tratamento de pele','Tosa higiênica','Corte de unhas','Limpeza de ouvidos'].includes(x)).join(', ')} placeholder="Produtos utilizados, preferências de tosa..."/><Textarea name="notes" label="Observações para a equipe" defaultValue={modal.data?.notes} placeholder="Essas observações ficarão no histórico após concluir o atendimento."/><p className="form-help wide">Tratamentos de pele seguem a orientação do veterinário responsável. Os cuidados acima são registros do atendimento; o valor total é definido no campo de cobrança.</p></Form>})()}
 {modal.type==='appointmentDetail'&&(()=>{const a=s.appointments.find(x=>x.id===modal.data.id)||modal.data,p=petBy(a.petId),ended=['Concluído','Cancelado'].includes(a.status);return <><div className="appointment-detail-top"><button className="pet-cell" onClick={()=>{if(p){setModal(null);openProfile(p)}}}><PetAvatar pet={p} size={60}/><span><strong>{p?.name}</strong><small>{owner(p)?.name}</small></span></button><Status status={a.status}/></div><h3 className="appointment-title">{a.serviceName}</h3><div className="detail-grid"><div><CalendarDays size={18}/><span>Data e horário<strong>{dateLabel(a.date)} às {a.time}</strong></span></div><div><Clock3 size={18}/><span>Duração<strong>{a.duration} minutos</strong></span></div><div><Users size={18}/><span>Profissional<strong>{a.professional}</strong></span></div><div><CreditCard size={18}/><span>Cobrança<strong>{a.packageId?s.subscriptions.find(x=>x.id===a.packageId)?.name:money(a.price)+' · avulso'}</strong></span></div></div>{p?.alerts&&<div className="pet-alert"><AlertTriangle size={18}/><p>{p.alerts}</p></div>}{a.addons.length>0&&<div className="pet-tags">{a.addons.map((x:string)=><span key={x}>{x}</span>)}</div>}{a.notes&&<div className="appointment-notes"><strong>Observações do atendimento</strong><p>{a.notes}</p></div>}{!ended?<><div className="status-actions">{a.status==='Agendado'&&<button className="btn outline" disabled={busy} onClick={()=>act({type:'appointmentStatus',data:{id:a.id,status:'Confirmado'}},'Agendamento confirmado.')}><Check size={16}/> Confirmar</button>}{a.status!=='Em atendimento'&&<button className="btn outline" disabled={busy} onClick={()=>act({type:'appointmentStatus',data:{id:a.id,status:'Em atendimento'}},'Atendimento iniciado.')}><Clock3 size={16}/> Iniciar atendimento</button>}<button className="btn primary" onClick={()=>open('finishAppointment',a)}><CheckCircle2 size={17}/> Concluir</button></div><div className="detail-footer"><button className="text-link" onClick={()=>open('appointment',a)}><Pencil size={15}/> Editar agendamento</button><button className="text-link red-text" onClick={()=>open('cancelAppointment',a)}>Cancelar agendamento</button></div></>:<div className="modal-actions"><button className="btn primary" onClick={()=>open('appointment',{petId:a.petId,serviceId:a.serviceId,category:a.category,date:addDays(d,7),time:a.time})}><CalendarDays size={16}/> Agendar próximo</button>{a.category==='Clínica'&&<button className="btn outline" onClick={()=>open('consultation',{petId:a.petId})}><FileText size={16}/> Registro clínico</button>}</div>}</>})()}
 {modal.type==='finishAppointment'&&<Form busy={busy} label="Confirmar conclusão" onSubmit={f=>act({type:'appointmentStatus',data:{id:modal.data.id,status:'Concluído',paid:f.has('paid')}},'Atendimento concluído e registrado no histórico.')}><p className="modal-intro wide"><strong>{petBy(modal.data.petId)?.name}</strong> · {modal.data.serviceName}<br/>{dateLabel(modal.data.date)} às {modal.data.time}</p>{modal.data.packageId?<div className="form-warning wide"><Package size={20}/><p>Uma sessão será descontada do pacote. O dia e os cuidados serão registrados no histórico da ficha.</p></div>:<><p className="wide form-help">Será gerada uma receita de <strong>{money(modal.data.price)}</strong> no financeiro.</p><div className="wide"><Checked name="paid">O pagamento deste atendimento já foi recebido</Checked></div></>}</Form>}
 {modal.type==='cancelAppointment'&&<><p className="modal-intro">Cancelar o atendimento de <strong>{petBy(modal.data.petId)?.name}</strong> em {dateLabel(modal.data.date)} às {modal.data.time}? O horário será liberado. Nenhuma sessão será consumida.</p><div className="modal-actions"><button className="btn outline" onClick={()=>open('appointmentDetail',modal.data)}>Voltar</button><button className="btn danger" disabled={busy} onClick={()=>act({type:'appointmentStatus',data:{id:modal.data.id,status:'Cancelado'}},'Agendamento cancelado.')}>Cancelar agendamento</button></div></>}
 {modal.type==='consultation'&&<Form busy={busy} label="Salvar registro clínico" onSubmit={f=>act({type:'addConsultation',data:payload(f)},'Registro clínico salvo. O retorno, se informado, foi agendado.')}><Select name="petId" label="Paciente *" required defaultValue={modal.data?.petId||''}>{petOptions()}</Select><Input name="date" label="Data da consulta *" type="date" max={d} defaultValue={d} required/><Input name="professional" label="Veterinário responsável *" defaultValue={professionals().find(x=>x.startsWith('Dr'))||''} required/><Input name="crmv" label="CRMV / UF *" placeholder="Ex.: 12345 / DF" required/><Input name="reason" label="Motivo da consulta *" placeholder="Queixa principal ou avaliação" required wide/><Textarea name="findings" label="Anamnese, exame e avaliação clínica" placeholder="Registre as informações observadas pelo profissional responsável."/><Textarea name="plan" label="Conduta e orientações"/><Input name="nextDate" label="Agendar retorno (opcional)" type="date" min={addDays(d,1)}/><Input name="nextTime" label="Horário do retorno" type="time" defaultValue="09:00"/><p className="form-help wide">Se você informar uma data de retorno, ele será criado na agenda com o mesmo profissional. O registro clínico é um documento operacional e não gera cobrança por si só; conclua o agendamento para registrar a receita.</p></Form>}
 {modal.type==='vaccine'&&<Form busy={busy} label="Registrar aplicação" onSubmit={f=>act({type:'addVaccine',data:payload(f)},'Vacina registrada na ficha do pet.')}><Select name="petId" label="Pet *" defaultValue={modal.data?.petId||''} required>{petOptions()}</Select><Input name="name" label="Nome da vacina *" required placeholder="Ex.: Antirrábica, V10"/><Input name="date" label="Data de aplicação *" type="date" max={d} defaultValue={d} required/><Input name="nextDate" label="Data do próximo reforço" type="date" min={addDays(d,1)}/><Input name="batch" label="Lote *" required/><Input name="manufacturer" label="Fabricante"/><Input name="professional" label="Veterinário responsável *" defaultValue={professionals().find(x=>x.startsWith('Dr'))||''} required/><Input name="crmv" label="CRMV / UF *" placeholder="Ex.: 12345 / DF" required/><p className="form-help wide">A data de reforço é definida pelo veterinário. O sistema apenas registra a aplicação e exibe o lembrete.</p></Form>}
 {modal.type==='product'&&<Form busy={busy} label="Salvar produto" onSubmit={f=>{const v=payload(f);act({type:'saveProduct',data:{...v,id:modal.data?.id,stock:Number(v.stock),minStock:Number(v.minStock),cost:Number(v.cost),price:Number(v.price)}},'Produto salvo.')}}><Input name="name" label="Nome do produto *" defaultValue={modal.data?.name} required wide/><Input name="sku" label="Código / SKU *" defaultValue={modal.data?.sku} required/><Input name="category" label="Categoria *" defaultValue={modal.data?.category||'Acessórios'} list="product-categories" required/><datalist id="product-categories">{['Rações','Acessórios','Higiene e proteção','Comedouros','Brinquedos','Farmácia'].map(c=><option value={c} key={c}/>)}</datalist><Select name="unit" label="Unidade de medida" defaultValue={modal.data?.unit||'un'}><option value="un">Unidade (un)</option><option value="kg">Quilograma (kg)</option><option value="L">Litro (L)</option></Select><Input name="stock" label={modal.data?.id?'Estoque atual':'Estoque inicial *'} type="number" min="0" step="0.001" defaultValue={modal.data?.stock||0} readOnly={!!modal.data?.id} required hint={modal.data?.id?'Use Movimentar para registrar entradas e saídas.':undefined}/><Input name="minStock" label="Estoque mínimo *" type="number" min="0" step="0.001" defaultValue={modal.data?.minStock||0} required/><Input name="cost" label="Custo unitário (R$) *" type="number" min="0" step="0.01" defaultValue={modal.data?.cost||0} required/><Input name="price" label="Preço de venda unitário (R$) *" type="number" min="0" step="0.01" defaultValue={modal.data?.price||0} required/></Form>}
 {modal.type==='stock'&&<Form busy={busy} label="Confirmar movimentação" onSubmit={f=>{const v=payload(f);act({type:'stockMove',data:{...v,quantity:Number(v.quantity),unitPrice:Number(v.unitPrice),paid:f.has('paid')}},'Movimentação registrada. Estoque e financeiro atualizados.')}}><Select name="productId" label="Produto *" value={stockProduct} onChange={(e:any)=>setStockProduct(e.target.value)} required><option value="">Selecione o produto</option>{s.products.map(p=><option key={p.id} value={p.id}>{p.name} · {p.stock} {p.unit} · venda {money(p.price)}</option>)}</Select><Select name="kind" label="Tipo de movimentação *" value={stockKind} onChange={(e:any)=>setStockKind(e.target.value)}><option>Entrada</option><option>Saída</option><option>Venda</option></Select><Input name="quantity" label="Quantidade *" type="number" min="0.001" step="0.001" defaultValue="1" required/><Input key={stockProduct+stockKind} name="unitPrice" label={stockKind==='Venda'?'Preço de venda unitário (R$) *':'Custo unitário (R$) *'} type="number" min="0" step="0.01" defaultValue={stockProduct?(stockKind==='Venda'?s.products.find(p=>p.id===stockProduct)?.price:s.products.find(p=>p.id===stockProduct)?.cost)||0:0} required/><Input name="date" label="Data *" type="date" max={d} defaultValue={d} required/><div className="field check-field"><Checked name="paid">Pagamento já confirmado</Checked></div><Input key={stockKind} name="reason" label="Descrição da movimentação *" defaultValue={stockKind==='Venda'?'Venda no balcão':''} placeholder="Venda no balcão, compra, consumo interno..." wide required/><p className="form-help wide">Venda gera uma receita. Entrada com custo gera uma despesa. Saída registra consumo ou perda, sem movimentação financeira. Estoque inicial é definido no cadastro do produto.</p></Form>}
 {modal.type==='transaction'&&<Form busy={busy} label="Salvar lançamento" onSubmit={f=>{const v=payload(f);act({type:'addTransaction',data:{...v,amount:Number(v.amount),paid:f.has('paid')}},'Lançamento registrado.')}}><Select name="type" label="Tipo *"><option value="income">Receita / entrada</option><option value="expense">Despesa / saída</option></Select><Input name="amount" label="Valor (R$) *" type="number" min="0.01" step="0.01" required/><Input name="description" label="Descrição *" required wide/><Input name="category" label="Categoria *" required placeholder="Ex.: Despesas fixas, Serviços"/><Input name="date" label="Data / vencimento *" type="date" defaultValue={d} required/><div className="wide"><Checked name="paid">Pagamento / recebimento já confirmado</Checked></div></Form>}
 {modal.type==='movements'&&<>{s.movements.length?<div className="table-scroll"><table><thead><tr><th>Data</th><th>Produto</th><th>Tipo</th><th>Quantidade</th><th>Motivo</th></tr></thead><tbody>{[...s.movements].reverse().map(m=><tr key={m.id}><td>{dateLabel(m.date)}</td><td>{s.products.find(p=>p.id===m.productId)?.name}</td><td><Badge tone={m.kind==='Entrada'?'green':'amber'}>{m.kind}</Badge></td><td>{m.quantity}</td><td>{m.reason}</td></tr>)}</tbody></table></div>:<Empty icon={Package} title="Rastreabilidade começa aqui" description="Entradas, saídas e vendas aparecerão neste histórico. Os saldos iniciais ficam no cadastro do produto."/>}</>}
 {modal.type==='whatsapp'&&(()=>{const r=modal.data as Reminder,p=petBy(r.petId),c=owner(p),sub=s.subscriptions.find(x=>x.id===r.refId);let message='';if(r.type==='package'&&sub){if(sub.expiresAt<d)message=s.settings.messageTemplate;else if(sub.used>=sub.total)message='Olá, {tutor}! 🐾 As sessões do pacote {pacote} do(a) {pet} chegaram ao fim. Vamos renovar os cuidados? Entre em contato com a {empresa}!';else message='Olá, {tutor}! 🐾 O pacote {pacote} do(a) {pet} vence em {vencimento}. Vamos combinar a renovação? Esperamos vocês na {empresa}!';for(const [key,value] of Object.entries({tutor:c?.name.split(' ')[0]||'',pet:p?.name||'',pacote:sub.name,vencimento:dateLabel(sub.expiresAt),empresa:brandName}))message=message.split('{'+key+'}').join(value);}else if(r.type==='vaccine'){const v=s.vaccines.find(x=>x.id===r.refId);message=`Olá, ${c?.name.split(' ')[0]}! 🐾 Passando para lembrar do reforço da vacina ${v?.name} do(a) ${p?.name}, previsto para ${dateLabel(r.date)}. Vamos agendar a avaliação com o veterinário? Equipe ${brandName}.`;}else{const apt=s.appointments.find(x=>x.id===r.refId);message=`Olá, ${c?.name.split(' ')[0]}! 🐾 Podemos confirmar o atendimento de ${p?.name}? ${apt?.serviceName} em ${dateLabel(r.date)} às ${apt?.time}, com ${apt?.professional}. Esperamos vocês na ${brandName}!`;}return <form onSubmit={e=>{e.preventDefault();const f=new FormData(e.currentTarget),raw=String(f.get('phone')).replace(/\D/g,'');let number=raw;if(raw.length===10||raw.length===11)number='55'+raw;if(!/^55\d{10,11}$/.test(number)){setError('Informe um telefone brasileiro válido, com DDD.');return}window.open('https://wa.me/'+number+'?text='+encodeURIComponent(String(f.get('message'))),'_blank','noopener,noreferrer');setToast('WhatsApp aberto. Revise e envie a mensagem por lá.')}}><div className="message-recipient"><PetAvatar pet={p} size={48}/><div><strong>{c?.name}</strong><small>Tutor de {p?.name}</small></div><Badge tone="green">Envio manual</Badge></div><div className="form-grid"><Input label="WhatsApp do tutor com DDD *" name="phone" type="tel" defaultValue={c?.phone||''} placeholder="(61) 99999-9999" required wide/><Textarea name="message" label="Revise sua mensagem" defaultValue={message} rows={6} required/></div>{!c?.phone&&<p className="form-help">Este tutor ainda não tem WhatsApp salvo. <button type="button" className="text-link" onClick={()=>open('client',c)}>Cadastrar na ficha</button></p>}<div className="message-note"><MessageCircle size={17}/><p>O envio acontece no WhatsApp, após sua confirmação. Abrir a conversa não significa que a mensagem foi enviada.</p></div><div className="modal-actions"><button type="button" className="btn outline" onClick={async()=>{try{const form=dialogRef.current?.querySelector('form');const text=(form?.querySelector('textarea') as HTMLTextAreaElement)?.value||message;await navigator.clipboard.writeText(text);setToast('Mensagem copiada.')}catch{setError('Não foi possível copiar. Selecione a mensagem e copie manualmente.')}}}><Copy size={16}/> Copiar</button><button type="submit" className="btn whatsapp"><MessageCircle size={17}/> Abrir WhatsApp <ExternalLink size={14}/></button></div><button type="button" disabled={busy} className="register-contact" onClick={()=>act({type:'logContact',data:{refId:r.refId}},'Contato registrado. O lembrete continua até o cuidado ser resolvido.')}><Check size={14}/> Já entrei em contato · registrar</button></form>})()}
 {modal.type==='help'&&<div className="help-content"><span className="start-icon"><Bell size={30}/></span><h3>Você decide quando conversar.</h3><p>O sistema encontra pacotes vencidos ou sem sessões, vacinas próximas ao reforço e atendimentos de hoje e amanhã.</p><p>Clique em <strong>WhatsApp</strong>, revise a mensagem e abra a conversa. Você conclui o envio no próprio aplicativo. Depois, use <strong>Registrar contato</strong> para guardar a data.</p><p>Os lembretes continuam visíveis até a renovação, o novo registro de vacina ou a conclusão do atendimento. A antecedência de pacotes e vacinas pode ser ajustada nas configurações.</p><div className="message-note"><ShieldCheck size={19}/><p>Envios automáticos exigem uma integração com a API oficial do WhatsApp. Nenhuma mensagem é enviada sozinha nesta versão.</p></div></div>}
 </div></section></div>}
 </div>
}
