/* Admin Anuncios — mismos campos que eventos + prioridad y publicación */

const annToLocalDatetime = (iso) => (iso ? String(iso).slice(0, 16) : '');
const annToLocalDate = (iso) => (iso ? String(iso).slice(0, 10) : '');

const AnnouncementFormModal = ({ open, onClose, theme, announcementId, initial, onSaved }) => {
  const [form, setForm] = React.useState({
    title: '',
    body: '',
    priority: 'normal',
    published_at: '',
    starts_at: '',
    ends_at: '',
    end_date: '',
    location: '',
    maps_url: '',
    multi_day: false,
    image_path: '',
    image_focus_x: 50,
    image_focus_y: 50,
  });
  const [coverFile, setCoverFile] = React.useState(null);
  const [coverBlobUrl, setCoverBlobUrl] = React.useState(null);
  const [savedImageUrl, setSavedImageUrl] = React.useState(null);
  const [registrations, setRegistrations] = React.useState([]);
  const [loadingReg, setLoadingReg] = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const [err, setErr] = React.useState('');
  const fileInputRef = React.useRef(null);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const setFocus = (x, y) => setForm(f => ({ ...f, image_focus_x: x, image_focus_y: y }));

  React.useEffect(() => {
    if (!open) return;
    setCoverFile(null);
    setErr('');
    const now = new Date();
    const nowLocal = now.toISOString().slice(0, 16);
    const base = initial || {};
    const pubLocal = annToLocalDatetime(base.published_at) || (announcementId === 'new' ? nowLocal : '');
    setForm({
      title: base.title || '',
      body: base.body || '',
      priority: base.priority || 'normal',
      published_at: pubLocal,
      starts_at: annToLocalDatetime(base.starts_at) || pubLocal || (announcementId === 'new' ? nowLocal : ''),
      ends_at: annToLocalDatetime(base.ends_at),
      end_date: annToLocalDate(base.ends_at) || annToLocalDate(base.starts_at),
      location: base.location || '',
      maps_url: base.maps_url || '',
      multi_day: base.multi_day === true,
      image_path: base.image_path || '',
      image_focus_x: Number(base.image_focus_x) || 50,
      image_focus_y: Number(base.image_focus_y) || 50,
    });
    setSavedImageUrl(base.image_path ? announcementImageUrl(base.image_path) : null);
    setCoverBlobUrl(null);
  }, [open, announcementId, initial?.id]);

  React.useEffect(() => {
    if (!coverFile) {
      setCoverBlobUrl(null);
      return undefined;
    }
    const url = URL.createObjectURL(coverFile);
    setCoverBlobUrl(url);
    return () => URL.revokeObjectURL(url);
  }, [coverFile]);

  React.useEffect(() => {
    if (!open || !announcementId || announcementId === 'new') {
      setRegistrations([]);
      return;
    }
    let cancelled = false;
    setLoadingReg(true);
    fetchAnnouncementRegistrations(announcementId)
      .then(rows => { if (!cancelled) setRegistrations(rows || []); })
      .catch(() => { if (!cancelled) setRegistrations([]); })
      .finally(() => { if (!cancelled) setLoadingReg(false); });
    return () => { cancelled = true; };
  }, [open, announcementId]);

  const removeRegistration = async (id) => {
    if (!confirm('¿Quitar este registro de alumno?')) return;
    try {
      await deleteAnnouncementRegistration(id);
      setRegistrations(prev => prev.filter(r => r.id !== id));
    } catch (e) { alert(e.message); }
  };

  const coverDisplayUrl = coverBlobUrl || savedImageUrl;

  const onPickCover = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (!file.type.startsWith('image/')) {
      alert('Selecciona una imagen (JPG, PNG o WebP).');
      return;
    }
    setCoverFile(file);
    e.target.value = '';
  };

  const save = async () => {
    if (!form.title?.trim()) {
      setErr('El título es obligatorio.');
      return;
    }
    if (!form.body?.trim()) {
      setErr('La descripción es obligatoria.');
      return;
    }
    setSaving(true);
    setErr('');
    try {
      const toIso = typeof datetimeLocalToIso === 'function'
        ? datetimeLocalToIso
        : (v) => (v ? new Date(v).toISOString() : null);
      let publishedAt = toIso(form.published_at);
      if (!publishedAt) {
        publishedAt = new Date().toISOString();
      }
      let startsAt = toIso(form.starts_at);
      if (!startsAt) startsAt = publishedAt;
      let endsAt = null;
      if (form.starts_at) {
        const start = new Date(form.starts_at);
        if (form.multi_day) {
          const endDay = form.end_date || form.starts_at.slice(0, 10);
          const end = new Date(`${endDay}T23:59:59`);
          if (end < start) {
            setErr('La fecha final debe ser igual o posterior al inicio.');
            setSaving(false);
            return;
          }
          endsAt = end.toISOString();
          startsAt = start.toISOString();
        } else if (form.ends_at) {
          endsAt = new Date(form.ends_at).toISOString();
          startsAt = start.toISOString();
        } else {
          startsAt = start.toISOString();
        }
      }

      let image_path = form.image_path || null;
      let savedId = announcementId === 'new' ? null : announcementId;

      const payload = {
        title: form.title,
        body: form.body,
        priority: form.priority,
        published_at: publishedAt,
        starts_at: startsAt,
        ends_at: endsAt,
        location: form.location,
        maps_url: form.maps_url,
        multi_day: form.multi_day,
        image_path,
        image_focus_x: form.image_focus_x,
        image_focus_y: form.image_focus_y,
      };

      const row = await upsertAnnouncement(payload, savedId);
      savedId = row?.id || savedId;

      if (coverFile && savedId) {
        image_path = await uploadAnnouncementImage(coverFile, savedId);
        await upsertAnnouncement({ ...payload, image_path }, savedId);
      }

      onSaved?.();
      if (typeof notifyAnnouncementsChanged === 'function') notifyAnnouncementsChanged();
      onClose();
    } catch (e) { setErr(e.message); }
    setSaving(false);
  };

  return (
    <Modal open={open} onClose={onClose} theme={theme} title={announcementId === 'new' ? 'Nuevo aviso' : 'Editar aviso'} width={800}>
      <div style={{ padding: '8px 24px 24px', display: 'grid', gap: 16, maxHeight: '78vh', overflowY: 'auto' }}>
        <Field label="Título" theme={theme}>
          <input value={form.title} onChange={e => set('title', e.target.value)} style={inputStyle(theme)} />
        </Field>
        <Field label="Descripción" theme={theme}>
          <textarea value={form.body} onChange={e => set('body', e.target.value)} rows={4} style={{ ...inputStyle(theme), resize: 'vertical' }} />
        </Field>
        <Field label="Prioridad" theme={theme}>
          <select value={form.priority} onChange={e => set('priority', e.target.value)} style={inputStyle(theme)}>
            <option value="normal">Normal</option>
            <option value="alta">Alta</option>
            <option value="urgente">Urgente</option>
          </select>
        </Field>
        <div style={{
          padding: 12, borderRadius: 10, background: theme.bgInput, border: `1px solid ${theme.border}`,
          display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'center', justifyContent: 'space-between',
        }}>
          <p style={{ margin: 0, fontSize: 12, color: theme.textDim, fontFamily: 'Inter, sans-serif', lineHeight: 1.45, flex: 1, minWidth: 200 }}>
            Para que el aviso aparezca en la landing y en el calendario, debe tener fecha de publicación (ahora o antes) y fecha de referencia.
          </p>
          <Btn theme={theme} kind="soft" size="sm" icon="check" onClick={() => {
            const n = new Date().toISOString().slice(0, 16);
            setForm(f => ({ ...f, published_at: n, starts_at: f.starts_at || n }));
          }}>
            Publicar ahora
          </Btn>
        </div>
        <Field label="Publicar en sitio (obligatorio para mostrar)" theme={theme}>
          <input type="datetime-local" value={form.published_at} onChange={e => set('published_at', e.target.value)} style={inputStyle(theme)} />
        </Field>
        <Field label="Fecha en calendario (día del aviso)" theme={theme}>
          <input type="datetime-local" value={form.starts_at} onChange={e => set('starts_at', e.target.value)} style={inputStyle(theme)} />
        </Field>
        <label style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 13, color: theme.text, fontFamily: 'Inter, sans-serif', cursor: 'pointer' }}>
          <input type="checkbox" checked={form.multi_day} onChange={e => set('multi_day', e.target.checked)} />
          El aviso aplica varios días (vigencia extendida)
        </label>
        {form.multi_day ? (
          <Field label="Último día de vigencia" theme={theme}>
            <input type="date" value={form.end_date} onChange={e => set('end_date', e.target.value)} style={inputStyle(theme)} />
          </Field>
        ) : (
          <Field label="Fin de vigencia (opcional)" theme={theme}>
            <input type="datetime-local" value={form.ends_at} onChange={e => set('ends_at', e.target.value)} style={inputStyle(theme)} />
          </Field>
        )}
        <Field label="Lugar" theme={theme}>
          <input value={form.location} onChange={e => set('location', e.target.value)} placeholder="Ej. Cancha principal" style={inputStyle(theme)} />
        </Field>
        <Field label="Enlace Google Maps" theme={theme}>
          <input value={form.maps_url} onChange={e => set('maps_url', e.target.value)} placeholder="https://maps.google.com/..." style={inputStyle(theme)} />
        </Field>
        <div>
          <div style={{ fontSize: 12, fontWeight: 700, color: theme.textMute, marginBottom: 8, fontFamily: 'Inter, sans-serif', letterSpacing: 0.5, textTransform: 'uppercase' }}>
            Imagen del aviso
          </div>
          <input ref={fileInputRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={onPickCover} />
          <Btn theme={theme} kind="soft" size="sm" icon="upload" onClick={() => fileInputRef.current?.click()}>Subir imagen</Btn>
          {coverFile && (
            <span style={{ marginLeft: 10, fontSize: 12, color: theme.textDim, fontFamily: 'Inter, sans-serif' }}>
              {coverFile.name}
            </span>
          )}
          {coverDisplayUrl && typeof AnnouncementLandingPreview === 'function' ? (
            <AnnouncementLandingPreview
              theme={theme}
              imageUrl={coverDisplayUrl}
              focusX={form.image_focus_x}
              focusY={form.image_focus_y}
              onFocusChange={setFocus}
              title={form.title}
              body={form.body}
              priority={form.priority}
            />
          ) : coverDisplayUrl ? (
            <div style={{ marginTop: 12 }}>
              <LandingFocusPhotoFrame
                theme={theme}
                imageUrl={coverDisplayUrl}
                focusX={form.image_focus_x}
                focusY={form.image_focus_y}
                onFocusChange={setFocus}
                aspectRatio="16/9"
                maxWidth={420}
              />
            </div>
          ) : null}
        </div>

        {announcementId && announcementId !== 'new' && typeof InterestRegistrationsPanel === 'function' && (
          <InterestRegistrationsPanel
            theme={theme}
            kind="announcement"
            entityId={announcementId}
            entity={{
              title: form.title || initial?.title,
              starts_at: form.starts_at || initial?.starts_at,
              location: form.location || initial?.location,
            }}
            studentRows={registrations}
            loadingStudents={loadingReg}
            onRemoveStudent={removeRegistration}
            reload={registrations.length}
          />
        )}

        {err && <div style={{ color: theme.danger, fontSize: 13 }}>{err}</div>}
        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <Btn theme={theme} kind="ghost" onClick={onClose}>Cancelar</Btn>
          <Btn theme={theme} onClick={save} disabled={saving}>{saving ? 'Guardando…' : 'Guardar aviso'}</Btn>
        </div>
      </div>
    </Modal>
  );
};

const AnunciosAdminModule = ({ theme }) => {
  const { rows, loading, error, needsAuth, reload } = useAdminList(() => fetchAnnouncementsAdmin(), []);
  const [modal, setModal] = React.useState(null);
  const [editRow, setEditRow] = React.useState(null);

  const openNew = () => { setEditRow(null); setModal('new'); };
  const openEdit = (r) => { setEditRow(r); setModal(r.id); };
  const del = async (id) => {
    if (!confirm('¿Eliminar este aviso?')) return;
    try { await deleteAnnouncement(id); reload(); } catch (e) { alert(e.message); }
  };

  return (
    <AdminEntityShell theme={theme} title="ANUNCIOS" sub="Avisos en landing y portal. Campos como eventos, estilo visual distinto en el sitio." icon="megaphone" onAdd={openNew} addLabel="Nuevo aviso">
      {needsAuth ? <AuthRequired theme={theme} onRetry={reload} /> : loading ? <LoadingBlock theme={theme} /> : error ? <EmptyState theme={theme} title="Error" message={error} /> : (
        <Card theme={theme} style={{ padding: 0, overflow: 'hidden' }}>
          {rows.length === 0 ? <EmptyState theme={theme} title="Sin avisos" message="Crea el primer aviso." icon="megaphone" /> : rows.map(r => (
            <div key={r.id} style={{ padding: 16, borderBottom: `1px solid ${theme.border}`, display: 'flex', gap: 12, alignItems: 'center' }}>
              {r.image_path ? (
                <img src={announcementImageUrl(r.image_path)} alt="" style={{ width: 48, height: 48, borderRadius: 8, objectFit: 'cover' }} />
              ) : (
                <div style={{ width: 48, height: 48, borderRadius: 8, background: theme.bgInput, display: 'grid', placeItems: 'center' }}>
                  <Icon name="megaphone" size={20} style={{ color: theme.textMute }} />
                </div>
              )}
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700, color: theme.text }}>{r.title}</div>
                <div style={{ fontSize: 12, color: theme.textDim, marginTop: 4 }}>
                  {r.published_at ? `Publicado ${new Date(r.published_at).toLocaleString('es-MX')}` : 'Borrador'}
                  {' · '}{r.priority}
                  {r.starts_at ? ` · ${new Date(r.starts_at).toLocaleDateString('es-MX')}` : ''}
                </div>
              </div>
              <RowActions theme={theme} onEdit={() => openEdit(r)} onDelete={() => del(r.id)} />
            </div>
          ))}
        </Card>
      )}
      <AnnouncementFormModal
        open={!!modal}
        onClose={() => setModal(null)}
        theme={theme}
        announcementId={modal}
        initial={editRow}
        onSaved={reload}
      />
    </AdminEntityShell>
  );
};

Object.assign(window, { AnunciosAdminModule });
