// AdminPage.jsx — gated admin backend for managing farm listings.
//
// Flow: not logged in → login form. Logged in → dashboard listing all farms
// with create / edit / delete, plus per-listing image upload & management.
// All data lives server-side via window.API; this is just the UI.

const CATEGORY_OPTIONS = [
  'Pumpkin Patch', 'Apple Orchard', 'Flower Farm',
  'Berry Farm', 'Corn Maze', 'Christmas Tree Farm',
];
const PRICE_OPTIONS = ['$', '$$', '$$$'];
const MONTHS = [
  'January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December',
];

// ── Shared styles ──
const adminInput = {
  width: '100%', padding: '9px 12px', borderRadius: 8,
  border: '2px solid var(--cream-mid)', fontSize: 14,
  fontFamily: 'Source Serif 4, serif', color: 'var(--bark)',
  background: '#fff', outline: 'none', transition: 'border-color 0.2s',
};
const adminLabel = {
  display: 'block', fontSize: 11, fontFamily: 'DM Mono, monospace',
  letterSpacing: '0.08em', textTransform: 'uppercase',
  color: 'var(--bark-light)', marginBottom: 6,
};
const btnPrimary = {
  background: 'var(--orange)', color: '#fff', border: 'none',
  borderRadius: 8, padding: '10px 20px', fontSize: 14,
  fontFamily: 'Source Serif 4, serif', fontWeight: 600, cursor: 'pointer',
  transition: 'background 0.2s',
};
const btnGhost = {
  background: 'none', color: 'var(--bark)', border: '2px solid var(--cream-mid)',
  borderRadius: 8, padding: '8px 16px', fontSize: 14,
  fontFamily: 'Source Serif 4, serif', fontWeight: 600, cursor: 'pointer',
  transition: 'all 0.2s',
};

function AdminField({ label, children }) {
  return (
    <div style={{ marginBottom: 16 }}>
      <label style={adminLabel}>{label}</label>
      {children}
    </div>
  );
}

function TextInput({ value, onChange, type = 'text', placeholder }) {
  return (
    <input
      type={type}
      value={value ?? ''}
      placeholder={placeholder}
      onChange={(e) => onChange(e.target.value)}
      style={adminInput}
      onFocus={(e) => (e.target.style.borderColor = 'var(--orange)')}
      onBlur={(e) => (e.target.style.borderColor = 'var(--cream-mid)')}
    />
  );
}

// ── Login ──
function LoginForm({ onSuccess }) {
  const [username, setUsername] = React.useState('');
  const [password, setPassword] = React.useState('');
  const [error, setError] = React.useState(null);
  const [busy, setBusy] = React.useState(false);

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true);
    setError(null);
    try {
      const user = await window.API.login(username, password);
      onSuccess(user);
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{
      minHeight: '70vh', display: 'flex', alignItems: 'center',
      justifyContent: 'center', padding: '0 1.5rem',
    }}>
      <form onSubmit={submit} style={{
        width: '100%', maxWidth: 380, background: '#fff',
        border: '1px solid var(--cream-mid)', borderRadius: 14,
        padding: 'clamp(1.5rem, 4vw, 2.5rem)',
        boxShadow: '0 8px 30px rgba(0,0,0,0.08)',
      }}>
        <h1 style={{
          fontFamily: 'Playfair Display, serif', fontSize: 26,
          color: 'var(--bark)', marginBottom: 6,
        }}>Admin Sign In</h1>
        <p style={{ fontSize: 14, color: 'var(--bark-light)', marginBottom: 24 }}>
          Manage farm listings & photos.
        </p>
        <AdminField label="Username">
          <TextInput value={username} onChange={setUsername} placeholder="admin" />
        </AdminField>
        <AdminField label="Password">
          <TextInput value={password} onChange={setPassword} type="password" placeholder="••••••••" />
        </AdminField>
        {error && (
          <div style={{
            background: 'var(--orange-pale)', color: '#7A2E00',
            borderRadius: 8, padding: '10px 12px', fontSize: 13, marginBottom: 16,
          }}>{error}</div>
        )}
        <button type="submit" disabled={busy} style={{ ...btnPrimary, width: '100%', opacity: busy ? 0.6 : 1 }}>
          {busy ? 'Signing in…' : 'Sign In'}
        </button>
      </form>
    </div>
  );
}

// ── Image manager (per listing) ──
function ImageManager({ listing, onChange }) {
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [urlInput, setUrlInput] = React.useState('');
  const fileRef = React.useRef(null);
  const images = listing.images || [];

  const handleUpload = async (e) => {
    const files = Array.from(e.target.files || []);
    if (!files.length) return;
    setBusy(true);
    setError(null);
    try {
      const updated = await window.API.uploadImages(listing.id, files);
      onChange(updated);
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
      if (fileRef.current) fileRef.current.value = '';
    }
  };

  const addUrl = async () => {
    const url = urlInput.trim();
    if (!url) return;
    setBusy(true);
    setError(null);
    try {
      const updated = await window.API.updateListing(listing.id, { images: [...images, url] });
      onChange(updated);
      setUrlInput('');
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  };

  const removeImage = async (url) => {
    setBusy(true);
    setError(null);
    try {
      const updated = await window.API.deleteImage(listing.id, url);
      onChange(updated);
    } catch (err) {
      setError(err.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={{
      background: 'var(--cream)', border: '1px solid var(--cream-mid)',
      borderRadius: 10, padding: 16, marginBottom: 20,
    }}>
      <div style={{ ...adminLabel, marginBottom: 12 }}>Photos ({images.length})</div>

      {images.length > 0 && (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, marginBottom: 14 }}>
          {images.map((img, i) => (
            <div key={i} style={{ position: 'relative', width: 110, height: 80 }}>
              <img src={img} alt={`Photo ${i + 1}`} style={{
                width: '100%', height: '100%', objectFit: 'cover',
                borderRadius: 8, border: i === 0 ? '2px solid var(--orange)' : '1px solid var(--cream-mid)',
              }} />
              {i === 0 && (
                <span style={{
                  position: 'absolute', bottom: 3, left: 3,
                  background: 'var(--orange)', color: '#fff', fontSize: 9,
                  padding: '1px 5px', borderRadius: 3, fontFamily: 'DM Mono, monospace',
                }}>PRIMARY</span>
              )}
              <button
                onClick={() => removeImage(img)}
                disabled={busy}
                title="Remove photo"
                style={{
                  position: 'absolute', top: -8, right: -8,
                  width: 22, height: 22, borderRadius: '50%',
                  background: '#fff', border: '1px solid var(--cream-mid)',
                  color: 'var(--bark)', cursor: 'pointer', fontSize: 13, lineHeight: 1,
                  boxShadow: '0 1px 4px rgba(0,0,0,0.15)',
                }}
              >×</button>
            </div>
          ))}
        </div>
      )}

      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'center' }}>
        <input
          ref={fileRef}
          type="file"
          accept="image/*"
          multiple
          onChange={handleUpload}
          disabled={busy}
          style={{ fontSize: 13, fontFamily: 'Source Serif 4, serif' }}
        />
      </div>
      <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
        <input
          type="text"
          value={urlInput}
          onChange={(e) => setUrlInput(e.target.value)}
          placeholder="…or paste an image URL"
          style={{ ...adminInput, flex: 1 }}
        />
        <button onClick={addUrl} disabled={busy || !urlInput.trim()} style={btnGhost}>Add URL</button>
      </div>
      <p style={{ fontSize: 11, color: 'var(--bark-light)', marginTop: 8 }}>
        First photo is used as the primary card image. JPEG/PNG/WebP/GIF, up to 8MB each.
      </p>
      {error && <div style={{ color: '#B91C1C', fontSize: 12, marginTop: 8 }}>{error}</div>}
    </div>
  );
}

// ── Listing editor ──
function ListingEditor({ listing, onSaved, onCancel, onDelete }) {
  const isNew = !listing.id;
  const [draft, setDraft] = React.useState(() => ({
    name: '', category: CATEGORY_OPTIONS[0], city: '', state: '', address: '',
    lat: '', lng: '', shortDesc: '', description: '', hours: '',
    season: [], activities: [], amenities: [], tags: [],
    phone: '', email: '', website: '', facebook: '', instagram: '',
    uPickCrops: '', pricingNotes: '', bookingInfo: '',
    priceRange: '$$', featured: false, images: [],
    ...listing,
  }));
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState(null);

  const set = (key) => (val) => setDraft((d) => ({ ...d, [key]: val }));
  const setCsv = (key) => (val) =>
    setDraft((d) => ({ ...d, [key]: val.split(',').map((s) => s.trim()).filter(Boolean) }));
  const toggleMonth = (m) =>
    setDraft((d) => ({
      ...d,
      season: d.season.includes(m) ? d.season.filter((x) => x !== m) : [...d.season, m],
    }));

  const save = async () => {
    if (!draft.name.trim()) { setError('Name is required.'); return; }
    setSaving(true);
    setError(null);
    try {
      const payload = {
        ...draft,
        lat: draft.lat === '' ? null : Number(draft.lat),
        lng: draft.lng === '' ? null : Number(draft.lng),
      };
      const saved = isNew
        ? await window.API.createListing(payload)
        : await window.API.updateListing(listing.id, payload);
      onSaved(saved, isNew);
    } catch (err) {
      setError(err.message);
    } finally {
      setSaving(false);
    }
  };

  return (
    <div style={{ maxWidth: 820, margin: '0 auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 24 }}>
        <h1 style={{ fontFamily: 'Playfair Display, serif', fontSize: 28, color: 'var(--bark)' }}>
          {isNew ? 'New Listing' : 'Edit Listing'}
        </h1>
        <button onClick={onCancel} style={btnGhost}>← Back to list</button>
      </div>

      {isNew ? (
        <div style={{
          background: 'var(--gold-pale)', border: '1px solid var(--cream-mid)',
          borderRadius: 8, padding: '10px 14px', fontSize: 13,
          color: 'var(--bark-mid)', marginBottom: 20,
        }}>
          Save the listing first, then you can upload photos.
        </div>
      ) : (
        <ImageManager listing={draft} onChange={(updated) => setDraft((d) => ({ ...d, ...updated }))} />
      )}

      <div style={{
        background: '#fff', border: '1px solid var(--cream-mid)',
        borderRadius: 12, padding: 'clamp(1.25rem, 3vw, 2rem)',
      }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
          <div style={{ gridColumn: '1 / -1' }}>
            <AdminField label="Farm Name *"><TextInput value={draft.name} onChange={set('name')} /></AdminField>
          </div>
          <AdminField label="Category *">
            <select value={draft.category} onChange={(e) => set('category')(e.target.value)} style={adminInput}>
              {CATEGORY_OPTIONS.map((c) => <option key={c} value={c}>{c}</option>)}
            </select>
          </AdminField>
          <AdminField label="Price Range">
            <select value={draft.priceRange || '$$'} onChange={(e) => set('priceRange')(e.target.value)} style={adminInput}>
              {PRICE_OPTIONS.map((p) => <option key={p} value={p}>{p}</option>)}
            </select>
          </AdminField>
          <AdminField label="City"><TextInput value={draft.city} onChange={set('city')} /></AdminField>
          <AdminField label="State"><TextInput value={draft.state} onChange={set('state')} placeholder="SD" /></AdminField>
          <div style={{ gridColumn: '1 / -1' }}>
            <AdminField label="Address"><TextInput value={draft.address} onChange={set('address')} /></AdminField>
          </div>
          <AdminField label="Latitude"><TextInput value={draft.lat} onChange={set('lat')} type="number" placeholder="43.54" /></AdminField>
          <AdminField label="Longitude"><TextInput value={draft.lng} onChange={set('lng')} type="number" placeholder="-96.73" /></AdminField>
        </div>

        <AdminField label="Short Description (card blurb)">
          <textarea value={draft.shortDesc || ''} onChange={(e) => set('shortDesc')(e.target.value)} rows={2}
            style={{ ...adminInput, resize: 'vertical', lineHeight: 1.6 }} />
        </AdminField>
        <AdminField label="Full Description">
          <textarea value={draft.description || ''} onChange={(e) => set('description')(e.target.value)} rows={4}
            style={{ ...adminInput, resize: 'vertical', lineHeight: 1.6 }} />
        </AdminField>
        <AdminField label="Hours"><TextInput value={draft.hours} onChange={set('hours')} placeholder="Sat–Sun 9am–6pm" /></AdminField>

        <AdminField label="Season (months)">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {MONTHS.map((m) => {
              const on = draft.season.includes(m);
              return (
                <button key={m} type="button" onClick={() => toggleMonth(m)} style={{
                  padding: '5px 10px', borderRadius: 20, fontSize: 12, cursor: 'pointer',
                  fontFamily: 'DM Mono, monospace',
                  border: `1px solid ${on ? 'var(--orange)' : 'var(--cream-mid)'}`,
                  background: on ? 'var(--orange)' : '#fff',
                  color: on ? '#fff' : 'var(--bark-light)',
                }}>{m.slice(0, 3)}</button>
              );
            })}
          </div>
        </AdminField>

        <AdminField label="Activities (comma-separated)">
          <TextInput value={(draft.activities || []).join(', ')} onChange={setCsv('activities')}
            placeholder="U-Pick Apples, Hayrides, Corn Maze" />
        </AdminField>
        <AdminField label="Amenities (comma-separated)">
          <TextInput value={(draft.amenities || []).join(', ')} onChange={setCsv('amenities')}
            placeholder="Parking, Restrooms, Farm Store" />
        </AdminField>
        <AdminField label="Tags (comma-separated)">
          <TextInput value={(draft.tags || []).join(', ')} onChange={setCsv('tags')}
            placeholder="u-pick, family-friendly" />
        </AdminField>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
          <AdminField label="Phone"><TextInput value={draft.phone} onChange={set('phone')} /></AdminField>
          <AdminField label="Email"><TextInput value={draft.email} onChange={set('email')} /></AdminField>
          <AdminField label="Website"><TextInput value={draft.website} onChange={set('website')} placeholder="example.com" /></AdminField>
          <AdminField label="Facebook URL"><TextInput value={draft.facebook} onChange={set('facebook')} /></AdminField>
          <AdminField label="Instagram URL"><TextInput value={draft.instagram} onChange={set('instagram')} /></AdminField>
          <AdminField label="U-Pick Crops"><TextInput value={draft.uPickCrops} onChange={set('uPickCrops')} /></AdminField>
        </div>
        <AdminField label="Pricing Notes"><TextInput value={draft.pricingNotes} onChange={set('pricingNotes')} /></AdminField>
        <AdminField label="Booking Info"><TextInput value={draft.bookingInfo} onChange={set('bookingInfo')} /></AdminField>

        <label style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 20, cursor: 'pointer' }}>
          <input type="checkbox" checked={!!draft.featured} onChange={(e) => set('featured')(e.target.checked)}
            style={{ width: 18, height: 18, cursor: 'pointer' }} />
          <span style={{ fontSize: 14, color: 'var(--bark)' }}>Feature this listing on the homepage</span>
        </label>

        {error && (
          <div style={{ background: 'var(--orange-pale)', color: '#7A2E00', borderRadius: 8, padding: '10px 12px', fontSize: 13, marginBottom: 16 }}>
            {error}
          </div>
        )}

        <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
          <button onClick={save} disabled={saving} style={{ ...btnPrimary, opacity: saving ? 0.6 : 1 }}>
            {saving ? 'Saving…' : isNew ? 'Create Listing' : 'Save Changes'}
          </button>
          <button onClick={onCancel} style={btnGhost}>Cancel</button>
          {!isNew && (
            <button
              onClick={() => onDelete(listing)}
              style={{ ...btnGhost, marginLeft: 'auto', color: '#B91C1C', borderColor: '#E5B4B4' }}
            >Delete</button>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Dashboard list ──
function Dashboard({ listings, onNew, onEdit, onDelete, onLogout, username }) {
  const [query, setQuery] = React.useState('');
  const filtered = listings.filter((l) =>
    !query || (l.name || '').toLowerCase().includes(query.toLowerCase()) ||
    (l.city || '').toLowerCase().includes(query.toLowerCase()) ||
    (l.category || '').toLowerCase().includes(query.toLowerCase())
  );

  return (
    <div style={{ maxWidth: 1000, margin: '0 auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12, marginBottom: 8 }}>
        <h1 style={{ fontFamily: 'Playfair Display, serif', fontSize: 30, color: 'var(--bark)' }}>
          Listings Admin
        </h1>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ fontSize: 13, color: 'var(--bark-light)', fontFamily: 'DM Mono, monospace' }}>
            {username}
          </span>
          <button onClick={onLogout} style={btnGhost}>Sign out</button>
        </div>
      </div>
      <p style={{ fontSize: 14, color: 'var(--bark-light)', marginBottom: 24 }}>
        {listings.length} listing{listings.length === 1 ? '' : 's'} in the directory.
      </p>

      <div style={{ display: 'flex', gap: 12, marginBottom: 20, flexWrap: 'wrap' }}>
        <input
          type="text" value={query} onChange={(e) => setQuery(e.target.value)}
          placeholder="Search listings…"
          style={{ ...adminInput, flex: 1, minWidth: 200 }}
        />
        <button onClick={onNew} style={btnPrimary}>+ New Listing</button>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {filtered.map((l) => (
          <div key={l.id} style={{
            display: 'flex', alignItems: 'center', gap: 14,
            background: '#fff', border: '1px solid var(--cream-mid)',
            borderRadius: 10, padding: 12,
          }}>
            <div style={{
              width: 64, height: 48, borderRadius: 6, overflow: 'hidden', flexShrink: 0,
              background: 'var(--cream-dark)',
            }}>
              {(l.images && l.images[0]) || l.image ? (
                <img src={(l.images && l.images[0]) || l.image} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
              ) : (
                <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 20 }}>🌾</div>
              )}
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: 'Playfair Display, serif', fontSize: 16, fontWeight: 600, color: 'var(--bark)' }}>
                {l.name} {l.featured && <span style={{ fontSize: 11, color: 'var(--orange)' }}>★ featured</span>}
              </div>
              <div style={{ fontSize: 12, color: 'var(--bark-light)', fontFamily: 'DM Mono, monospace' }}>
                {l.category} · {l.city}{l.city && l.state ? ', ' : ''}{l.state} · {(l.images || []).length} photo{(l.images || []).length === 1 ? '' : 's'}
              </div>
            </div>
            <button onClick={() => onEdit(l)} style={btnGhost}>Edit</button>
            <button onClick={() => onDelete(l)} style={{ ...btnGhost, color: '#B91C1C', borderColor: '#E5B4B4' }}>Delete</button>
          </div>
        ))}
        {filtered.length === 0 && (
          <div style={{ textAlign: 'center', color: 'var(--bark-light)', padding: 40 }}>
            No listings match “{query}”.
          </div>
        )}
      </div>
    </div>
  );
}

// ── Top-level admin page ──
const AdminPage = ({ navigate, onDataChange }) => {
  const [user, setUser] = React.useState(undefined); // undefined = loading
  const [listings, setListings] = React.useState([]);
  const [view, setView] = React.useState('list'); // 'list' | 'edit'
  const [editing, setEditing] = React.useState(null);

  const refresh = React.useCallback(async () => {
    const data = await window.API.listings();
    setListings(data);
    window.LISTINGS_DATA = data;
    if (window.recomputeCategoryCounts) window.recomputeCategoryCounts();
    if (onDataChange) onDataChange();
  }, [onDataChange]);

  React.useEffect(() => {
    (async () => {
      try {
        const me = await window.API.me();
        setUser(me);
        if (me) await refresh();
      } catch (_) {
        setUser(null);
      }
    })();
  }, [refresh]);

  const onLoginSuccess = async (u) => {
    setUser(u);
    await refresh();
  };

  const onLogout = async () => {
    await window.API.logout();
    setUser(null);
    setView('list');
  };

  const onSaved = async (saved, wasNew) => {
    await refresh();
    if (wasNew) {
      setEditing(saved); // stay in editor so photos can be added
      setView('edit');
    } else {
      setView('list');
      setEditing(null);
    }
  };

  const onDelete = async (l) => {
    if (!window.confirm(`Delete “${l.name}”? This can't be undone.`)) return;
    await window.API.deleteListing(l.id);
    await refresh();
    setView('list');
    setEditing(null);
  };

  if (user === undefined) {
    return <div style={{ paddingTop: 160, textAlign: 'center', color: 'var(--bark-light)' }}>Loading…</div>;
  }

  return (
    <div style={{ paddingTop: 100, paddingBottom: 80, minHeight: '100vh', background: 'var(--cream-dark)' }}>
      <div style={{ padding: '0 clamp(1.5rem, 4vw, 3rem)' }}>
        {!user ? (
          <LoginForm onSuccess={onLoginSuccess} />
        ) : view === 'edit' ? (
          <ListingEditor
            // Remount when switching listings (and after a create, when the
            // saved record gains an id) so the form's draft state re-initializes.
            key={(editing && editing.id) || 'new'}
            listing={editing || {}}
            onSaved={onSaved}
            onCancel={() => { setView('list'); setEditing(null); }}
            onDelete={onDelete}
          />
        ) : (
          <Dashboard
            listings={listings}
            username={user.username}
            onNew={() => { setEditing({}); setView('edit'); }}
            onEdit={(l) => { setEditing(l); setView('edit'); }}
            onDelete={onDelete}
            onLogout={onLogout}
          />
        )}
        <div style={{ textAlign: 'center', marginTop: 40 }}>
          <button onClick={() => navigate('home')} style={{ ...btnGhost, fontSize: 13 }}>
            ← Back to site
          </button>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { AdminPage });
