/* Formulario admin de entrenadores — landing */

const DEFAULT_COACH_FORM = {
  name: '',
  specialty: '',
  experience_years: '',
  card_summary: '',
  trajectory: '',
  certifications: '',
  assigned_groups: '',
  icon: 'whistle',
  photo_path: '',
  photo_focus_x: 50,
  photo_focus_y: 50,
  sort_order: 0,
  active: true,
};

const COACH_ICON_OPTS = [
  { value: 'whistle', label: 'Silbato (entrenador)' },
  { value: 'medal', label: 'Medalla' },
  { value: 'trophy', label: 'Trofeo' },
  { value: 'star', label: 'Estrella' },
  { value: 'target', label: 'Objetivo' },
];

const clampFocus = (v) => Math.max(5, Math.min(95, Number(v) || 50));

/** Vista previa de tarjeta landing + arrastre para encuadrar foto */
const CoachLandingPhotoPreview = ({ theme, imageUrl, form, focusX, focusY, onFocusChange }) => {
  const frameRef = React.useRef(null);
  const dragRef = React.useRef(null);

  const fx = clampFocus(focusX);
  const fy = clampFocus(focusY);
  const objPos = `${fx}% ${fy}%`;

  const onPointerDown = (e) => {
    if (!imageUrl) return;
    dragRef.current = {
      startX: e.clientX,
      startY: e.clientY,
      startFx: fx,
      startFy: fy,
    };
    e.currentTarget.setPointerCapture(e.pointerId);
  };

  const onPointerMove = (e) => {
    const d = dragRef.current;
    if (!d || !frameRef.current) return;
    const rect = frameRef.current.getBoundingClientRect();
    const dx = e.clientX - d.startX;
    const dy = e.clientY - d.startY;
    const nx = clampFocus(d.startFx - (dx / rect.width) * 120);
    const ny = clampFocus(d.startFy - (dy / rect.height) * 120);
    onFocusChange(nx, ny);
  };

  const onPointerUp = (e) => {
    dragRef.current = null;
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch { /* ignore */ }
  };

  const displayName = form.name?.trim() || 'Nombre del entrenador';
  const displayRole = form.specialty?.trim() || 'Entrenador';
  const displayExp = (form.experience_years || '').trim();

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8, gap: 8, flexWrap: 'wrap' }}>
        <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>
          Vista previa — tarjeta en landing
        </label>
        {imageUrl && (
          <button type="button" onClick={() => onFocusChange(50, 50)}
            style={{
              fontSize: 11, padding: '4px 10px', borderRadius: 6, cursor: 'pointer',
              border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.textDim,
              fontFamily: 'Inter, sans-serif',
            }}>
            Centrar foto
          </button>
        )}
      </div>
      {imageUrl && (
        <p style={{ margin: '0 0 10px', fontSize: 11, color: theme.textDim, fontFamily: 'Inter, sans-serif' }}>
          Arrastra la foto para ajustar el encuadre. Así se verá en el sitio público.
        </p>
      )}
      <Card theme={theme} style={{ padding: 0, overflow: 'hidden', maxWidth: 220, margin: '0 auto' }}>
        <div
          ref={frameRef}
          onPointerDown={onPointerDown}
          onPointerMove={onPointerMove}
          onPointerUp={onPointerUp}
          onPointerCancel={onPointerUp}
          style={{
            aspectRatio: '4/3',
            background: `linear-gradient(180deg, ${theme.primary}28, ${theme.bgInput})`,
            position: 'relative',
            overflow: 'hidden',
            cursor: imageUrl ? 'grab' : 'default',
            touchAction: 'none',
            userSelect: 'none',
          }}
        >
          {imageUrl ? (
            <img
              src={imageUrl}
              alt=""
              draggable={false}
              style={{
                position: 'absolute', inset: 0, width: '100%', height: '100%',
                objectFit: 'cover',
                objectPosition: objPos,
                pointerEvents: 'none',
              }}
            />
          ) : (
            <div style={{ width: '100%', height: '100%', display: 'grid', placeItems: 'center' }}>
              <Icon name="user" size={48} style={{ color: theme.textMute }} />
            </div>
          )}
          {displayExp && (
            <div style={{
              position: 'absolute', top: 8, right: 8, padding: '3px 8px', borderRadius: 999,
              background: 'rgba(0,0,0,0.55)', fontSize: 9, fontWeight: 700, color: '#fff',
              fontFamily: 'Inter, sans-serif', pointerEvents: 'none',
            }}>{displayExp} EXP.</div>
          )}
          <div style={{
            position: 'absolute', bottom: 8, left: 8, width: 28, height: 28, borderRadius: 6,
            background: theme.primary, color: '#fff', display: 'grid', placeItems: 'center',
            pointerEvents: 'none',
          }}>
            <Icon name={form.icon || 'whistle'} size={14} />
          </div>
        </div>
        <div style={{ padding: '12px 12px 14px' }}>
          <h4 style={{
            fontFamily: 'Bebas Neue, sans-serif', fontSize: 18, letterSpacing: 0.5,
            color: theme.text, margin: 0, fontWeight: 400, lineHeight: 1.1,
          }}>{displayName}</h4>
          <div style={{
            fontSize: 10, color: theme.primary, marginTop: 2, fontWeight: 700,
            letterSpacing: 0.8, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif',
          }}>{displayRole}</div>
          {form.card_summary?.trim() && (
            <p style={{
              fontSize: 11, color: theme.textDim, margin: '6px 0 0', fontFamily: 'Inter, sans-serif',
              lineHeight: 1.35, display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden',
            }}>{form.card_summary.trim()}</p>
          )}
        </div>
      </Card>
    </div>
  );
};

const CoachFormModal = ({
  open, onClose, theme, form, onChange, onFocusChange, onSave, saving, error, photoPreview, onPhoto, uploadingPhoto,
}) => (
  <Modal open={open} onClose={onClose} theme={theme} title="Entrenador — contenido de la landing" width={700}>
    <div style={{ padding: '8px 24px 24px', display: 'grid', gap: 16, maxHeight: '75vh', overflowY: 'auto' }}>
      <p style={{ margin: 0, fontSize: 12, color: theme.textDim, fontFamily: 'Inter, sans-serif', lineHeight: 1.5 }}>
        Estos campos alimentan la tarjeta en el sitio público y el modal «Ver perfil».
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <Input theme={theme} label="Nombre completo *" value={form.name || ''} onChange={e => onChange('name', e.target.value)} icon="user" />
        <Input theme={theme} label="Rol / cargo (badge)" value={form.specialty || ''} onChange={e => onChange('specialty', e.target.value)} placeholder="Ej. Entrenador principal" />
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
        <Input theme={theme} label="Años exp. (tarjeta)" value={form.experience_years || ''} onChange={e => onChange('experience_years', e.target.value)} placeholder="12" />
        <div>
          <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Icono en tarjeta</label>
          <select value={form.icon || 'whistle'} onChange={e => onChange('icon', e.target.value)}
            style={{ width: '100%', marginTop: 6, padding: 12, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif' }}>
            {COACH_ICON_OPTS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
          </select>
        </div>
        <Input theme={theme} label="Orden en lista" type="number" value={form.sort_order ?? 0} onChange={e => onChange('sort_order', e.target.value)} />
      </div>
      <div>
        <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Resumen en tarjeta (corto)</label>
        <textarea value={form.card_summary || ''} onChange={e => onChange('card_summary', e.target.value)} rows={2} placeholder="1–2 líneas bajo el nombre en la landing"
          style={{ width: '100%', marginTop: 6, padding: 12, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif', resize: 'vertical' }} />
      </div>
      <div>
        <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Foto (tarjeta y modal)</label>
        <input type="file" accept="image/jpeg,image/png,image/webp" onChange={onPhoto}
          style={{ marginTop: 8, fontSize: 12, fontFamily: 'Inter, sans-serif', display: 'block' }} />
        {uploadingPhoto && <div style={{ fontSize: 11, color: theme.primary, marginTop: 4, fontFamily: 'Inter, sans-serif' }}>Subiendo…</div>}
      </div>

      <CoachLandingPhotoPreview
        theme={theme}
        imageUrl={photoPreview}
        form={form}
        focusX={form.photo_focus_x}
        focusY={form.photo_focus_y}
        onFocusChange={onFocusChange}
      />

      <div>
        <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Trayectoria (modal Ver perfil)</label>
        <textarea value={form.trajectory || ''} onChange={e => onChange('trajectory', e.target.value)} rows={4} placeholder="Experiencia, logros, enfoque de entrenamiento…"
          style={{ width: '100%', marginTop: 6, padding: 12, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif', resize: 'vertical' }} />
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <div>
          <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Certificaciones (una por línea)</label>
          <textarea value={form.certifications || ''} onChange={e => onChange('certifications', e.target.value)} rows={4} placeholder={'FIVB Nivel III\nConade acreditado'}
            style={{ width: '100%', marginTop: 6, padding: 12, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif', resize: 'vertical' }} />
        </div>
        <div>
          <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Grupos asignados (una por línea)</label>
          <textarea value={form.assigned_groups || ''} onChange={e => onChange('assigned_groups', e.target.value)} rows={4} placeholder={'Lun/Mié — Sub-14\nMar/Jue — Mayor'}
            style={{ width: '100%', marginTop: 6, padding: 12, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif', resize: 'vertical' }} />
        </div>
      </div>
      <div>
        <label style={{ fontSize: 11, color: theme.textMute, fontWeight: 700, textTransform: 'uppercase', fontFamily: 'Inter, sans-serif' }}>Visible en landing</label>
        <select value={form.active === false ? 'false' : 'true'} onChange={e => onChange('active', e.target.value === 'true')}
          style={{ display: 'block', marginTop: 6, padding: 10, borderRadius: 8, border: `1px solid ${theme.border}`, background: theme.bgInput, color: theme.text, fontFamily: 'Inter, sans-serif', maxWidth: 280 }}>
          <option value="true">Sí — publicado</option>
          <option value="false">No — oculto</option>
        </select>
      </div>
      {error && <div style={{ color: theme.danger, fontSize: 13, fontFamily: 'Inter, sans-serif' }}>{error}</div>}
    </div>
    <div style={{ padding: '16px 24px', borderTop: `1px solid ${theme.border}`, display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
      <Btn theme={theme} kind="ghost" onClick={onClose}>Cancelar</Btn>
      <Btn theme={theme} icon="check" onClick={onSave} disabled={saving || uploadingPhoto}>{saving ? 'Guardando…' : 'Guardar'}</Btn>
    </div>
  </Modal>
);

const EntrenadoresAdminModule = ({ theme }) => {
  const { rows, loading, error, needsAuth, reload } = useAdminList(async () => {
    const sb = getSupabase();
    const { data, error } = await sb.from('coaches').select('*').order('sort_order');
    if (error) throw error;
    return data || [];
  }, []);
  const [modal, setModal] = React.useState(null);
  const [form, setForm] = React.useState({ ...DEFAULT_COACH_FORM });
  const [saving, setSaving] = React.useState(false);
  const [formErr, setFormErr] = React.useState('');
  const [uploadingPhoto, setUploadingPhoto] = React.useState(false);
  const [localPhotoUrl, setLocalPhotoUrl] = React.useState(null);

  React.useEffect(() => () => {
    if (localPhotoUrl) URL.revokeObjectURL(localPhotoUrl);
  }, [localPhotoUrl]);

  const closeModal = () => {
    setModal(null);
    if (localPhotoUrl) {
      URL.revokeObjectURL(localPhotoUrl);
      setLocalPhotoUrl(null);
    }
  };

  const openNew = () => {
    setForm({ ...DEFAULT_COACH_FORM });
    setFormErr('');
    if (localPhotoUrl) URL.revokeObjectURL(localPhotoUrl);
    setLocalPhotoUrl(null);
    setModal('new');
  };

  const openEdit = (r) => {
    setForm({
      name: r.name || '',
      specialty: r.specialty || '',
      experience_years: r.experience_years || '',
      card_summary: r.card_summary || '',
      trajectory: r.trajectory || r.bio || '',
      certifications: r.certifications || '',
      assigned_groups: r.assigned_groups || '',
      icon: r.icon || 'whistle',
      photo_path: r.photo_path || '',
      photo_focus_x: Number(r.photo_focus_x) || 50,
      photo_focus_y: Number(r.photo_focus_y) || 50,
      sort_order: r.sort_order ?? 0,
      active: r.active !== false,
    });
    setFormErr('');
    if (localPhotoUrl) URL.revokeObjectURL(localPhotoUrl);
    setLocalPhotoUrl(null);
    setModal(r.id);
  };

  const storagePhotoUrl = form.photo_path
    ? (getStoragePublicUrl('gallery', form.photo_path) || getStoragePublicUrl('public-assets', form.photo_path))
    : null;
  const photoPreview = localPhotoUrl || storagePhotoUrl;

  const save = async () => {
    if (!form.name?.trim()) { setFormErr('El nombre es obligatorio.'); return; }
    setSaving(true);
    setFormErr('');
    try {
      await upsertCoach(form, modal === 'new' ? null : modal);
      notifyCoachesChanged();
      closeModal();
      reload();
    } catch (e) { setFormErr(e.message); }
    setSaving(false);
  };

  const onPhoto = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (localPhotoUrl) URL.revokeObjectURL(localPhotoUrl);
    const blobUrl = URL.createObjectURL(file);
    setLocalPhotoUrl(blobUrl);
    setForm(f => ({ ...f, photo_focus_x: 50, photo_focus_y: 50 }));
    setUploadingPhoto(true);
    setFormErr('');
    try {
      const path = await uploadCoachPhoto(file, modal === 'new' ? null : modal);
      setForm(f => ({ ...f, photo_path: path }));
    } catch (err) { setFormErr(err.message || 'Error al subir foto'); }
    setUploadingPhoto(false);
    e.target.value = '';
  };

  const onFormChange = (k, v) => setForm(f => ({ ...f, [k]: v }));

  return (
    <AdminEntityShell theme={theme} title="ENTRENADORES" sub="Todo lo que ves en la sección Entrenadores del sitio público." icon="whistle"
      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 entrenadores" message="Agrega el cuerpo técnico para la landing." icon="whistle" action={<Btn theme={theme} onClick={openNew}>Agregar entrenador</Btn>} />
          ) : rows.map(r => {
            const thumb = r.photo_path ? getStoragePublicUrl('gallery', r.photo_path) : null;
            const focus = coachPhotoFocus(r);
            return (
              <div key={r.id} style={{ padding: 14, borderBottom: `1px solid ${theme.border}`, display: 'flex', gap: 12, alignItems: 'center' }}>
                {thumb ? (
                  <img src={thumb} alt="" style={{
                    width: 48, height: 48, borderRadius: 8, objectFit: 'cover',
                    objectPosition: `${focus.x}% ${focus.y}%`,
                  }} />
                ) : (
                  <Avatar name={r.name} size={48} theme={theme} />
                )}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700 }}>{r.name}</div>
                  <div style={{ fontSize: 12, color: theme.textDim }}>
                    {r.specialty || '—'} · Orden {r.sort_order}
                    {r.experience_years ? ` · ${r.experience_years} años exp.` : ''}
                    {!r.active ? ' · Oculto' : ''}
                  </div>
                </div>
                <RowActions theme={theme} onEdit={() => openEdit(r)}
                  onDelete={async () => { if (confirm(`¿Eliminar a ${r.name}?`)) { await deleteCoach(r.id); notifyCoachesChanged(); reload(); } }} />
              </div>
            );
          })}
        </Card>
      )}
      <CoachFormModal open={!!modal} onClose={closeModal} theme={theme} form={form}
        onChange={onFormChange}
        onFocusChange={(x, y) => setForm(f => ({ ...f, photo_focus_x: x, photo_focus_y: y }))}
        onSave={save} saving={saving} error={formErr} photoPreview={photoPreview} onPhoto={onPhoto} uploadingPhoto={uploadingPhoto} />
    </AdminEntityShell>
  );
};

Object.assign(window, { EntrenadoresAdminModule, CoachFormModal, CoachLandingPhotoPreview, DEFAULT_COACH_FORM });
