/* Admin Eventos — formulario completo, imagen con encuadre, confirmaciones */

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

const EventFormModal = ({ open, onClose, theme, eventId, initial, onSaved }) => {
  const [form, setForm] = React.useState({
    title: '',
    description: '',
    starts_at: '',
    ends_at: '',
    end_date: '',
    location: '',
    maps_url: '',
    category: 'general',
    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 [confirmations, setConfirmations] = React.useState([]);
  const [loadingConf, setLoadingConf] = 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 base = initial || {};
    const startLocal = toLocalDatetime(base.starts_at) || now.toISOString().slice(0, 16);
    const endIso = base.ends_at || base.starts_at;
    setForm({
      title: base.title || '',
      description: base.description || '',
      starts_at: startLocal,
      ends_at: toLocalDatetime(base.ends_at),
      end_date: toLocalDate(base.ends_at) || toLocalDate(base.starts_at),
      location: base.location || '',
      maps_url: base.maps_url || '',
      category: base.category || 'general',
      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 ? eventImageUrl(base.image_path) : null);
    setCoverBlobUrl(null);
  }, [open, eventId, 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 || !eventId || eventId === 'new') {
      setConfirmations([]);
      return;
    }
    let cancelled = false;
    setLoadingConf(true);
    fetchEventConfirmations(eventId)
      .then(rows => { if (!cancelled) setConfirmations(rows || []); })
      .catch(() => { if (!cancelled) setConfirmations([]); })
      .finally(() => { if (!cancelled) setLoadingConf(false); });
    return () => { cancelled = true; };
  }, [open, eventId]);

  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.starts_at) {
      setErr('Indica la fecha del evento.');
      return;
    }
    setSaving(true);
    setErr('');
    try {
      const startsAt = new Date(form.starts_at);
      let endsAt = null;
      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 < startsAt) {
          setErr('La fecha final debe ser igual o posterior al inicio.');
          setSaving(false);
          return;
        }
        endsAt = end.toISOString();
      } else if (form.ends_at) {
        endsAt = new Date(form.ends_at).toISOString();
      }

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

      const payload = {
        title: form.title,
        description: form.description,
        starts_at: startsAt.toISOString(),
        ends_at: endsAt,
        location: form.location,
        maps_url: form.maps_url,
        category: form.category,
        multi_day: form.multi_day,
        image_path,
        image_focus_x: form.image_focus_x,
        image_focus_y: form.image_focus_y,
      };

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

      if (coverFile && savedId) {
        image_path = await uploadEventImage(coverFile, savedId);
        await upsertEvent({ ...payload, image_path }, savedId);
      }

      onSaved?.();
      onClose();
    } catch (e) { setErr(e.message); }
    setSaving(false);
  };

  const removeConfirmation = async (id) => {
    if (!confirm('¿Quitar esta confirmación?')) return;
    try {
      await deleteEventConfirmation(id);
      setConfirmations(c => c.filter(x => x.id !== id));
    } catch (e) { alert(e.message); }
  };

  return (
    <Modal open={open} onClose={onClose} theme={theme} title={eventId === 'new' ? 'Nuevo evento' : 'Editar evento'} width={720}>
      <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.description} onChange={e => set('description', e.target.value)} rows={4} style={{ ...inputStyle(theme), resize: 'vertical' }} />
        </Field>
        <Field label="Fecha y hora del evento" 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 evento dura varios días (aparece en el calendario en ese rango)
        </label>
        {form.multi_day ? (
          <Field label="Último día del evento" theme={theme}>
            <input type="date" value={form.end_date} onChange={e => set('end_date', e.target.value)} style={inputStyle(theme)} />
          </Field>
        ) : (
          <Field label="Fin (opcional, misma fecha)" 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>
        <Field label="Categoría" theme={theme}>
          <select value={form.category} onChange={e => set('category', e.target.value)} style={inputStyle(theme)}>
            <option value="general">General</option>
            <option value="torneo">Torneo</option>
            <option value="entrenamiento">Entrenamiento</option>
            <option value="reunion">Reunión</option>
            <option value="pago">Pago</option>
            <option value="cumpleanos">Cumpleaños</option>
          </select>
        </Field>

        <div>
          <div style={{ fontSize: 12, fontWeight: 700, color: theme.textMute, marginBottom: 8, fontFamily: 'Inter, sans-serif', letterSpacing: 0.5, textTransform: 'uppercase' }}>
            Imagen del evento
          </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>
          {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={360}
              />
            </div>
          )}
        </div>

        {eventId && eventId !== 'new' && typeof InterestRegistrationsPanel === 'function' && (
          <InterestRegistrationsPanel
            theme={theme}
            kind="event"
            entityId={eventId}
            entity={{
              title: form.title || initial?.title,
              starts_at: form.starts_at || initial?.starts_at,
              location: form.location || initial?.location,
            }}
            studentRows={confirmations}
            loadingStudents={loadingConf}
            onRemoveStudent={removeConfirmation}
            reload={confirmations.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 evento'}</Btn>
        </div>
      </div>
    </Modal>
  );
};

const EventosAdminModule = ({ theme }) => {
  const { rows, loading, error, needsAuth, reload } = useAdminList(() => fetchEventsAdmin(), []);
  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 evento?')) return;
    try { await deleteEvent(id); reload(); } catch (e) { alert(e.message); }
  };

  return (
    <AdminEntityShell theme={theme} title="EVENTOS" sub="Calendario público, imagen, maps y confirmaciones de asistencia." icon="cal" onAdd={openNew}>
      {needsAuth ? <AuthRequired theme={theme} onRetry={reload} /> : loading ? <LoadingBlock theme={theme} /> : error ? <EmptyState theme={theme} title="Error" message={error} /> : (
        <Card theme={theme} style={{ padding: 0 }}>
          {rows.length === 0 ? <EmptyState theme={theme} title="Sin eventos" icon="cal" /> : 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={eventImageUrl(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="cal" size={20} style={{ color: theme.textMute }} />
                </div>
              )}
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700 }}>{r.title}</div>
                <div style={{ fontSize: 12, color: theme.textDim }}>
                  {new Date(r.starts_at).toLocaleString('es-MX')}
                  {r.multi_day && r.ends_at ? ` → ${new Date(r.ends_at).toLocaleDateString('es-MX')}` : ''}
                  {' · '}{r.category}
                </div>
              </div>
              <RowActions theme={theme} onEdit={() => openEdit(r)} onDelete={() => del(r.id)} />
            </div>
          ))}
        </Card>
      )}
      <EventFormModal
        open={!!modal}
        onClose={() => setModal(null)}
        theme={theme}
        eventId={modal}
        initial={editRow}
        onSaved={reload}
      />
    </AdminEntityShell>
  );
};

Object.assign(window, { EventosAdminModule });
