// ─── Propiedades · vista dual lista / mapa (Mapbox GL JS) ───────────────────

const MAPBOX_TOKEN =
  'pk.eyJ1Ijoibm9kZXhpcyIsImEiOiJjbXFhYmNwbzIwMDRoMnBvZjBieWhxdXBvIn0.PhFDk_Y3FsXbLyno6AyEpA';

// Colores de marker en el mapa — coinciden con el design system
const MARKER_COLOR = {
  Disponible: '#10b981',   // verde esmeralda
  Reservada:  '#f59e0b',   // ámbar
  Vendida:    '#6b7280',   // gris neutro
  Alquilada:  '#6b7280',
  Baja:       '#94a3b8',
};

// Colores badge dentro del popup
const BADGE_STYLE = {
  Disponible: { bg: '#d1fae5', fg: '#065f46' },
  Reservada:  { bg: '#fef3c7', fg: '#92400e' },
  Vendida:    { bg: '#f1f5f9', fg: '#475569' },
  Alquilada:  { bg: '#f1f5f9', fg: '#475569' },
  Baja:       { bg: '#f1f5f9', fg: '#94a3b8' },
};

// Colores del design system (igual que antes) — usados en filtros y leyenda
const ESTADO_COLOR = {
  Disponible: '#3F8A6B',
  Reservada:  '#C9A961',
  Vendida:    '#677A88',
  Alquilada:  '#677A88',
};

// ─── Helpers ─────────────────────────────────────────────────────────────────

function formatPrecio(p) {
  if (p.precio_usd != null && !isNaN(p.precio_usd)) return USD(p.precio_usd);
  if (p.precio_ars != null && !isNaN(p.precio_ars)) return `$${Math.round(p.precio_ars / 1000)}k ARS`;
  return '—';
}

// Adapta el formato crudo del backend (Prisma) al contrato del frontend
function adaptarPropiedad(p) {
  const TIPO_MAP = {
    VENTA:             'Venta',
    ALQUILER:          'Alquiler',
    ALQUILER_TEMPORAL: 'Alquiler',
  };
  const ESTADO_MAP = {
    DISPONIBLE: 'Disponible',
    RESERVADA:  'Reservada',
    VENDIDA:    'Vendida',
    ALQUILADA:  'Alquilada',
    BAJA:       'Baja',
  };
  const precio = p.precio != null ? Number(p.precio) : null;
  return {
    id:         p.id,
    dir:        p.direccion,
    barrio:     p.barrio   ?? '',
    ciudad:     p.ciudad,
    tipo:       TIPO_MAP[p.operacionTipo]  ?? p.operacionTipo,
    estado:     ESTADO_MAP[p.estado]       ?? p.estado,
    moneda:     p.moneda,
    precio_usd: p.moneda === 'USD' ? precio : null,
    precio_ars: p.moneda === 'ARS' ? precio : null,
    m2:         p.superficie ?? null,
    amb:        p.ambientes  ?? null,
    broker:     p.broker ? `${p.broker.nombre}` : null,
    // Coordenadas reales del backend (null si no geocodificadas aún)
    lat:        p.lat ?? null,
    lng:        p.lng ?? null,
  };
}

// ─── HTML del popup Mapbox ────────────────────────────────────────────────────
// Uso de window.__lanvenSelectProp para comunicar click al estado React.
function buildPopupHTML(p) {
  const badge  = BADGE_STYLE[p.estado] || { bg: '#f1f5f9', fg: '#677A88' };
  const extras = [p.amb ? `${p.amb} amb` : null, p.m2 ? `${p.m2} m²` : null]
    .filter(Boolean).join(' · ');
  return `
    <div style="font-family: Manrope, system-ui, sans-serif; min-width: 220px; padding: 2px 0 0;">
      <div style="font-size: 10px; color: #677A88; text-transform: uppercase;
                  letter-spacing: 0.08em; margin-bottom: 3px;">
        ${p.barrio || p.ciudad} · ${p.tipo}
      </div>
      <div style="font-size: 14px; font-weight: 600; color: #1F2A33;
                  line-height: 1.3; margin-bottom: 7px;">
        ${p.dir}
      </div>
      <div style="display: flex; align-items: center; gap: 8px; margin-bottom: ${extras ? '5px' : '8px'};">
        <span style="font-size: 10px; padding: 2px 8px; border-radius: 20px;
                     background: ${badge.bg}; color: ${badge.fg}; font-weight: 600;">
          ${p.estado}
        </span>
        <span style="font-size: 13px; font-weight: 600; color: #1F2A33;
                     font-family: 'JetBrains Mono', monospace;">
          ${formatPrecio(p)}
        </span>
      </div>
      ${extras ? `<div style="font-size: 11px; color: #677A88; margin-bottom: 8px;">${extras}</div>` : ''}
      <button
        onclick="window.__lanvenSelectProp && window.__lanvenSelectProp('${p.id}')"
        style="width: 100%; padding: 7px 12px; background: #C9A961; color: #1F2A33;
               border: none; border-radius: 5px; font-size: 12px; font-weight: 600;
               cursor: pointer; font-family: Manrope, sans-serif;"
        onmouseover="this.style.background='#A88A47'"
        onmouseout="this.style.background='#C9A961'">
        Ver detalle
      </button>
    </div>
  `;
}

// ─── Estilos del marker ───────────────────────────────────────────────────────
function applyMarkerStyle(el, color, isSelected) {
  el.style.width      = isSelected ? '20px'  : '13px';
  el.style.height     = isSelected ? '20px'  : '13px';
  el.style.borderRadius = '50%';
  el.style.background   = color;
  el.style.border       = '2.5px solid white';
  el.style.boxShadow    = isSelected
    ? `0 0 0 3px ${color}55, 0 2px 8px rgba(31,42,51,0.4)`
    : '0 1px 4px rgba(31,42,51,0.35)';
  el.style.cursor    = 'pointer';
  el.style.transition = 'all 0.18s ease';
  el.style.position  = 'relative';
  el.style.zIndex    = isSelected ? '10' : '1';
}

// ─── Componente MapboxMap ────────────────────────────────────────────────────
function MapboxMap({ props, selected, setSelected }) {
  const containerRef = useRef(null);
  const mapRef       = useRef(null);
  const markersRef   = useRef({}); // id → { marker, el, color }
  const [loaded, setLoaded]             = useState(false);
  const [geocodificando, setGeocodificando] = useState(false);
  const [geoResult, setGeoResult]       = useState(null);

  // ¿El usuario actual es ADMIN? (window.CURRENT_USER seteado en app.jsx)
  const isAdmin = window.CURRENT_USER?.rol === 'admin';

  // Exponer setter al popup HTML (no puede acceder al closure de React)
  useEffect(() => {
    window.__lanvenSelectProp = (id) => setSelected(id);
    return () => { delete window.__lanvenSelectProp; };
  }, [setSelected]);

  // ── Inicializar mapa una sola vez ────────────────────────────────────────
  useEffect(() => {
    if (!containerRef.current || mapRef.current) return;
    const mb = window.mapboxgl;
    if (!mb) { console.error('[MapboxMap] mapboxgl no disponible'); return; }

    mb.accessToken = MAPBOX_TOKEN;
    const map = new mb.Map({
      container: containerRef.current,
      style:     'mapbox://styles/mapbox/light-v11',
      center:    [-58.3816, -34.6037],  // Buenos Aires
      zoom:      11,
    });

    // Controles de zoom/navegación en esquina inferior derecha
    map.addControl(new mb.NavigationControl({ showCompass: false }), 'bottom-right');
    map.once('load', () => setLoaded(true));
    mapRef.current = map;

    return () => {
      map.remove();
      mapRef.current = null;
      markersRef.current = {};
    };
  }, []);

  // ── Sincronizar markers con la lista filtrada ────────────────────────────
  useEffect(() => {
    if (!loaded || !mapRef.current) return;
    const map = mapRef.current;
    const mb  = window.mapboxgl;

    const currentIds = new Set(props.map(p => p.id));

    // Quitar markers de propiedades que ya no están en el filtro
    Object.keys(markersRef.current).forEach(id => {
      if (!currentIds.has(id)) {
        markersRef.current[id].marker.remove();
        delete markersRef.current[id];
      }
    });

    // Agregar markers nuevos (solo para props con lat/lng reales)
    props.forEach(p => {
      if (p.lat == null || p.lng == null) return;
      if (markersRef.current[p.id]) return; // ya existe, no recrear

      const color  = MARKER_COLOR[p.estado] || '#6b7280';
      const isSel  = selected === p.id;

      const el = document.createElement('div');
      el.dataset.propId = p.id;
      applyMarkerStyle(el, color, isSel);

      const popup = new mb.Popup({
        offset:      16,
        closeButton: true,
        maxWidth:    '280px',
      }).setHTML(buildPopupHTML(p));

      const marker = new mb.Marker({ element: el })
        .setLngLat([p.lng, p.lat])
        .setPopup(popup)
        .addTo(map);

      // Click en marker → seleccionar + abrir popup
      el.addEventListener('click', () => {
        setSelected(p.id);
        if (!marker.getPopup().isOpen()) marker.togglePopup();
      });

      markersRef.current[p.id] = { marker, el, color };
    });

    // Actualizar estilo visual de todos los markers existentes
    Object.entries(markersRef.current).forEach(([id, { el, color }]) => {
      applyMarkerStyle(el, color, id === selected);
    });

  }, [props, loaded]); // eslint-disable-line react-hooks/exhaustive-deps

  // ── flyTo + highlight cuando cambia `selected` ───────────────────────────
  useEffect(() => {
    if (!mapRef.current) return;

    // Actualizar estilos de todos los markers
    Object.entries(markersRef.current).forEach(([id, { el, color, marker }]) => {
      applyMarkerStyle(el, color, id === selected);
      // Cerrar popup de los que ya no están seleccionados
      if (id !== selected && marker.getPopup()?.isOpen()) {
        marker.togglePopup();
      }
    });

    if (!selected) return;

    // flyTo suave hacia la propiedad seleccionada
    const prop = props.find(p => p.id === selected);
    if (prop?.lat != null && prop?.lng != null) {
      mapRef.current.flyTo({
        center:    [prop.lng, prop.lat],
        zoom:      15,
        duration:  700,
        essential: true,
      });
    }
  }, [selected]); // eslint-disable-line react-hooks/exhaustive-deps

  // ── Geocodificar todas las propiedades (ADMIN) ───────────────────────────
  async function handleGeocodificarTodas() {
    setGeocodificando(true);
    setGeoResult(null);
    try {
      const res  = await fetch(`${API_BASE}/api/propiedades/geocodificar-todas`,
        { credentials: 'include' });
      const data = await res.json();
      setGeoResult(data);
      // Disparar recarga de propiedades para obtener lat/lng actualizados
      window.dispatchEvent(new Event('lanven:reloadPropiedades'));
    } catch {
      setGeoResult({ error: 'Error de red' });
    } finally {
      setGeocodificando(false);
    }
  }

  // Propiedades sin coordenadas → contador informativo
  const sinCoords = props.filter(p => p.lat == null || p.lng == null).length;

  return (
    <div className="relative w-full h-full">
      {/* Contenedor del mapa */}
      <div ref={containerRef} className="absolute inset-0" />

      {/* Panel ADMIN — geocodificar + resultado */}
      {isAdmin && (
        <div className="absolute top-4 left-4 z-10 flex flex-col gap-2">
          <button
            onClick={handleGeocodificarTodas}
            disabled={geocodificando}
            className="bg-white hover:bg-slate-50 border border-slate-200 shadow-card rounded px-3 py-1.5 text-[11px] font-medium text-slate-600 hover:text-ink inline-flex items-center gap-1.5 transition-colors disabled:opacity-60 disabled:cursor-not-allowed">
            <I.Pin size={12} />
            {geocodificando
              ? 'Geocodificando…'
              : `Geocodificar propiedades${sinCoords > 0 ? ` (${sinCoords} sin coords)` : ''}`
            }
          </button>

          {geoResult && !geoResult.error && (
            <div className="bg-white/95 border border-slate-200 shadow-card rounded px-3 py-1.5 text-[11px] text-slate-500 font-mono">
              ✓ {geoResult.actualizadas}/{geoResult.total} actualizadas
              {geoResult.errores > 0 && ` · ${geoResult.errores} errores`}
            </div>
          )}
          {geoResult?.error && (
            <div className="bg-white border border-red-200 shadow-card rounded px-3 py-1.5 text-[11px] text-red-500">
              {geoResult.error}
            </div>
          )}
        </div>
      )}

      {/* Leyenda colores */}
      <div className="absolute bottom-10 left-4 bg-white/90 backdrop-blur rounded shadow-card border border-slate-100 px-3 py-2 flex items-center gap-3 text-[10px] z-10">
        {[['Disponible','#10b981'],['Reservada','#f59e0b'],['Vendida','#6b7280']].map(([label, color]) => (
          <span key={label} className="inline-flex items-center gap-1.5">
            <span style={{ background: color, width: 8, height: 8, borderRadius: '50%', display: 'inline-block' }} />
            {label}
          </span>
        ))}
        {sinCoords > 0 && (
          <span className="text-slate-400 pl-1 border-l border-slate-200">
            {sinCoords} sin pin
          </span>
        )}
      </div>
    </div>
  );
}

// ─── Propiedades (raíz del módulo) ────────────────────────────────────────────
function Propiedades() {
  const [view, setView]               = useState('mapa');
  const [tipo, setTipo]               = useState('Todos');
  const [estado, setEstado]           = useState('Todos');
  const [selected, setSelected]       = useState(null);
  const [propiedades, setPropiedades] = useState([]);
  const [loading, setLoading]         = useState(true);
  const [error, setError]             = useState(null);

  useEffect(() => {
    function load() {
      setLoading(true);
      fetch(`${API_BASE}/api/propiedades`, { credentials: 'include' })
        .then(r => r.json())
        .then(json => {
          setPropiedades((json.data ?? []).map(adaptarPropiedad));
          setLoading(false);
        })
        .catch(err => {
          console.error('[propiedades fetch]', err);
          setError('Error al cargar propiedades.');
          setLoading(false);
        });
    }
    load();
    // Recarga tras geocodificación masiva
    window.addEventListener('lanven:reloadPropiedades', load);
    return () => window.removeEventListener('lanven:reloadPropiedades', load);
  }, []);

  const filtered = useMemo(() => propiedades.filter(p =>
    (tipo   === 'Todos' || p.tipo   === tipo) &&
    (estado === 'Todos' || p.estado === estado)
  ), [propiedades, tipo, estado]);

  if (loading) return <div className="p-8 text-slate-500">Cargando propiedades…</div>;
  if (error)   return <div className="p-8 text-red-500">{error}</div>;

  return (
    <div className="fade-in">
      <PageHeader
        crumbs={['Inicio', 'Propiedades']}
        title="Propiedades"
        sub={`${filtered.length} en el viewport · ${propiedades.length} totales`}
        actions={
          <>
            <div className="inline-flex bg-slate-100 rounded p-0.5">
              {[['mapa', 'Mapa', I.Map], ['lista', 'Lista', I.List]].map(([k, l, Ico]) => (
                <button key={k} onClick={() => setView(k)}
                  className={`inline-flex items-center gap-1.5 text-[12px] font-medium px-3 py-1.5 rounded transition-colors ${view === k ? 'bg-white text-ink shadow-card' : 'text-slate-500 hover:text-ink'}`}>
                  <Ico size={13} />{l}
                </button>
              ))}
            </div>
            <Button variant="primary" size="md" icon={<I.Plus size={14} sw={2} />}>Nueva propiedad</Button>
          </>
        }
      />

      {/* Barra de filtros */}
      <div className="flex items-center gap-2.5 mb-4 flex-wrap">
        <SearchInput placeholder="Buscar dirección, barrio…" value={''} onChange={() => {}} w="w-72" />
        <div className="h-8 w-px bg-slate-200 mx-1" />
        <Select label="Tipo" value={tipo} onChange={setTipo} w="w-40"
          options={[
            { value: 'Todos',    label: 'Todos los tipos', count: propiedades.length },
            { value: 'Venta',    label: 'Venta',    count: propiedades.filter(p => p.tipo === 'Venta').length },
            { value: 'Alquiler', label: 'Alquiler', count: propiedades.filter(p => p.tipo === 'Alquiler').length },
          ]} />
        <Select label="Estado" value={estado} onChange={setEstado} w="w-44"
          options={[
            { value: 'Todos',      label: 'Todos los estados', count: propiedades.length },
            { value: 'Disponible', label: 'Disponible', dot: ESTADO_COLOR.Disponible, count: propiedades.filter(p => p.estado === 'Disponible').length },
            { value: 'Reservada',  label: 'Reservada',  dot: ESTADO_COLOR.Reservada,  count: propiedades.filter(p => p.estado === 'Reservada').length },
            { value: 'Vendida',    label: 'Vendida',    dot: ESTADO_COLOR.Vendida,    count: propiedades.filter(p => p.estado === 'Vendida').length },
            { value: 'Alquilada',  label: 'Alquilada',  dot: ESTADO_COLOR.Alquilada,  count: propiedades.filter(p => p.estado === 'Alquilada').length },
          ]} />
        <Select label="Precio" value="todos" onChange={() => {}} w="w-44"
          options={[
            { value: 'todos',    label: 'Cualquier precio' },
            { value: '<150k',    label: 'Hasta US$ 150k' },
            { value: '150-300k', label: 'US$ 150k – 300k' },
            { value: '300-500k', label: 'US$ 300k – 500k' },
            { value: '>500k',    label: 'Más de US$ 500k' },
          ]} />
        <Select label="Ambientes" value="todos" onChange={() => {}} w="w-36"
          options={[
            { value: 'todos', label: 'Cualquiera' },
            { value: '1',     label: '1 ambiente' },
            { value: '2',     label: '2 ambientes' },
            { value: '3',     label: '3 ambientes' },
            { value: '4+',    label: '4 o más' },
          ]} />
      </div>

      {view === 'mapa'
        ? <MapaView props={filtered} selected={selected} setSelected={setSelected} />
        : <ListaView props={filtered} />
      }
    </div>
  );
}

// ─── MapaView ─────────────────────────────────────────────────────────────────
function MapaView({ props, selected, setSelected }) {
  return (
    <div className="grid grid-cols-10 gap-4">
      {/* Panel mapa */}
      <div className="col-span-7 bg-white rounded-md border border-slate-100 shadow-card overflow-hidden relative h-[640px]">
        <MapboxMap props={props} selected={selected} setSelected={setSelected} />
      </div>

      {/* Panel lateral — lista de propiedades filtradas */}
      <div className="col-span-3 bg-white rounded-md border border-slate-100 shadow-card overflow-hidden flex flex-col h-[640px]">
        <div className="px-5 py-4 border-b border-slate-100 flex items-center justify-between">
          <div>
            <div className="text-[13px] font-semibold text-ink">En el viewport</div>
            <div className="text-[11px] text-slate-500">{props.length} propiedades visibles</div>
          </div>
          <button className="text-[11px] text-slate-500 hover:text-ink inline-flex items-center gap-1">
            Ordenar <I.ChevronDn size={11} />
          </button>
        </div>
        <ul className="flex-1 overflow-y-auto divide-y divide-slate-100">
          {props.map(p => (
            <li key={p.id}
              onClick={() => setSelected(p.id)}
              className={`px-5 py-3.5 cursor-pointer transition-colors ${selected === p.id ? 'bg-canvas' : 'hover:bg-canvas/60'}`}>
              <div className="flex items-start gap-3">
                <div className="w-14 h-14 rounded placeholder-stripe border border-slate-200 flex-shrink-0 flex items-center justify-center">
                  <I.Home size={16} className="text-slate-400" />
                </div>
                <div className="flex-1 min-w-0">
                  <div className="flex items-start justify-between gap-2">
                    <div className="font-mono text-[10px] text-slate-400 truncate">{p.id}</div>
                    <StatusBadge status={p.estado} />
                  </div>
                  <div className="text-[13px] text-ink font-medium leading-tight mt-0.5 truncate">{p.dir}</div>
                  <div className="text-[11px] text-slate-500 mt-0.5">
                    {p.barrio || p.ciudad} · {p.amb ?? '–'} amb · {p.m2 ?? '–'} m²
                  </div>
                  <div className="font-mono text-[13px] text-ink mt-1">
                    {formatPrecio(p)}
                    <span className="text-[10px] text-slate-400 ml-1.5">
                      / {p.tipo === 'Alquiler' ? 'mes' : 'venta'}
                    </span>
                  </div>
                  {/* Indicador visual si no tiene coordenadas */}
                  {(p.lat == null || p.lng == null) && (
                    <div className="text-[10px] text-slate-400 mt-0.5 inline-flex items-center gap-1">
                      <I.Pin size={10} />sin pin
                    </div>
                  )}
                </div>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

// ─── ListaView ────────────────────────────────────────────────────────────────
function ListaView({ props }) {
  return (
    <div className="grid grid-cols-4 gap-4">
      {props.map(p => (
        <div key={p.id} className="bg-white rounded-md border border-slate-100 shadow-card overflow-hidden hover:shadow-pop hover:-translate-y-0.5 transition-all cursor-pointer">
          <div className="h-36 placeholder-stripe relative flex items-center justify-center">
            <I.Home size={24} className="text-slate-400" />
            <div className="absolute top-2.5 left-2.5"><StatusBadge status={p.estado} /></div>
            <div className="absolute bottom-2.5 right-2.5 text-[9px] font-mono uppercase tracking-[0.16em] text-slate-400">{p.id}</div>
          </div>
          <div className="p-4">
            <div className="text-[10px] uppercase tracking-[0.12em] text-slate-400">{p.barrio || p.ciudad} · {p.tipo}</div>
            <div className="font-serif text-[18px] text-ink leading-tight mt-1">{p.dir}</div>
            <div className="text-[11.5px] text-slate-500 mt-0.5">{p.amb ?? '–'} amb · {p.m2 ?? '–'} m²</div>
            <div className="mt-3 pt-3 border-t border-slate-100 flex items-center justify-between">
              <div className="font-mono text-[15px] text-ink">{formatPrecio(p)}</div>
              <button className="text-[11px] text-slate-700 hover:text-ink font-medium inline-flex items-center gap-1">
                Ver <I.Arrow size={11} />
              </button>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

window.Propiedades = Propiedades;
