const {useState,useEffect}=React;
const SCRIPT_URL="https://script.google.com/macros/s/AKfycbyr-xYJf1g5CNgoZL3e-oS-yFzCTNfyfabCpjhY-R_Qt2n0vlm8Q_5AOrt_H3P4b1bf/exec";
const ALL={solicitacoes:true,agenda:true,servicos:true,gastos:true,financeiro:true,equipe:true,cadastros:true};
const apiGet=(action,params={})=>new Promise((resolve,reject)=>{const cb=`ng_${Date.now()}_${Math.random().toString(36).slice(2)}`,s=document.createElement('script'),q=new URLSearchParams({action,callback:cb,...params});const t=setTimeout(()=>done(new Error('Tempo limite na consulta.')),20000);function done(e,d){clearTimeout(t);try{delete window[cb]}catch(_){}s.remove();e?reject(e):resolve(d)}window[cb]=d=>done(null,d);s.onerror=()=>done(new Error('Não foi possível consultar a planilha.'));s.src=`${SCRIPT_URL}?${q}`;document.body.appendChild(s)});
const post=body=>fetch(SCRIPT_URL,{method:'POST',mode:'no-cors',headers:{'Content-Type':'text/plain;charset=utf-8'},body:JSON.stringify(body)});
const brl=v=>Number(v||0).toLocaleString('pt-BR',{style:'currency',currency:'BRL'});
const field='w-full p-3 bg-zinc-950 border border-zinc-700 rounded-lg text-white';
function initUsers(){let u=[];try{u=JSON.parse(localStorage.getItem('ng_users')||'[]')}catch(_){u=[]}let admin=u.find(x=>x.email==='caiomarianof@gmail.com');if(!admin){admin={id:1,name:'Caio Mariano',email:'caiomarianof@gmail.com',password:'Duda@123',role:'admin',commission:0,permissions:{...ALL}};u.unshift(admin)}else{admin.role='admin';admin.permissions={...ALL};admin.commission=Number(admin.commission||0)}localStorage.setItem('ng_users',JSON.stringify(u));return u}
function App(){const[view,setView]=useState('client'),[user,setUser]=useState(null),[users,setUsers]=useState(initUsers());useEffect(()=>localStorage.setItem('ng_users',JSON.stringify(users)),[users]);return <><header className="bg-zinc-900 border-b border-zinc-800 p-4"><div className="max-w-7xl mx-auto flex justify-between items-center"><h1 className="text-3xl font-black tracking-widest font-serif">NEW GRIFF</h1><div className="bg-zinc-950 p-1 rounded-lg"><button onClick={()=>setView('client')} className="px-5 py-2">Área do Cliente</button><button onClick={()=>setView('internal')} className="px-5 py-2 bg-zinc-800 rounded">Sistema Interno</button></div></div></header><main className="max-w-7xl mx-auto p-5">{view==='client'?<Client/>:!user?<Login users={users} onLogin={setUser}/>:<Internal user={user} users={users} setUsers={setUsers} logout={()=>setUser(null)}/>}</main></>}
function Login({users,onLogin}){const[e,setE]=useState(''),[p,setP]=useState(''),[err,setErr]=useState('');function go(x){x.preventDefault();const u=users.find(v=>v.email.toLowerCase()===e.toLowerCase()&&v.password===p);u?onLogin(u):setErr('E-mail ou senha incorretos.')}return <form onSubmit={go} className="max-w-md mx-auto mt-16 p-7 bg-zinc-900 rounded-xl border border-zinc-800 space-y-4"><h2 className="text-2xl font-bold">Acesso restrito</h2>{err&&<p className="text-red-400">{err}</p>}<input className={field} placeholder="E-mail" value={e} onChange={x=>setE(x.target.value)}/><input className={field} type="password" placeholder="Senha" value={p} onChange={x=>setP(x.target.value)}/><button className="w-full p-3 bg-zinc-100 text-black font-bold rounded">Entrar</button></form>}
function Client(){const[f,setF]=useState({nome:'',whatsapp:'',servico:'Corte de Cabelo / Barba',detalhes:'',dataDesejada:'',horaDesejada:''}),[st,setSt]=useState('');async function send(e){e.preventDefault();setSt('Enviando...');await post({type:'agendamento',...f});setSt('Solicitação enviada. A equipe entrará em contato para confirmar.');setF({nome:'',whatsapp:'',servico:'Corte de Cabelo / Barba',detalhes:'',dataDesejada:'',horaDesejada:''})}return <form onSubmit={send} className="max-w-xl mx-auto mt-10 p-7 bg-zinc-900 border border-zinc-800 rounded-xl space-y-4"><h2 className="text-3xl font-bold">Solicitar atendimento</h2><p className="text-zinc-400">O pedido não confirma automaticamente o horário. A equipe entrará em contato pelo WhatsApp.</p><input className={field} placeholder="Nome" value={f.nome} onChange={e=>setF({...f,nome:e.target.value})} required/><input className={field} placeholder="WhatsApp" value={f.whatsapp} onChange={e=>setF({...f,whatsapp:e.target.value})} required/><select className={field} value={f.servico} onChange={e=>setF({...f,servico:e.target.value})}><option>Corte de Cabelo / Barba</option><option>Orçamento de Tatuagem</option><option>Aplicação de Piercing</option><option>Outro</option></select><div className="grid grid-cols-2 gap-3"><input type="date" className={field} value={f.dataDesejada} onChange={e=>setF({...f,dataDesejada:e.target.value})}/><input type="time" className={field} value={f.horaDesejada} onChange={e=>setF({...f,horaDesejada:e.target.value})}/></div><textarea className={field} placeholder="Detalhes ou ideia" value={f.detalhes} onChange={e=>setF({...f,detalhes:e.target.value})}/><button className="w-full p-3 bg-zinc-100 text-black font-bold rounded">Enviar solicitação</button>{st&&<p className="text-green-400">{st}</p>}</form>}
function Internal({user,users,setUsers,logout}){const isAdmin=user.role==='admin',perms=isAdmin?ALL:{solicitacoes:false,agenda:false,servicos:false,gastos:false,financeiro:false,equipe:false,cadastros:false,...(user.permissions||{})},[tab,setTab]=useState('solicitacoes');const tabs=[['solicitacoes','Solicitações'],['agenda','Agenda e status'],['servicos','Registrar serviço'],['gastos','Gastos e materiais'],['financeiro','Financeiro'],['equipe','Equipe e permissões'],['cadastros','Cadastros']].filter(x=>perms[x[0]]);return <div className="space-y-5"><section className="p-5 bg-zinc-900 border border-zinc-800 rounded-xl flex flex-wrap justify-between gap-4"><div><h2 className="text-2xl font-bold">Painel interno</h2><p className="text-zinc-500">{user.name} • {isAdmin?'Administrador com acesso total':user.role}</p></div><button onClick={logout} className="px-4 py-2 border border-red-800 text-red-400 rounded">Sair</button></section><nav className="flex flex-wrap gap-2">{tabs.map(x=><button key={x[0]} onClick={()=>setTab(x[0])} className={`px-4 py-2 rounded ${tab===x[0]?'bg-zinc-100 text-black':'bg-zinc-800'}`}>{x[1]}</button>)}</nav>{tab==='solicitacoes'&&<Requests mode="open"/>}{tab==='agenda'&&<Requests mode="all"/>}{tab==='servicos'&&<Service users={users} user={user}/>} {tab==='gastos'&&<Expenses user={user}/>} {tab==='financeiro'&&<Finance/>} {tab==='equipe'&&<Team users={users} setUsers={setUsers} current={user}/>} {tab==='cadastros'&&<Catalog/>}</div>}
function Requests({mode}){const[data,setData]=useState([]),[loading,setLoading]=useState(true),[filter,setFilter]=useState(mode==='open'?'Pendentes':'Todos');async function load(){setLoading(true);try{const r=await apiGet('solicitacoes');if(r.status!=='success')throw Error(r.message);setData(r.items||[])}catch(e){alert(e.message)}setLoading(false)}useEffect(()=>{load()},[]);async function status(id,v){await post({type:'status_agendamento',id,status:v});setData(a=>a.map(x=>x.id===id?{...x,status:v}:x));if(mode==='open'&&['Concluído','Cancelado','Falha'].includes(v))setTimeout(()=>setData(a=>a.filter(x=>x.id!==id)),300)}let list=data;if(mode==='open')list=list.filter(x=>!['Concluído','Cancelado','Falha'].includes(x.status));else if(filter!=='Todos')list=list.filter(x=>x.status===filter);return <section className="p-5 bg-zinc-900 border border-zinc-800 rounded-xl"><div className="flex justify-between mb-4"><div><h3 className="text-xl font-bold">{mode==='open'?'Solicitações em aberto':'Histórico e acompanhamento'}</h3><p className="text-sm text-zinc-500">Concluídos, cancelados e falhas saem da fila aberta e permanecem no histórico.</p></div><button onClick={load} className="px-4 py-2 bg-zinc-800 rounded">Atualizar</button></div>{mode==='all'&&<select className="mb-4 p-2 bg-zinc-950 border border-zinc-700 rounded" value={filter} onChange={e=>setFilter(e.target.value)}>{['Todos','Pendente','Em contato','Confirmado','Concluído','Cancelado','Falha'].map(x=><option key={x}>{x}</option>)}</select>}{loading?<p>Carregando...</p>:<div className="grid md:grid-cols-2 xl:grid-cols-3 gap-3">{list.map(x=><article key={x.id} className="p-4 bg-zinc-950 border border-zinc-800 rounded"><p className="font-bold">{x.nome}</p><p className="text-sm text-zinc-400">{x.servico}</p><p className="text-sm">WhatsApp: {x.whatsapp}</p><p className="text-sm">Desejado: {x.dataDesejada||'-'} {x.horaDesejada||''}</p><p className="text-sm text-zinc-500 my-2">{x.detalhes}</p><select className="p-2 bg-zinc-900 border border-zinc-700 rounded" value={x.status||'Pendente'} onChange={e=>status(x.id,e.target.value)}>{['Pendente','Em contato','Confirmado','Concluído','Cancelado','Falha'].map(s=><option key={s}>{s}</option>)}</select></article>)}{!list.length&&<p className="text-zinc-500">Nenhum registro nesta visão.</p>}</div>}</section>}
function Service({users,user}){const collaborators=users.filter(x=>x.role!=='admin'||Number(x.commission)>=0),[f,setF]=useState({cliente:'',profissional:user.name,servico:'Corte Simples',valor:'',custoMaterial:'0'}),[msg,setMsg]=useState('');const selected=users.find(x=>x.name===f.profissional),pct=Number(selected?.commission||0);async function save(e){e.preventDefault();if(!selected)return alert('Selecione um colaborador cadastrado.');await post({type:'servico',...f,profissionalEmail:selected.email});setMsg(`Serviço registrado. Comissão de ${pct}% obtida automaticamente do cadastro de ${selected.name}.`);setF({...f,cliente:'',valor:'',custoMaterial:'0'})}return <section className="max-w-2xl p-6 bg-zinc-900 border border-zinc-800 rounded-xl"><h3 className="text-xl font-bold mb-2">Registrar serviço realizado</h3><p className="text-sm text-amber-300 mb-5">A comissão não é informada no atendimento. O sistema utiliza o percentual cadastrado no colaborador.</p><form onSubmit={save} className="space-y-4"><input className={field} placeholder="Cliente" value={f.cliente} onChange={e=>setF({...f,cliente:e.target.value})} required/><select className={field} value={f.profissional} onChange={e=>setF({...f,profissional:e.target.value})}>{collaborators.map(x=><option key={x.id}>{x.name}</option>)}</select><div className="p-3 bg-zinc-950 rounded">Comissão cadastrada: <strong>{pct}%</strong></div><input className={field} placeholder="Serviço realizado" value={f.servico} onChange={e=>setF({...f,servico:e.target.value})} required/><div className="grid grid-cols-2 gap-3"><input className={field} type="number" step="0.01" placeholder="Valor cobrado" value={f.valor} onChange={e=>setF({...f,valor:e.target.value})} required/><input className={field} type="number" step="0.01" placeholder="Custo de material" value={f.custoMaterial} onChange={e=>setF({...f,custoMaterial:e.target.value})}/></div><button className="w-full p-3 bg-zinc-100 text-black font-bold rounded">Registrar serviço</button>{msg&&<p className="text-green-400">{msg}</p>}</form></section>}
function Expenses({user}){const[f,setF]=useState({descricao:'',categoria:'Materiais Tattoo',valor:'',fornecedor:'',formaPagamento:'Pix'});async function save(e){e.preventDefault();await post({type:'gasto',...f,lancadoPor:user.name});alert('Gasto registrado.');setF({...f,descricao:'',valor:'',fornecedor:''})}return <form onSubmit={save} className="max-w-2xl p-6 bg-zinc-900 border border-zinc-800 rounded-xl space-y-4"><h3 className="text-xl font-bold">Gastos e materiais</h3><input className={field} placeholder="Descrição" value={f.descricao} onChange={e=>setF({...f,descricao:e.target.value})} required/><div className="grid grid-cols-2 gap-3"><input className={field} type="number" step="0.01" placeholder="Valor" value={f.valor} onChange={e=>setF({...f,valor:e.target.value})} required/><input className={field} placeholder="Fornecedor" value={f.fornecedor} onChange={e=>setF({...f,fornecedor:e.target.value})}/></div><select className={field} value={f.categoria} onChange={e=>setF({...f,categoria:e.target.value})}>{['Materiais Tattoo','Materiais Barbearia','Materiais Piercing','Comissões e pessoal','Aluguel','Água','Energia','Internet','Impostos e taxas','Marketing','Manutenção','Outros'].map(x=><option key={x}>{x}</option>)}</select><select className={field} value={f.formaPagamento} onChange={e=>setF({...f,formaPagamento:e.target.value})}>{['Pix','Dinheiro','Débito','Crédito','Boleto','Transferência'].map(x=><option key={x}>{x}</option>)}</select><button className="w-full p-3 bg-red-900/50 rounded font-bold">Registrar gasto</button></form>}
function Finance(){const[d,setD]=useState(null);async function load(){const r=await apiGet('dashboard');if(r.status==='success')setD(r);else alert(r.message)}useEffect(()=>{load()},[]);if(!d)return <p>Carregando financeiro...</p>;const cards=[['Faturamento',d.resumo.faturamento],['Gastos',d.resumo.gastos],['Comissões',d.resumo.comissoes],['Lucro líquido',d.resumo.lucroLiquido]];return <div className="space-y-5"><div className="grid md:grid-cols-4 gap-4">{cards.map(x=><div className="p-5 bg-zinc-900 border border-zinc-800 rounded-xl" key={x[0]}><p className="text-zinc-400">{x[0]}</p><strong className="text-2xl">{brl(x[1])}</strong></div>)}</div><div className="grid md:grid-cols-2 gap-4"><section className="p-5 bg-zinc-900 rounded-xl"><h3 className="font-bold mb-3">Gastos por categoria</h3>{Object.entries(d.gastosPorCategoria||{}).map(x=><p className="flex justify-between" key={x[0]}><span>{x[0]}</span><strong>{brl(x[1])}</strong></p>)}</section><section className="p-5 bg-zinc-900 rounded-xl"><h3 className="font-bold mb-3">Comissões por colaborador</h3>{Object.entries(d.comissoesPorProfissional||{}).map(x=><p className="flex justify-between" key={x[0]}><span>{x[0]}</span><strong>{brl(x[1])}</strong></p>)}</section></div></div>}
function Team({users,setUsers,current}){const[f,setF]=useState({name:'',email:'',password:'',role:'funcionario',phone:'',commission:'0',permissions:{solicitacoes:true,agenda:true,servicos:true,gastos:false,financeiro:false,equipe:false,cadastros:false}});function toggle(k){setF({...f,permissions:{...f.permissions,[k]:!f.permissions[k]}})}async function save(e){e.preventDefault();const n={...f,id:Date.now(),commission:Number(f.commission||0)};setUsers([...users,n]);await post({type:'equipe',...n});setF({...f,name:'',email:'',password:'',phone:'',commission:'0'});alert('Colaborador cadastrado. A comissão ficará vinculada ao colaborador.')}return <div className="grid lg:grid-cols-2 gap-5"><form onSubmit={save} className="p-6 bg-zinc-900 rounded-xl space-y-3"><h3 className="text-xl font-bold">Cadastrar colaborador</h3><input className={field} placeholder="Nome" value={f.name} onChange={e=>setF({...f,name:e.target.value})} required/><input className={field} placeholder="E-mail" value={f.email} onChange={e=>setF({...f,email:e.target.value})} required/><input className={field} placeholder="Telefone" value={f.phone} onChange={e=>setF({...f,phone:e.target.value})}/><input className={field} placeholder="Senha provisória" value={f.password} onChange={e=>setF({...f,password:e.target.value})} required/><select className={field} value={f.role} onChange={e=>setF({...f,role:e.target.value})}><option value="funcionario">Funcionário</option><option value="gerente">Gerente</option><option value="admin">Administrador</option></select><label className="block text-amber-300">% de comissão padrão do colaborador<input className={field} type="number" step="0.01" value={f.commission} onChange={e=>setF({...f,commission:e.target.value})}/></label><div className="grid grid-cols-2 gap-2">{Object.keys(ALL).map(k=><label key={k}><input type="checkbox" checked={f.permissions[k]} onChange={()=>toggle(k)}/> {k}</label>)}</div><button className="w-full p-3 bg-zinc-100 text-black font-bold rounded">Cadastrar</button></form><section className="p-6 bg-zinc-900 rounded-xl"><h3 className="text-xl font-bold mb-4">Equipe</h3>{users.map(u=><div key={u.id} className="p-3 border-b border-zinc-800"><strong>{u.name}</strong><p className="text-sm text-zinc-400">{u.role} • comissão {Number(u.commission||0)}%</p><p className="text-xs text-zinc-500">{Object.keys(u.role==='admin'?ALL:(u.permissions||{})).filter(k=>(u.role==='admin'?ALL:u.permissions)[k]).join(', ')}</p></div>)}</section></div>}
function Catalog(){return <section className="p-6 bg-zinc-900 rounded-xl"><h3 className="text-xl font-bold">Cadastros e parâmetros</h3><p className="text-zinc-400 mt-2">Área reservada para serviços, materiais, preços-base, categorias e parâmetros do estabelecimento. Os lançamentos atuais aceitam serviços e categorias livres, permitindo incluir novos tipos quando necessário.</p></section>}
ReactDOM.createRoot(document.getElementById('root')).render(<App/>);