const { Button, IconButton, Card, Icon, Input, Dialog, Badge } = window.MiradorDesignSystem_4bae5c;

/* Shared chrome + data helpers for the Propiedades pages.
   El catálogo se lee en vivo de /api/propiedades (Pages Function que consulta
   Notion); si ese endpoint no responde, se usa la copia local del catálogo. */
/* Rutas. En producción (Cloudflare Pages) las URLs son limpias: /propiedades,
   /propiedad/<id>-<slug>. Dentro del editor los archivos se sirven con .html,
   así que el modo se deduce de la ruta actual y los enlaces siguen funcionando
   en los dos sitios sin tocar nada. */
const FILEMODE = /\.html$/i.test(location.pathname);
const route = (n) => FILEMODE ? n + '.html' : (n === 'index' ? '/' : '/' + n);
const slug = (s = '') => s.toString().normalize('NFD').replace(/[\u0300-\u036f]/g, '')
  .toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 70);

const BACKEND = {
  site: 'https://casamia.ec',
  rest: { properties: location.protocol === 'file:' ? '' : '/api/propiedades' },
  mapsKey: 'AIzaSyDGMOzVpE20bL5dzuaJioko3FZJPjIJqqk',
  whatsapp: '593988957054',
  links: {
    inicio: route('index'), compra: route('propiedades'), cuenta: route('cuenta'), panel: route('panel'),
    publicar: route('publicar'), creditos: route('creditos'),
    contacto: route('contacto'), novedades: route('novedades'),
    facebook: 'https://web.facebook.com/casamia.ec.quito/', instagram: 'https://www.instagram.com/casamia.ecuador/',
    tiktok: 'https://www.tiktok.com/@casamia.ecuador', agencia: 'https://agavemkt.com'
  }
};
const WA = (t) => `https://wa.me/${BACKEND.whatsapp}?text=${encodeURIComponent(t || 'Hola, me gustaría recibir asistencia.')}`;
const money = (n) => '$' + Number(n).toLocaleString('es-EC').replace(/,/g, '.');
const num = (n) => Number(n).toLocaleString('es-EC', { maximumFractionDigits: 1 }).replace(/,/g, ',');
/* Los enlaces del propio sitio se abren en la misma pestaña; WhatsApp, redes y
   correo sí en una nueva, que es lo que espera quien vuelve al anuncio. */
const go = (url) => {
  const fuera = /^(mailto:|tel:)/i.test(url) || (/^https?:\/\//i.test(url) && !url.startsWith(location.origin));
  if (fuera) window.open(url, '_blank', 'noopener'); else location.href = url;
};
const detailUrl = (id, titulo) => FILEMODE
  ? 'ficha.html?id=' + encodeURIComponent(id)
  : '/propiedad/' + encodeURIComponent(id) + (titulo ? '-' + slug(titulo) : '');
/* Artículo del blog: /novedades/<slug> en producción. */
const artUrl = (s) => FILEMODE ? 'articulo.html?slug=' + encodeURIComponent(s) : '/novedades/' + s;
/* Portada de un artículo. La real viene de Notion (columna Portada o la imagen
   de cubierta de la página) o de la imagen destacada de WordPress; si el
   artículo no tiene ninguna, la API toma la primera foto de su propio cuerpo.
   Solo cuando no hay absolutamente ninguna imagen se usa una foto del banco
   local del sitio —nunca stock ajeno al tema. */
/* La portada de un artículo es SIEMPRE la del blog: la imagen destacada de
   WordPress (o la primera imagen de su cuerpo, que ya resuelve la API). Nunca
   una foto de una propiedad. */
const portadaArt = (a = {}) => a.portada || '';
/* Varios artículos migrados de WordPress guardan su imagen destacada como
   casamia.ec/wp-content/uploads/..., una ruta que ya no existe ahora que el
   dominio apunta al sitio nuevo. Sin esto se ve el icono de imagen rota; con
   esto cae a una de tres portadas genéricas, siempre la misma para el mismo
   artículo. Arreglar la URL real en Notion es la solución de fondo. */
const PLACEHOLDERS_POST = ['assets/ph-post-1.png', 'assets/ph-post-2.png', 'assets/ph-post-3.png'];
const placeholderPost = (a = {}) => PLACEHOLDERS_POST[Math.abs((a.id || a.slug || '').split('').reduce((h, c) => h + c.charCodeAt(0), 0)) % PLACEHOLDERS_POST.length];
const fechaLarga = (iso = '') => {
  const d = new Date((iso || '').length === 10 ? iso + 'T12:00:00' : iso);
  return isNaN(d) ? '' : d.toLocaleDateString('es-EC', { day: 'numeric', month: 'short', year: 'numeric' });
};

/* Novedades. Igual que el catálogo: en vivo si el endpoint responde, copia
   local si no. Con slug trae un solo artículo, con su cuerpo. Se revalida al
   volver a la pestaña y cada cinco minutos, así un artículo nuevo en Notion
   aparece sin volver a desplegar. */
function useNovedades(slugArt) {
  const local = window.CASAMIA_NOVEDADES || [];
  const [data, setData] = React.useState(() => slugArt ? local.filter(a => a.slug === slugArt) : local);
  const [estado, setEstado] = React.useState('local');
  React.useEffect(() => {
    if (FILEMODE) return;
    let alive = true;
    const url = '/api/novedades' + (slugArt ? '?slug=' + encodeURIComponent(slugArt) : '');
    const traer = () => fetch(url, { headers: { Accept: 'application/json' } })
      .then(r => r.ok ? r.json() : Promise.reject(r.status))
      .then(j => {
        const rows = Array.isArray(j) ? j : j.results;
        if (alive && Array.isArray(rows) && rows.length) { setData(rows); setEstado('vivo'); }
      })
      .catch(() => { if (alive) setEstado('local'); });
    traer();
    const t = setInterval(traer, 300000);
    const alVolver = () => { if (document.visibilityState === 'visible') traer(); };
    document.addEventListener('visibilitychange', alVolver);
    return () => { alive = false; clearInterval(t); document.removeEventListener('visibilitychange', alVolver); };
  }, [slugArt]);
  return [data, estado];
}
/* Red de seguridad: guardamos el id de la última ficha abierta. Si el hosting
   pierde el id de la ruta, la ficha lo recupera en vez de mostrar otra casa. */
document.addEventListener('click', (e) => {
  const a = e.target.closest && e.target.closest('a[href*="/propiedad/"],a[href*="ficha.html?id="]');
  if (!a) return;
  const m = (a.getAttribute('href') || '').match(/\/propiedad\/([^/-]+)|[?&]id=([^&]+)/);
  const id = m && (m[1] || decodeURIComponent(m[2] || ''));
  if (id) { try { sessionStorage.setItem('casamia:ultima', id); } catch (x) {} }
}, true);

function useToast() {
  const [msg, setMsg] = React.useState(null);
  const t = React.useRef(null);
  React.useEffect(() => () => clearTimeout(t.current), []);
  return [msg, (m) => { setMsg(m); clearTimeout(t.current); t.current = setTimeout(() => setMsg(null), 2800); }];
}
function Toast({ msg, icon }) {
  if (!msg) return null;
  return <div className="cm-toast" role="status"><Icon name={icon || 'check'} size={16} />{msg}</div>;
}

const finTone = (f = '') => /vip/i.test(f) ? 'premium' : /biess/i.test(f) ? 'wash' : /miti/i.test(f) ? 'verified' : /banca|privada|credicasa/i.test(f) ? 'dark' : 'floating';
const finIcon = (f = '') => /vip/i.test(f) ? 'shield-check' : /biess/i.test(f) ? 'badge-check' : /miti/i.test(f) ? 'handshake' : 'landmark';

function useSaved() {
  const [saved, setSaved] = React.useState(() => { try { return JSON.parse(localStorage.getItem('casamia:saved') || '{}'); } catch (e) { return {}; } });
  const toggle = (id) => setSaved(s => { const n = { ...s, [id]: !s[id] }; try { localStorage.setItem('casamia:saved', JSON.stringify(n)); } catch (e) {} return n; });
  return [saved, toggle];
}
function useCatalog(withStatus = false) {
  const offline = location.protocol === 'file:';
  const [data, setData] = React.useState(offline ? (window.CASAMIA_CATALOGO || []) : []);
  const [status, setStatus] = React.useState(offline ? 'offline' : 'loading');
  React.useEffect(() => {
    if (!BACKEND.rest.properties) return;
    let alive = true, pending = false, controller;
    const traer = async () => {
      if (pending || document.visibilityState === 'hidden') return;
      pending = true;
      controller = new AbortController();
      const timer = setTimeout(() => controller.abort(), 15000);
      try {
        const r = await fetch(BACKEND.rest.properties, { cache: 'no-store', signal: controller.signal, headers: { Accept: 'application/json' } });
        if (!r.ok) throw new Error('catalog');
        const j = await r.json();
        const rows = Array.isArray(j) ? j : j.results;
        if (!Array.isArray(rows)) throw new Error('format');
        if (alive) { setData(rows); setStatus('live'); }
      } catch (e) { if (alive) setStatus('error'); }
      finally { clearTimeout(timer); pending = false; }
    };
    traer();
    const t = setInterval(traer, 15000);
    const alVolver = () => { if (document.visibilityState === 'visible') traer(); };
    document.addEventListener('visibilitychange', alVolver);
    window.addEventListener('focus', alVolver);
    window.addEventListener('online', alVolver);
    return () => { alive = false; controller?.abort(); clearInterval(t); document.removeEventListener('visibilitychange', alVolver); window.removeEventListener('focus', alVolver); window.removeEventListener('online', alVolver); };
  }, []);
  return withStatus ? [data, status] : data;
}

function Header({ onJoin, savedCount, children }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  const [user, setAuthUser] = React.useState(null);
  React.useEffect(() => { CasaMiaAuth.session().then(setAuthUser).catch(() => {}); }, []);
  const initials = user?.nombre ? user.nombre.split(' ').filter(Boolean).slice(0, 2).map(w => w[0].toUpperCase()).join('') : null;
  React.useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', h); return () => document.removeEventListener('mousedown', h);
  }, []);
  const item = (label, onClick, icon) => (
    <button key={label} onClick={() => { setOpen(false); onClick(); }} className="cm-menu-item"><Icon name={icon} size={16} />{label}</button>
  );
  return (
    <header className="cm-header">
      <div className="cm-header-in">
        <a href={BACKEND.links.inicio} className="cm-logo"><img src="assets/logo-casamia-alpha.png" alt="casamia.ec" /></a>
        <nav className="cm-nav">
          <a href={BACKEND.links.compra}><Icon name="house" size={15} />Propiedades</a>
          <a href={BACKEND.links.creditos}><Icon name="calculator" size={15} />Créditos</a>
        <a href={BACKEND.links.novedades}><Icon name="newspaper" size={15} />Novedades</a>
          <a href={BACKEND.links.contacto}><Icon name="message-circle" size={15} />Contacto</a>
        </nav>
        {children}
        <div className="cm-header-right" ref={ref}>
          <span className="cm-hide-sm"><Button size="sm" variant="outline" onClick={() => { location.href = user ? BACKEND.links.publicar : BACKEND.links.cuenta + '?next=publicar'; }}>Publica tu propiedad</Button></span>
          <button className="cm-account" aria-label="Menú de cuenta" aria-expanded={open} onClick={() => setOpen(!open)}>
            <Icon name="menu" size={16} />
            <span className="cm-avatar">{initials || <Icon name="user" size={14} />}</span>
          </button>
          {open ? (
            <div className="cm-menu" role="menu">
              {user ? <div className="cm-menu-head">{user.nombre}</div> : null}
              {item(user ? 'Mi panel' : 'Entrar con Google', () => { location.href = user ? BACKEND.links.panel : BACKEND.links.cuenta; }, 'user')}
              {item('Publica tu propiedad', () => { location.href = user ? BACKEND.links.publicar : BACKEND.links.cuenta + '?next=publicar'; }, 'key-round')}
              {item(savedCount ? `Guardadas (${savedCount})` : 'Guardadas', () => { location.href = user ? BACKEND.links.panel + '#guardadas' : BACKEND.links.compra + '?guardadas=1'; }, 'heart')}
              {item('Créditos hipotecarios', () => { location.href = BACKEND.links.creditos; }, 'calculator')}
              <div className="cm-menu-sep"></div>
              {item('Trabaja con nosotros', onJoin, 'handshake')}
              {item('Contacto', () => { location.href = BACKEND.links.contacto; }, 'message-circle')}
            </div>) : null}
        </div>
      </div>
    </header>
  );
}

function Footer({ onJoin }) {
  return (
    <footer className="cm-footer">
      <div className="cm-footer-in">
        <div className="cm-footer-brand">
          <img src="assets/logo-casamia-alpha.png" alt="casamia.ec" />
          <p className="cm-footer-tag">Tu hogar ideal en minutos.</p>
          <a className="cm-footer-wa" href={WA()} target="_blank" rel="noopener"><Icon name="message-circle" size={15} />+593 98 895 7054</a>
        </div>
        {[
          { t: 'Propiedades', l: [['Comprar', BACKEND.links.compra], ['Vender', BACKEND.links.publicar], ['Créditos hipotecarios', BACKEND.links.creditos]] },
          { t: 'Empresa', l: [['Contacto', BACKEND.links.contacto], ['Novedades', BACKEND.links.novedades]] },
          { t: 'Contacto', l: [['hola@casamia.ec', 'mailto:hola@casamia.ec'], ['Quito, Ecuador', BACKEND.links.contacto]] }
        ].map(c => (
          <div key={c.t}>
            <div className="cm-footer-h">{c.t}</div>
            <ul className="cm-footer-list">
              {c.l.map(([label, href]) => <li key={label}><a href={href} target="_blank" rel="noopener">{label}</a></li>)}
              {c.t === 'Empresa' ? <li><a href="#" onClick={(e) => { e.preventDefault(); onJoin(); }}>Trabaja con nosotros</a></li> : null}
            </ul>
          </div>
        ))}
      </div>
      <div className="cm-footer-legal">
        <span>© 2026 casamia.ec</span>
        <span className="cm-footer-social">
          <a href={BACKEND.links.facebook} target="_blank" rel="noopener" aria-label="Facebook"><Icon name="facebook" size={16} /></a>
          <a href={BACKEND.links.instagram} target="_blank" rel="noopener" aria-label="Instagram"><Icon name="instagram" size={16} /></a>
          <a href={BACKEND.links.tiktok} target="_blank" rel="noopener" aria-label="TikTok"><Icon name="music-2" size={16} /></a>
        </span>
        <a className="cm-agency" href={BACKEND.links.agencia} target="_blank" rel="noopener" aria-label="agave">agave<i>.</i></a>
      </div>
    </footer>
  );
}

function MobileBar() {
  return (
    <div className="cm-bar">
      <nav className="cm-bar-main">
        <a href={BACKEND.links.compra}><Icon name="search" size={19} />Explorar</a>
        <a href={BACKEND.links.creditos}><Icon name="calculator" size={19} />Créditos</a>
        <a href={BACKEND.links.cuenta + '?next=publicar'}><Icon name="key-round" size={19} />Publicar</a>
      </nav>
      <a className="cm-bar-wa" href={WA()} target="_blank" rel="noopener" aria-label="Escríbenos por WhatsApp"><Icon name="message-circle" size={22} /></a>
    </div>
  );
}

function JoinDialog({ open, onClose }) {
  const [role, setRole] = React.useState('agente');
  const [form, setForm] = React.useState({ nombre: '', email: '', tel: '', msg: '' });
  const [err, setErr] = React.useState({});
  const [sent, setSent] = React.useState(false);
  React.useEffect(() => { document.body.style.overflow = open ? 'hidden' : ''; return () => { document.body.style.overflow = ''; }; }, [open]);
  if (!open) return null;
  const set = (k) => (e) => setForm({ ...form, [k]: e.target.value });
  const submit = () => {
    const e = {};
    if (!form.nombre.trim()) e.nombre = 'Escribe tu nombre completo';
    if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.email)) e.email = 'Escribe un correo válido';
    if (form.tel && form.tel.replace(/\D/g, '').length < 9) e.tel = 'Ingresa 10 dígitos';
    setErr(e);
    if (!Object.keys(e).length) {

      /* Aviso por Resend: el equipo recibe la solicitud con rol, teléfono y nota. */
      if (window.API) API.post('contacto', {
        nombre: form.nombre, email: form.email || 'sin-correo@casamia.ec', tel: form.tel,
        motivo: 'Quiero trabajar con casamia.ec · ' + (form.rol || 'sin rol'),
        mensaje: form.msg || 'Solicitud enviada desde el diálogo «Trabaja con nosotros».'
      }).catch(() => {});
      setSent(true);
    }
  };
  const roleCard = (id, icon, title, sub) => (
    <button type="button" onClick={() => setRole(id)} className={'cm-role' + (role === id ? ' is-on' : '')}>
      <Icon name={icon} size={22} />
      <span><span className="cm-role-t">{title}</span><span className="cm-role-s">{sub}</span></span>
    </button>
  );
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 80 }}>
      <Dialog open onClose={onClose} width={560} title={sent ? 'Solicitud enviada' : 'Trabaja con nosotros'}
        footer={sent ? <Button block onClick={onClose}>Cerrar</Button> : <Button block onClick={submit}>Enviar solicitud</Button>}>
        {sent ? (
          <div style={{ textAlign: 'center', padding: '16px 0 8px' }}>
            <Icon name="check-circle" size={36} style={{ color: 'var(--verified)' }} />
            <h3 style={{ marginTop: 12, fontSize: 'var(--fs-display-sm)', fontWeight: 600, color: 'var(--text-heading)' }}>Recibimos tu solicitud</h3>
            <p style={{ marginTop: 6, fontSize: 'var(--fs-body-md)', color: 'var(--text-muted)' }}>El equipo de casamia.ec revisa tu información y te escribe en menos de 24 horas.</p>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <p style={{ fontSize: 'var(--fs-body-md)', color: 'var(--text-muted)' }}>Selecciona cómo quieres colaborar con casamia.ec</p>
            <div className="cm-roles">
              {roleCard('agente', 'handshake', 'Agente vendedor', 'Vendo propiedades y gano comisiones')}
              {roleCard('proyecto', 'building-2', 'Proyecto inmobiliario', 'Tengo un proyecto para comercializar')}
            </div>
            <Input label="Nombre completo" placeholder="Tu nombre y apellido" value={form.nombre} onChange={set('nombre')} error={err.nombre} />
            <Input label="Email" type="email" placeholder="tucorreo@ejemplo.com" value={form.email} onChange={set('email')} error={err.email} />
            <Input label="Teléfono / WhatsApp" placeholder="0988957054" value={form.tel} onChange={set('tel')} error={err.tel} hint="Te escribimos por WhatsApp" />
            <Input label="Cuéntanos sobre ti" placeholder="Zonas donde trabajas, experiencia, proyecto…" value={form.msg} onChange={set('msg')} />
          </div>
        )}
      </Dialog>
    </div>
  );
}

/* Loads the Google Maps JS API once per page. */
let mapsPromise = null;
function loadMaps() {
  if (mapsPromise) return mapsPromise;
  /* Callback bootstrap: Google calls __casamiaMapsReady once google.maps.Map exists.
     A 12s guard means the promise always settles, so the UI can show its error card. */
  mapsPromise = new Promise((res, rej) => {
    if (window.google?.maps?.Map) return res(window.google.maps);
    const timer = setTimeout(() => rej(new Error('maps-timeout')), 12000);
    window.__casamiaMapsReady = () => { clearTimeout(timer); res(window.google.maps); };
    const s = document.createElement('script');
    s.src = `https://maps.googleapis.com/maps/api/js?key=${BACKEND.mapsKey}&v=weekly&language=es&region=EC&callback=__casamiaMapsReady`;
    s.async = true;
    s.onerror = () => { clearTimeout(timer); rej(new Error('maps')); };
    document.head.appendChild(s);
  });
  return mapsPromise;
}
const MAP_STYLE = [
  { elementType: 'geometry', stylers: [{ color: '#f6f7f9' }] },
  { elementType: 'labels.text.fill', stylers: [{ color: '#667085' }] },
  { elementType: 'labels.text.stroke', stylers: [{ color: '#ffffff' }] },
  { featureType: 'poi', stylers: [{ visibility: 'off' }] },
  { featureType: 'transit', stylers: [{ visibility: 'off' }] },
  { featureType: 'road', elementType: 'geometry', stylers: [{ color: '#ffffff' }] },
  { featureType: 'road.highway', elementType: 'geometry', stylers: [{ color: '#e9eff8' }] },
  { featureType: 'water', elementType: 'geometry', stylers: [{ color: '#dce7f5' }] },
  { featureType: 'landscape.natural', elementType: 'geometry', stylers: [{ color: '#eef1ee' }] }
];

Object.assign(window, { BACKEND, FILEMODE, route, slug, WA, money, num, go, detailUrl, finTone, finIcon, useSaved, useCatalog, Header, Footer, MobileBar, JoinDialog, loadMaps, MAP_STYLE, useToast, Toast, artUrl, portadaArt, placeholderPost, fechaLarga, useNovedades });
