import React, {useEffect,useMemo,useState} from 'react';
import {createRoot} from 'react-dom/client';
import {createClient} from '@supabase/supabase-js';
import {Plane,Plus,LogOut,CalendarDays,Wallet,Hotel,Ticket,MapPin,Users,ShieldCheck,ChevronLeft,Trash2,Check,Mail,ExternalLink} from 'lucide-react';
import './style.css';
const url=import.meta.env.VITE_SUPABASE_URL;
const key=import.meta.env.VITE_SUPABASE_ANON_KEY;
const supabase=url&&key?createClient(url,key):null;
const today=()=>new Date().toISOString().slice(0,10);
const money=(n,c='EUR')=>new Intl.NumberFormat('es-ES',{style:'currency',currency:c}).format(Number(n)||0);
const readable=(d)=>d?new Date(d+'T12:00:00').toLocaleDateString('es-ES',{day:'numeric',month:'short',year:'numeric'}):'—';
function App(){
 const [session,setSession]=useState(null),[ready,setReady]=useState(false),[authMode,setAuthMode]=useState('login'),[email,setEmail]=useState(''),[password,setPassword]=useState('');
 const [trips,setTrips]=useState([]),[active,setActive]=useState(null),[items,setItems]=useState([]),[members,setMembers]=useState([]),[invites,setInvites]=useState([]),[pending,setPending]=useState([]);
 const [tab,setTab]=useState('itinerary'),[notice,setNotice]=useState(''),[busy,setBusy]=useState(false),[showTrip,setShowTrip]=useState(false),[showItem,setShowItem]=useState(false);
 const [tripDraft,setTripDraft]=useState({title:'',destination:'',start_date:today(),end_date:today(),currency:'EUR'});
 const [itemDraft,setItemDraft]=useState({category:'activity',title:'',start_at:'',end_at:'',location:'',confirmation:'',amount:'',notes:''});
 const [inviteEmail,setInviteEmail]=useState(''),[inviteRole,setInviteRole]=useState('editor');
 const error=(e)=>setNotice(e?.message||String(e));
 useEffect(()=>{if(!supabase){setReady(true);return;}supabase.auth.getSession().then(({data})=>{setSession(data.session);setReady(true);});const {data:{subscription}}=supabase.auth.onAuthStateChange((_event,s)=>setSession(s));return()=>subscription.unsubscribe()},[]);
 async function loadTrips(){if(!session)return;const {data,error:e}=await supabase.from('trips').select('*').order('created_at',{ascending:false});if(e)return error(e);setTrips(data||[]);if(active&&!data?.some(t=>t.id===active.id))setActive(null);}
 async function loadPending(){const {data,error:e}=await supabase.from('trip_invitations').select('id,email,role,status,created_at,trip_id,trips(title,destination)').eq('status','pending');if(e)return error(e);setPending(data||[])}
 async function loadDetail(id){const [a,b,c]=await Promise.all([supabase.from('trip_entries').select('*').eq('trip_id',id).order('start_at',{ascending:true}),supabase.from('trip_members').select('user_id,role,joined_at').eq('trip_id',id),supabase.from('trip_invitations').select('id,email,role,status,created_at').eq('trip_id',id).order('created_at',{ascending:false})]);if(a.error)error(a.error);else setItems(a.data||[]);if(b.error)error(b.error);else setMembers(b.data||[]);if(c.error)error(c.error);else setInvites(c.data||[])}
 useEffect(()=>{if(session){loadTrips();loadPending()}else{setTrips([]);setActive(null);setPending([])}},[session?.user.id]);
 useEffect(()=>{if(active)loadDetail(active.id)},[active?.id]);
 async function perform(action){setBusy(true);setNotice('');try{await action()}catch(e){error(e)}finally{setBusy(false)}}
 async function auth(e){e.preventDefault();perform(async()=>{const {error:e,data}=await (authMode==='login'?supabase.auth.signInWithPassword({email,password}):supabase.auth.signUp({email,password}));if(e)throw e;if(authMode==='signup'&&!data.session)setNotice('Comprueba tu correo para confirmar tu cuenta.');})}
 async function createTrip(e){e.preventDefault();perform(async()=>{if(tripDraft.end_date<tripDraft.start_date)throw Error('La fecha final no puede ser anterior al inicio.');const {data,error:e}=await supabase.from('trips').insert({...tripDraft,owner_id:session.user.id}).select().single();if(e)throw e;setShowTrip(false);setActive(data);await loadTrips()})}
 async function saveEntry(e){e.preventDefault();perform(async()=>{if(!itemDraft.title.trim())throw Error('Añade un título.');const row={trip_id:active.id,category:itemDraft.category,title:itemDraft.title,start_at:itemDraft.start_at||null,end_at:itemDraft.end_at||null,location:itemDraft.location||null,confirmation:itemDraft.confirmation||null,notes:itemDraft.notes||null,amount:itemDraft.amount===''?null:Number(itemDraft.amount),created_by:session.user.id};const {error:e}=await supabase.from('trip_entries').insert(row);if(e)throw e;setShowItem(false);setItemDraft({category:'activity',title:'',start_at:'',end_at:'',location:'',confirmation:'',amount:'',notes:''});await loadDetail(active.id)})}
 async function removeEntry(id){if(!confirm('¿Eliminar este elemento?'))return;perform(async()=>{const {error:e}=await supabase.from('trip_entries').delete().eq('id',id);if(e)throw e;await loadDetail(active.id)})}
 async function sendInvite(e){e.preventDefault();perform(async()=>{const {error:e}=await supabase.rpc('create_trip_invitation',{p_trip_id:active.id,p_email:inviteEmail.trim().toLowerCase(),p_role:inviteRole});if(e)throw e;setInviteEmail('');setNotice('Invitación preparada. La persona verá la invitación al iniciar sesión con ese correo.');await loadDetail(active.id)})}
 async function acceptInvite(id,accept){perform(async()=>{const {error:e}=await supabase.rpc('respond_to_invitation',{p_invitation_id:id,p_accept:accept});if(e)throw e;await Promise.all([loadPending(),loadTrips()]);if(active)await loadDetail(active.id)})}
 async function deleteTrip(){if(!confirm('¿Eliminar permanentemente el viaje y todas sus reservas?'))return;perform(async()=>{const {error:e}=await supabase.from('trips').delete().eq('id',active.id);if(e)throw e;setActive(null);await loadTrips()})}
 const role=active?(active.owner_id===session?.user.id?'owner':members.find(m=>m.user_id===session?.user.id)?.role):null;
 const canEdit=role==='owner'||role==='editor';const total=useMemo(()=>items.reduce((n,i)=>n+(Number(i.amount)||0),0),[items]);
 const groups=useMemo(()=>Object.entries(items.filter(i=>i.category!=='expense').reduce((a,i)=>{const k=i.start_at?i.start_at.slice(0,10):'Sin fecha';(a[k]??=[]).push(i);return a},{})),[items]);
 if(!ready)return <div className="center">Cargando MyTrips…</div>;
 if(!supabase)return <div className="center"><div className="panel narrow"><Plane size={40} color="#0e766e"/><h1>MyTrips</h1><p>Configura las variables de entorno <code>VITE_SUPABASE_URL</code> y <code>VITE_SUPABASE_ANON_KEY</code> para activar la app.</p><p>Consulta README.md para las instrucciones.</p></div></div>;
 if(!session)return <div className="authPage"><div className="authHero"><Plane size={45}/><h1>MyTrips</h1><p>Tus viajes, a tu manera.</p><p>Privados hasta que decidas compartirlos.</p></div><form className="panel authForm" onSubmit={auth}><h2>{authMode==='login'?'Bienvenido de nuevo':'Crea tu cuenta'}</h2><label>Correo electrónico<input type="email" required autoComplete="email" value={email} onChange={e=>setEmail(e.target.value)}/></label><label>Contraseña<input type="password" required minLength="6" autoComplete={authMode==='login'?'current-password':'new-password'} value={password} onChange={e=>setPassword(e.target.value)}/></label><button disabled={busy}>{authMode==='login'?'Iniciar sesión':'Crear cuenta'}</button><button className="plain" type="button" onClick={()=>setAuthMode(authMode==='login'?'signup':'login')}>{authMode==='login'?'¿No tienes cuenta? Regístrate':'Ya tengo una cuenta'}</button>{notice&&<p className="message">{notice}</p>}</form></div>;
 return <div className="shell"><aside className="sidebar"><div className="logo"><Plane/> MyTrips</div><p className="sideHeading">TUS VIAJES</p><button className={'nav '+(!active?'selected':'')} onClick={()=>setActive(null)}><CalendarDays size={18}/> Todos los viajes</button>{trips.map(t=><button key={t.id} className={'nav '+(active?.id===t.id?'selected':'')} onClick={()=>{setActive(t);setTab('itinerary')}}><MapPin size={16}/><span>{t.title}</span></button>)}<div className="sideBottom"><span title={session.user.email}>{session.user.email}</span><button className="plain" onClick={()=>supabase.auth.signOut()}><LogOut size={16}/> Salir</button></div></aside><main className="main"><header className="topbar"><span className="mobileLogo"><Plane size={19}/> MyTrips</span><span className="account">{session.user.email}</span><button className="small outline" onClick={()=>supabase.auth.signOut()}>Salir</button></header>{notice&&<div className="toast" role="status">{notice}<button className="plain" onClick={()=>setNotice('')}>×</button></div>}
 {!active?<><div className="heading"><div><p className="eyebrow">PLANIFICA SIN LÍMITES</p><h1>Mis viajes</h1><p className="muted">Cada viaje es privado hasta que invites a alguien.</p></div><button onClick={()=>setShowTrip(true)}><Plus size={18}/> Nuevo viaje</button></div>{pending.length>0&&<section className="panel"><h2><Mail size={19}/> Invitaciones recibidas</h2>{pending.map(p=><div className="inviteLine" key={p.id}><div><b>{p.trips?.title||'Viaje'}</b><p className="muted">{p.trips?.destination} · Acceso: {p.role}</p></div><div className="actions"><button className="small" onClick={()=>acceptInvite(p.id,true)}>Aceptar</button><button className="small outline" onClick={()=>acceptInvite(p.id,false)}>Rechazar</button></div></div>)}</section>}{trips.length===0?<div className="empty"><MapPin size={42}/><h2>Tu próximo viaje comienza aquí</h2><p>Crea un viaje y organiza todo en un solo lugar.</p><button onClick={()=>setShowTrip(true)}>Crear mi primer viaje</button></div>:<div className="tripGrid">{trips.map(t=><button className="tripCard" key={t.id} onClick={()=>setActive(t)}><div className="cardIllustration"><Plane size={32}/></div><div className="cardBody"><p className="eyebrow">{t.owner_id===session.user.id?'TU VIAJE':'COMPARTIDO CONTIGO'}</p><h2>{t.title}</h2><p><MapPin size={15}/> {t.destination||'Destino por definir'}</p><p><CalendarDays size={15}/> {readable(t.start_date)} — {readable(t.end_date)}</p></div></button>)}</div>}</>:<><button className="back plain" onClick={()=>setActive(null)}><ChevronLeft size={18}/> Mis viajes</button><section className="tripBanner"><p className="eyebrow">{role==='owner'?'VIAJE PRIVADO · PROPIETARIO':'VIAJE COMPARTIDO'}</p><h1>{active.title}</h1><p><MapPin size={17}/> {active.destination||'Destino por definir'} <span>·</span> {readable(active.start_date)} — {readable(active.end_date)}</p></section><div className="tabs">{[['itinerary','Itinerario',CalendarDays],['bookings','Reservas',Ticket],['expenses','Gastos',Wallet],['team','Personas',Users]].map(([id,label,Icon])=><button key={id} className={tab===id?'active':''} onClick={()=>setTab(id)}><Icon size={17}/>{label}</button>)}</div>
 {tab==='itinerary'&&<section><div className="sectionTop"><div><h2>Itinerario</h2><p className="muted">Actividades y planes de cada día.</p></div>{canEdit&&<button onClick={()=>{setItemDraft(d=>({...d,category:'activity'}));setShowItem(true)}}><Plus size={17}/> Añadir</button>}</div>{groups.length===0?<div className="empty compact">Aún no hay actividades. Empieza por añadir la primera.</div>:groups.map(([day,entries])=><div className="day" key={day}><h3>{day==='Sin fecha'?day:readable(day)}</h3>{entries.map(i=><Entry key={i.id} item={i} canEdit={canEdit} remove={()=>removeEntry(i.id)}/>)}</div>)}</section>}
 {tab==='bookings'&&<section><div className="sectionTop"><div><h2>Reservas</h2><p className="muted">Vuelos, hoteles y transportes.</p></div>{canEdit&&<button onClick={()=>{setItemDraft(d=>({...d,category:'flight'}));setShowItem(true)}}><Plus size={17}/> Reserva</button>}</div>{items.filter(i=>['flight','hotel','transport'].includes(i.category)).length===0?<div className="empty compact">No hay reservas todavía.</div>:items.filter(i=>['flight','hotel','transport'].includes(i.category)).map(i=><Entry key={i.id} item={i} canEdit={canEdit} remove={()=>removeEntry(i.id)}/>)}</section>}
 {tab==='expenses'&&<section><div className="sectionTop"><div><h2>Gastos</h2><p className="muted">Total registrado en todas las categorías.</p></div>{canEdit&&<button onClick={()=>{setItemDraft(d=>({...d,category:'expense'}));setShowItem(true)}}><Plus size={17}/> Gasto</button>}</div><div className="stat"><Wallet size={22}/><div><span>Total presupuestado / registrado</span><strong>{money(total,active.currency)}</strong></div></div>{items.filter(i=>i.amount!=null).map(i=><div className="entry" key={i.id}><span>{i.title}</span><strong>{money(i.amount,active.currency)}</strong></div>)}</section>}
 {tab==='team'&&<section><div className="sectionTop"><div><h2>Personas y privacidad</h2><p className="muted">Solo los miembros invitados pueden consultar este viaje.</p></div><ShieldCheck color="#0e766e"/></div><div className="panel"><h3>Miembros</h3><p className="muted">Propietario · {active.owner_id===session.user.id?'Tú':active.owner_id.slice(0,8)+'…'}</p>{members.map(m=><p key={m.user_id} className="member">{m.user_id===session.user.id?'Tú':m.user_id.slice(0,8)+'…'} <span>{m.role}</span></p>)}</div>{role==='owner'&&<div className="panel"><h3>Invitar a otra persona</h3><p className="muted">La persona debe registrarse con el mismo correo. Cuando entre, verá tu invitación pendiente.</p><form className="inlineForm" onSubmit={sendInvite}><input type="email" required placeholder="persona@ejemplo.com" value={inviteEmail} onChange={e=>setInviteEmail(e.target.value)}/><select value={inviteRole} onChange={e=>setInviteRole(e.target.value)}><option value="editor">Editor</option><option value="viewer">Solo lectura</option></select><button disabled={busy}>Invitar</button></form>{invites.length>0&&<div className="invites"><h3>Invitaciones enviadas</h3>{invites.map(i=><p key={i.id}>{i.email} · {i.role} · {i.status}</p>)}</div>}</div>}{role==='owner'&&<button className="danger outline" onClick={deleteTrip}><Trash2 size={17}/> Eliminar viaje</button>}</section>}
 </>}
 </main>
 {showTrip&&<div className="overlay" onMouseDown={e=>e.target===e.currentTarget&&setShowTrip(false)}><form className="modal" onSubmit={createTrip}><h2>Crear viaje</h2><label>Nombre del viaje<input required maxLength="120" value={tripDraft.title} onChange={e=>setTripDraft({...tripDraft,title:e.target.value})} placeholder="Verano en Italia"/></label><label>Destino<input value={tripDraft.destination} onChange={e=>setTripDraft({...tripDraft,destination:e.target.value})} placeholder="Italia"/></label><div className="two"><label>Desde<input required type="date" value={tripDraft.start_date} onChange={e=>setTripDraft({...tripDraft,start_date:e.target.value})}/></label><label>Hasta<input required type="date" value={tripDraft.end_date} onChange={e=>setTripDraft({...tripDraft,end_date:e.target.value})}/></label></div><label>Moneda<select value={tripDraft.currency} onChange={e=>setTripDraft({...tripDraft,currency:e.target.value})}><option>EUR</option><option>USD</option><option>GBP</option><option>CHF</option></select></label><div className="actions"><button type="button" className="outline" onClick={()=>setShowTrip(false)}>Cancelar</button><button disabled={busy}>Crear viaje</button></div></form></div>}
 {showItem&&<div className="overlay" onMouseDown={e=>e.target===e.currentTarget&&setShowItem(false)}><form className="modal" onSubmit={saveEntry}><h2>Añadir al viaje</h2><label>Tipo<select value={itemDraft.category} onChange={e=>setItemDraft({...itemDraft,category:e.target.value})}>{[['activity','Actividad'],['flight','Vuelo'],['hotel','Alojamiento'],['transport','Transporte'],['expense','Gasto']].map(([v,l])=><option value={v} key={v}>{l}</option>)}</select></label><label>Título<input required maxLength="180" placeholder="Visita al museo / Vuelo LH123" value={itemDraft.title} onChange={e=>setItemDraft({...itemDraft,title:e.target.value})}/></label><div className="two"><label>Inicio<input type="datetime-local" value={itemDraft.start_at} onChange={e=>setItemDraft({...itemDraft,start_at:e.target.value})}/></label><label>Fin<input type="datetime-local" value={itemDraft.end_at} onChange={e=>setItemDraft({...itemDraft,end_at:e.target.value})}/></label></div><label>Lugar<input value={itemDraft.location} onChange={e=>setItemDraft({...itemDraft,location:e.target.value})}/></label><label>Referencia de reserva<input value={itemDraft.confirmation} onChange={e=>setItemDraft({...itemDraft,confirmation:e.target.value})}/></label><label>Importe ({active?.currency})<input type="number" step="0.01" min="0" value={itemDraft.amount} onChange={e=>setItemDraft({...itemDraft,amount:e.target.value})}/></label><label>Notas<textarea rows="3" value={itemDraft.notes} onChange={e=>setItemDraft({...itemDraft,notes:e.target.value})}/></label><div className="actions"><button type="button" className="outline" onClick={()=>setShowItem(false)}>Cancelar</button><button disabled={busy}>Guardar</button></div></form></div>}
 </div>
}
function Entry({item,canEdit,remove}){let Icon=item.category==='flight'?Plane:item.category==='hotel'?Hotel:item.category==='transport'?Ticket:MapPin;return <div className="entry"><div className="entryIcon"><Icon size={19}/></div><div className="entryText"><strong>{item.title}</strong><p>{item.start_at?new Date(item.start_at).toLocaleString('es-ES',{dateStyle:'medium',timeStyle:'short'}):'Sin fecha'}{item.location?' · '+item.location:''}</p>{item.confirmation&&<small>Reserva: {item.confirmation}</small>}{item.notes&&<small>{item.notes}</small>}</div>{canEdit&&<button className="iconButton" onClick={remove} aria-label={'Eliminar '+item.title}><Trash2 size={17}/></button>}</div>}
createRoot(document.getElementById('root')).render(<App/>);
