// Valdebebas Life — Tablón vecinal
const postType = id => VB_POST_TYPES.find(t => t.id === id) || VB_POST_TYPES[0];

function PostCard({ p, onOpen }) {
  const t = postType(p.type);
  return (
    <button className="post" onClick={() => onOpen(p)}>
      <span className={"ico " + t.tone}><Ic n={t.icon} /></span>
      <span>
        <span className="post-top">{p.featured && <span className="pill lime"><Ic n="push_pin" fill />Destacado</span>}<span className={"pill " + t.tone}>{t.short}</span>{p.done && <span className="pill done">Resuelto</span>}{p.detail && <span style={{ fontSize: 14, color: "var(--muted)", fontWeight: 600 }}>{p.detail}</span>}</span>
        <h3>{p.title}</h3><p>{p.body}</p>
        <span className="post-meta">
          <span className="who">{p.author}</span>{p.role === "negocio" && <span className="badge biz">Negocio</span>}
          <span><Ic n="schedule" />{ago(p.ts)}</span>
          <span><Ic n="chat_bubble" />{p.replies.length} {p.replies.length === 1 ? "respuesta" : "respuestas"}</span>
          {(p.files || []).length > 0 && <span><Ic n="attach_file" />{p.files.length}</span>}
        </span>
      </span>
      {(() => { const im = (p.files || []).find(x => x.type !== "application/pdf"); return im ? <img className="post-thumb" src={im.url} alt="" loading="lazy" /> : null; })()}
    </button>
  );
}

function Board({ posts, filter, setFilter, openPost, onPublish, user }) {
  const [q, setQ] = useState("");
  const [mine, setMine] = useState(false);
  let list = posts.filter(p => filter === "all" || p.type === filter);
  if (mine && user) list = list.filter(p => p.email === user.email);
  if (q.trim()) { const n = vrNorm(q); list = list.filter(p => vrNorm(p.title + " " + p.body).includes(n)); }
  list = [...list].sort((a, b) => (!!b.featured - !!a.featured) || b.ts - a.ts);
  const count = id => posts.filter(p => id === "all" || p.type === id).length;
  return (
    <>
      <section className="phead"><div className="wrap phead-row">
        <div><div className="eyebrow"><Ic n="forum" />Tablón vecinal</div><h1>Pide, ofrece, encuentra</h1><p>Ofertas de empleo, ayuda entre vecinos, cosas que regalas o vendes y objetos perdidos. Todo ordenado.</p></div>
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
          <div className="inline-search"><Ic n="search" /><input value={q} onChange={e => setQ(e.target.value)} placeholder="Buscar en el tablón" /></div>
          <button className="btn lime" onClick={onPublish}><Ic n="add" />Publicar anuncio</button>
        </div>
      </div></section>
      <div className="wrap board">
        <aside className="side">
          <button className={filter === "all" ? "on" : ""} onClick={() => setFilter("all")}><span className="ico green"><Ic n="apps" /></span>Todo<em>{count("all")}</em></button>
          {VB_POST_TYPES.map(t => <button key={t.id} className={filter === t.id ? "on" : ""} onClick={() => setFilter(t.id)}><span className={"ico " + t.tone}><Ic n={t.icon} /></span>{t.label}<em>{count(t.id)}</em></button>)}
          {user && <label className="check" style={{ padding: "12px 12px 0" }}><input type="checkbox" checked={mine} onChange={e => setMine(e.target.checked)} />Solo mis anuncios</label>}
          <div className="side-note"><b>Anuncios que caducan solos</b>Cada anuncio dura 7, 14 o 30 días. Así el tablón siempre está al día.</div>
        </aside>
        <div className="posts">
          {list.length ? list.map(p => <PostCard key={p.id} p={p} onOpen={openPost} />)
            : <div className="empty"><Ic n="forum" style={{ fontSize: 40 }} /><b style={{ color: "var(--ink)" }}>Nada por aquí todavía</b><button className="btn" onClick={onPublish}><Ic n="add" />Sé el primero en publicar</button></div>}
        </div>
      </div>
    </>
  );
}

function PublishModal({ open, onClose, onSave, defType }) {
  const [f, setF] = useState({ type: "ayuda", title: "", body: "", detail: "", days: 14, ok: false });
  const [err, setErr] = useState("");
  const [files, setFiles] = useState([]);
  const [busy, setBusy] = useState(false);
  const fileRef = useRef(null);
  useEffect(() => { if (open) { setF({ type: defType && defType !== "all" ? defType : "ayuda", title: "", body: "", detail: "", days: 14, ok: false }); setErr(""); setFiles([]); setBusy(false); } }, [open]);
  useEffect(() => () => files.forEach(x => x.preview && URL.revokeObjectURL(x.preview)), [files]);
  const addFiles = e => {
    const list = [...e.target.files]; e.target.value = "";
    const ok = list.filter(x => /^image\//.test(x.type) || x.type === "application/pdf");
    if (ok.length < list.length) setErr("Solo se pueden adjuntar fotos o PDF.");
    const big = ok.filter(x => x.type === "application/pdf" && x.size > 5 * 1024 * 1024);
    if (big.length) setErr("Los PDF no pueden pesar más de 5 MB.");
    const add = ok.filter(x => !big.includes(x)).map(file => ({ file, preview: /^image\//.test(file.type) ? URL.createObjectURL(file) : null }));
    setFiles(cur => [...cur, ...add].slice(0, 4));
    if (files.length + add.length > 4) setErr("Puedes adjuntar hasta 4 archivos.");
  };
  const set = k => e => setF({ ...f, [k]: e.target.type === "checkbox" ? e.target.checked : e.target.value });
  const ph = { empleo: ["Buscamos dependiente/a de tarde", "Horario, funciones, requisitos y cómo aplicar.", "Ej.: 20 h/sem · 12 €/h"], ayuda: ["¿Alguien sabe de un buen electricista?", "Cuenta qué necesitas y cuándo.", "Ej.: Este fin de semana"], ofrezco: ["Ofrezco clases de guitarra", "Qué ofreces, experiencia y disponibilidad.", "Ej.: 15 €/h o gratis"], venta: ["Vendo bici infantil", "Estado, medidas y dónde recoger.", "Ej.: 40 € / Gratis"], perdido: ["Encontradas unas llaves en el parque", "Dónde y cuándo, y cómo reconocerlo.", "Ej.: Zona Felipe VI"] }[f.type];
  function save() {
    if (f.title.trim().length < 6 || f.body.trim().length < 10) return setErr("Añade un título y una descripción un poco más completos.");
    if (!f.ok) return setErr("Acepta las normas del tablón para publicar.");
    setErr(""); setBusy(true);
    Promise.resolve(onSave({ ...f, files: files.map(x => x.file) })).catch(e => { setErr((e && e.message && /PDF|foto|Solo/.test(e.message)) ? e.message : "No se pudieron subir los archivos. Revisa tu conexión e inténtalo de nuevo."); setBusy(false); });
  }
  return (
    <Modal open={open} onClose={onClose} wide title="Publicar en el tablón" sub="Elige el tipo de anuncio para que llegue a quien lo necesita."
      footer={<><button className="btn ghost" onClick={onClose}>Cancelar</button><button id="publish-submit-btn" className="btn" onClick={save} disabled={busy}><Ic n="send" />{busy ? (files.length ? "Subiendo archivos…" : "Publicando…") : "Publicar"}</button></>}>
      <div className="types">{VB_POST_TYPES.map(t => <button key={t.id} className={"type-opt" + (f.type === t.id ? " on" : "")} onClick={() => setF({ ...f, type: t.id })}><Ic n={t.icon} />{t.label}</button>)}</div>
      <div className="fld"><label>Título</label><input className="inp" value={f.title} onChange={set("title")} placeholder={ph[0]} maxLength={90} /></div>
      <div className="fld"><label>Descripción</label><textarea className="inp" value={f.body} onChange={set("body")} placeholder={ph[1]}></textarea></div>
      <div className="row2">
        <div className="fld"><label>{f.type === "empleo" ? "Horario y salario" : "Detalle breve (opcional)"}</label><input className="inp" value={f.detail} onChange={set("detail")} placeholder={ph[2]} maxLength={40} /></div>
        <div className="fld"><label>Visible durante</label><select className="inp" value={f.days} onChange={set("days")}><option value={7}>7 días</option><option value={14}>14 días</option><option value={30}>30 días</option></select></div>
      </div>
      <div className="fld"><label>Fotos o PDF (opcional)</label>
        <div className="att-pick" id="publish-files">
          {files.map((x, i) => <div key={i} className="att-item">{x.preview ? <img src={x.preview} alt="" /> : <span className="att-pdf"><Ic n="picture_as_pdf" /><small>{x.file.name}</small></span>}<button type="button" className="att-x" aria-label="Quitar archivo" onClick={() => setFiles(files.filter((_, j) => j !== i))}><Ic n="close" /></button></div>)}
          {files.length < 4 && <button type="button" id="publish-add-file-btn" className="att-add" onClick={() => fileRef.current && fileRef.current.click()}><Ic n="add_photo_alternate" /><span>Añadir</span></button>}
          <input ref={fileRef} type="file" accept="image/*,application/pdf" multiple hidden onChange={addFiles} />
        </div>
        <small>Hasta 4 archivos. Útil para objetos perdidos, compraventa o una oferta en PDF. No subas fotos de personas ni documentos con datos personales.</small>
      </div>
      <label className="check"><input type="checkbox" checked={f.ok} onChange={set("ok")} />Acepto las normas del tablón. Los vecinos me responderán aquí; no se muestra mi email.</label>
      {err && <div className="err">{err}</div>}
    </Modal>
  );
}

function PostDetail({ post, onClose, user, requireAuth, onReply, onResolve, onDelete, onReport }) {
  const [txt, setTxt] = useState("");
  useEffect(() => setTxt(""), [post && post.id]);
  if (!post) return null;
  const t = postType(post.type);
  const own = user && (user.email === post.email || user.role === "admin");
  const send = () => { if (!txt.trim()) return; requireAuth("Crea tu cuenta para responder a este anuncio.", () => { onReply(post, txt.trim()); setTxt(""); }); };
  return (
    <Modal open onClose={onClose} wide title={post.title}
      footer={<>
        {own && !post.done && <button className="btn ghost sm" onClick={() => onResolve(post)}><Ic n="task_alt" />Marcar resuelto</button>}
        {own && <button className="btn ghost sm" onClick={() => onDelete(post)}><Ic n="delete" />Borrar</button>}
        {!own && <button className="btn ghost sm" onClick={() => onReport(post)}><Ic n="flag" />Reportar</button>}
      </>}>
      <div className="post-top"><span className={"pill " + t.tone}>{t.label}</span>{post.done && <span className="pill done">Resuelto</span>}</div>
      <p className="post-full">{post.body}</p>
      {(post.files || []).length > 0 && <div className="attach" id="post-attachments">{post.files.map(x => x.type === "application/pdf"
        ? <a key={x.path} className="attach-pdf" href={x.url} target="_blank" rel="noopener"><Ic n="picture_as_pdf" /><span>{x.name}</span><Ic n="open_in_new" /></a>
        : <a key={x.path} className="attach-img" href={x.url} target="_blank" rel="noopener"><img src={x.url} alt={"Foto adjunta al anuncio: " + post.title} loading="lazy" /></a>)}</div>}
      <div className="detail-grid">
        <span><Ic n="person" />{post.author}</span>
        <span><Ic n="schedule" />{ago(post.ts)}</span>
        {post.detail && <span><Ic n="info" />{post.detail}</span>}
      </div>
      <div className="thread">
        <b>{post.replies.length ? "Respuestas" : "Sé el primero en responder"}</b>
        {post.replies.map((r, i) => <div className="reply" key={i}><div className="reply-h"><span className="avatar" style={{ width: 26, height: 26, fontSize: 11 }}>{initials(r.author)}</span><b>{r.author}</b><small>{ago(r.ts)}</small></div><p>{r.text}</p></div>)}
      </div>
      <div className="reply-form"><textarea className="inp" value={txt} onChange={e => setTxt(e.target.value)} placeholder={user ? "Escribe una respuesta…" : "Entra para responder"}></textarea><button className="btn" onClick={send}><Ic n="send" /></button></div>
    </Modal>
  );
}

Object.assign(window, { Board, PublishModal, PostDetail });
