/* submit.jsx — Add a listing.
   Garage sales link to the native form on the map page; events, food trucks
   and farm stands have native forms right here. All three POST /api/submit
   and land in the moderation queue (pending + review email) — nothing goes
   live until approved. */

const SUBMIT_TYPES = [
  { key:'event',     label:'Community Event',  blurb:'A festival, market, concert or community gathering.',  Icon:IconCalendar, tint:'#cf9521' },
  { key:'sale',      label:'Garage Sale',      blurb:'List your driveway sale on the community map.',        Icon:IconTag,      tint:'#9a3b4f' },
  { key:'foodtruck', label:'Food Truck',        blurb:'Put your truck on the map — where you\'ll be this week.', Icon:IconTruck,   tint:'#b3603f' },
  { key:'farmstand', label:'Farm Stand or Market', blurb:'Share your stand or market: what you sell and when you\'re open.', Icon:IconSprout,  tint:'#5c7461' },
];

const EVENT_CATEGORIES = ['Festival', 'Market', 'Community', 'Music', 'Family', 'Outdoors', 'Other'];
const STAND_AVAILABLE  = ['Vegetables', 'Eggs', 'Honey', 'Fruit', 'Flowers', 'Meat', 'Preserves', 'Baked Goods', 'Other'];
const WEEK_DAYS        = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];

/* ── Shared form bits ─────────────────────────────────────────── */

const fieldStyle = {
  width:'100%', padding:'10px 12px', fontSize:14.5, fontFamily:'inherit',
  border:'1.5px solid var(--line)', borderRadius:10, background:'#fffdf6',
  boxSizing:'border-box', color:'var(--ink)',
};

function Field({ label, required, hint, children }) {
  return (
    <div style={{ marginBottom:18 }}>
      <label style={{ display:'block', fontWeight:600, fontSize:13.5, marginBottom:6 }}>
        {label}{required && <span style={{ color:'#9a3b4f' }}> *</span>}
        {hint && <span style={{ fontWeight:400, color:'var(--ink-faint)' }}> — {hint}</span>}
      </label>
      {children}
    </div>
  );
}

function CheckGroup({ options, value, onChange, columns = 2 }) {
  const toggle = opt => onChange(
    value.includes(opt) ? value.filter(v => v !== opt) : [...value, opt]
  );
  return (
    <div style={{ display:'grid', gridTemplateColumns:`repeat(${columns},1fr)`, gap:'6px 12px' }}>
      {options.map(opt => (
        <label key={opt} style={{ display:'flex', alignItems:'center', gap:8, cursor:'pointer', fontSize:14 }}>
          <input type="checkbox" checked={value.includes(opt)} onChange={() => toggle(opt)}
                 style={{ accentColor:'var(--spruce, #41431b)', width:15, height:15 }} />
          {opt}
        </label>
      ))}
    </div>
  );
}

/* Client-side resize to ≤800px WebP (JPEG fallback) before upload */
function sfResizeImage(file, maxPx) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = URL.createObjectURL(file);
    img.onload = () => {
      URL.revokeObjectURL(url);
      const scale = Math.min(1, maxPx / Math.max(img.width, img.height));
      const w = Math.round(img.width * scale), h = Math.round(img.height * scale);
      const canvas = document.createElement('canvas');
      canvas.width = w; canvas.height = h;
      canvas.getContext('2d').drawImage(img, 0, 0, w, h);
      canvas.toBlob(blob => {
        if (blob && blob.type === 'image/webp') return resolve(blob);
        canvas.toBlob(b => b ? resolve(b) : reject(new Error('Resize failed')), 'image/jpeg', 0.82);
      }, 'image/webp', 0.8);
    };
    img.onerror = () => { URL.revokeObjectURL(url); reject(new Error('Could not load image')); };
    img.src = url;
  });
}

function PhotoPicker({ photos, setPhotos }) {
  const inputRef = React.useRef(null);
  const [busy, setBusy] = React.useState(false);

  const onPick = async e => {
    const files = Array.from(e.target.files || []).slice(0, 3 - photos.length);
    e.target.value = '';
    if (!files.length) return;
    setBusy(true);
    const added = [];
    for (const file of files) {
      if (!file.type.startsWith('image/')) continue;
      try {
        const blob = await sfResizeImage(file, 800);
        const dataUrl = await new Promise((res, rej) => {
          const r = new FileReader();
          r.onload  = () => res(r.result);
          r.onerror = () => rej(new Error('read failed'));
          r.readAsDataURL(blob);
        });
        added.push(dataUrl);
      } catch (_) { /* skip unreadable file */ }
    }
    setPhotos([...photos, ...added].slice(0, 3));
    setBusy(false);
  };

  return (
    <div>
      <input ref={inputRef} type="file" accept="image/*" multiple style={{ display:'none' }} onChange={onPick} />
      <div style={{ display:'flex', gap:10, flexWrap:'wrap' }}>
        {photos.map((p, i) => (
          <div key={i} style={{ position:'relative' }}>
            <img src={p} alt={`Photo ${i + 1}`}
                 style={{ width:72, height:72, objectFit:'cover', borderRadius:10, border:'1.5px solid var(--line)' }} />
            <button type="button" onClick={() => setPhotos(photos.filter((_, j) => j !== i))}
                    aria-label="Remove photo"
                    style={{ position:'absolute', top:-7, right:-7, width:20, height:20, borderRadius:'50%',
                             background:'#444', color:'#fff', border:'none', cursor:'pointer', fontSize:12, lineHeight:1 }}>
              ×
            </button>
          </div>
        ))}
        {photos.length < 3 && (
          <button type="button" onClick={() => inputRef.current.click()} disabled={busy}
                  style={{ width:72, height:72, borderRadius:10, border:'1.5px dashed var(--line)',
                           background:'var(--paper-2)', color:'var(--ink-faint)', fontSize:24, cursor:'pointer' }}>
            {busy ? '…' : '+'}
          </button>
        )}
      </div>
    </div>
  );
}

/* "HH:MM" from <input type=time> → "h:mm AM/PM" (sheet convention) */
function to12h(str) {
  if (!str) return '';
  const [h, m] = str.split(':').map(Number);
  const period = h >= 12 ? 'PM' : 'AM';
  const hour   = h === 0 ? 12 : h > 12 ? h - 12 : h;
  return `${hour}:${String(m).padStart(2, '0')} ${period}`;
}

/* ── The three native forms ───────────────────────────────────── */

function ListingForm({ type }) {
  const mountedAt = React.useRef(Date.now());
  const [v, setV]           = React.useState({ days: [], available: [] });
  const [photos, setPhotos] = React.useState([]);
  const [state, setState]   = React.useState('idle'); // idle | sending | done
  const [error, setError]   = React.useState('');

  React.useEffect(() => {
    if (window.ffTrack) window.ffTrack('form_open', type);
  }, [type]);

  const set = (key, val) => setV(prev => ({ ...prev, [key]: val }));
  const text = (key, props = {}) => (
    <input style={fieldStyle} value={v[key] || ''} onChange={e => set(key, e.target.value)} {...props} />
  );

  const submit = async e => {
    e.preventDefault();
    setError('');
    setState('sending');

    const body = {
      type,
      website:   v.website || '',
      elapsedMs: Date.now() - mountedAt.current,
      photos,
      ...v,
    };
    // Convert native time values to the sheet's h:mm AM/PM convention
    for (const k of ['startTime', 'endTime']) if (body[k]) body[k] = to12h(body[k]);
    for (const d of WEEK_DAYS.map(x => x.toLowerCase())) {
      if (body[d + 'Open'])  body[d + 'Open']  = to12h(body[d + 'Open']);
      if (body[d + 'Close']) body[d + 'Close'] = to12h(body[d + 'Close']);
    }

    try {
      const res  = await fetch('/api/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });
      const data = await res.json();
      if (data.error) throw new Error(data.error);
      setState('done');
    } catch (err) {
      setError(err.message);
      setState('idle');
    }
  };

  if (state === 'done') {
    return (
      <div className="card" style={{ padding:'40px 32px', textAlign:'center' }}>
        <div style={{ fontSize:36, marginBottom:10 }}>🎉</div>
        <div style={{ fontFamily:'var(--display)', fontWeight:700, fontSize:20, marginBottom:6 }}>
          Submitted for review!
        </div>
        <p style={{ color:'var(--ink-soft)', fontSize:14.5, margin:0 }}>
          Thanks for contributing. A real person looks at every listing before it goes
          live — yours should appear on the site within a day.
        </p>
      </div>
    );
  }

  const recurring = v.eventType === 'Recurring';

  return (
    <form onSubmit={submit} className="card" style={{ padding:'26px 28px' }}>
      {/* Honeypot — humans never see this */}
      <input type="text" tabIndex={-1} autoComplete="off" aria-hidden="true"
             value={v.website || ''} onChange={e => set('website', e.target.value)}
             style={{ position:'absolute', left:-5000, top:-5000 }} />

      {type === 'event' && <>
        <Field label="Event Title" required>{text('title', { required:true, maxLength:200 })}</Field>
        <Field label="Event Type" required>
          <div style={{ display:'flex', gap:16 }}>
            {['One-time', 'Recurring'].map(t => (
              <label key={t} style={{ display:'flex', alignItems:'center', gap:7, cursor:'pointer', fontSize:14.5 }}>
                <input type="radio" name="eventType" checked={(v.eventType || 'One-time') === t}
                       onChange={() => set('eventType', t)} style={{ accentColor:'#41431b' }} />
                {t}
              </label>
            ))}
          </div>
        </Field>
        {!recurring && (
          <Field label="Date" required>{text('date', { type:'date', required:true })}</Field>
        )}
        {recurring && <>
          <Field label="Repeats" required>
            <select style={fieldStyle} value={v.repeats || ''} onChange={e => set('repeats', e.target.value)} required>
              <option value="">Choose…</option>
              <option>Weekly</option><option>Bi-weekly</option><option>Monthly</option>
            </select>
          </Field>
          <Field label="Day(s) of the week" required>
            <CheckGroup options={WEEK_DAYS} value={v.days} onChange={x => set('days', x)} />
          </Field>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
            <Field label="Start Date" required>{text('startDate', { type:'date', required:true })}</Field>
            <Field label="End Date" hint="blank if ongoing">{text('endDate', { type:'date' })}</Field>
          </div>
        </>}
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
          <Field label="Start Time" required>{text('startTime', { type:'time', required:true })}</Field>
          <Field label="End Time">{text('endTime', { type:'time' })}</Field>
        </div>
        <Field label="Venue / Location" required hint="we'll place it on the map">
          {text('venue', { required:true, maxLength:200, placeholder:'e.g. Lheidli T\'enneh Memorial Park' })}
        </Field>
        <Field label="Category" required>
          <select style={fieldStyle} value={v.category || ''} onChange={e => set('category', e.target.value)} required>
            <option value="">Choose…</option>
            {EVENT_CATEGORIES.map(c => <option key={c}>{c}</option>)}
          </select>
        </Field>
        <Field label="Description">
          <textarea style={{ ...fieldStyle, resize:'vertical' }} rows={3} maxLength={2000}
                    value={v.description || ''} onChange={e => set('description', e.target.value)} />
        </Field>
        <Field label="Website or Ticket Link">{text('link', { maxLength:300, placeholder:'https://…' })}</Field>
      </>}

      {type === 'foodtruck' && <>
        <Field label="Business Name" required>{text('name', { required:true, maxLength:150 })}</Field>
        <Field label="Cuisine Type" required>{text('cuisine', { required:true, maxLength:100, placeholder:'e.g. Tacos, Pizza, Thai' })}</Field>
        <Field label="Current Location / Address" required>{text('address', { required:true, maxLength:200, placeholder:'e.g. Gateway area, Hwy 97' })}</Field>
        <Field label="This Week's Schedule" required hint="list each day and location">
          <textarea style={{ ...fieldStyle, resize:'vertical' }} rows={3} maxLength={600} required
                    placeholder={'Mon: Gateway 11am–2pm\nWed: CNC parking lot 11am–1pm'}
                    value={v.schedule || ''} onChange={e => set('schedule', e.target.value)} />
        </Field>
        <Field label="Instagram or Website">{text('instagram', { maxLength:200 })}</Field>
      </>}

      {type === 'farmstand' && <>
        <Field label="Stand Name" required>{text('name', { required:true, maxLength:150 })}</Field>
        <Field label="Street Address" required hint="full address for mapping">
          {text('address', { required:true, maxLength:200 })}
        </Field>
        <Field label="Hours" hint="leave a day blank if you're closed">
          <div style={{ display:'grid', gridTemplateColumns:'88px 1fr 1fr', gap:'8px 10px', alignItems:'center' }}>
            <span></span>
            <span style={{ fontSize:12, color:'var(--ink-faint)', fontWeight:600 }}>Open</span>
            <span style={{ fontSize:12, color:'var(--ink-faint)', fontWeight:600 }}>Close</span>
            {WEEK_DAYS.map(day => {
              const dl = day.toLowerCase();
              return (
                <React.Fragment key={day}>
                  <span style={{ fontSize:13.5, fontWeight:600 }}>{day}</span>
                  <input type="time" style={fieldStyle} value={v[dl + 'Open'] || ''}  onChange={e => set(dl + 'Open',  e.target.value)} />
                  <input type="time" style={fieldStyle} value={v[dl + 'Close'] || ''} onChange={e => set(dl + 'Close', e.target.value)} />
                </React.Fragment>
              );
            })}
          </div>
        </Field>
        <Field label="What's Available">
          <CheckGroup options={STAND_AVAILABLE} value={v.available} onChange={x => set('available', x)} columns={3} />
        </Field>
        <Field label="Description">
          <textarea style={{ ...fieldStyle, resize:'vertical' }} rows={3} maxLength={2000}
                    value={v.description || ''} onChange={e => set('description', e.target.value)} />
        </Field>
        <Field label="Website">{text('website', { maxLength:300, placeholder:'https://…' })}</Field>
      </>}

      <Field label="Photos" hint="optional, up to 3">
        <PhotoPicker photos={photos} setPhotos={setPhotos} />
      </Field>

      <div style={{ borderTop:'1.5px solid var(--line)', margin:'22px 0 18px', paddingTop:18 }}>
        <div style={{ fontWeight:700, fontSize:14, marginBottom:12 }}>
          Your contact info <span style={{ fontWeight:400, color:'var(--ink-faint)' }}>— never shown publicly</span>
        </div>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
          <Field label="Your Name" required>{text(type === 'event' ? 'name' : 'name2', { required:true, maxLength:100 })}</Field>
          <Field label="Email" required>{text('email', { type:'email', required:true, maxLength:200 })}</Field>
        </div>
        <Field label="Phone" hint="optional">{text('phone', { maxLength:30 })}</Field>
      </div>

      <div style={{ display:'flex', alignItems:'center', gap:14, flexWrap:'wrap' }}>
        <button type="submit" className="btn btn-primary" disabled={state === 'sending'} style={{ fontSize:15, padding:'12px 22px' }}>
          {state === 'sending' ? 'Submitting…' : 'Submit for Review'}
        </button>
        {error && <span style={{ color:'#9a3b4f', fontSize:13.5 }}>Error: {error}</span>}
      </div>
    </form>
  );
}

/* ── Page ─────────────────────────────────────────────────────── */

function Submit() {
  const { go } = useFF();
  const [type, setType] = React.useState('event');
  const meta = SUBMIT_TYPES.find(s => s.key === type);

  const openSaleForm = () => {
    if (window.ffTrack) window.ffTrack('form_open', 'sale');
    window.location.href = '/garagesales.html#add';
  };

  return (
    <div>
      <PageBanner eyebrow="Made by neighbours" title="Add a Listing"
        sub="See something the rest of us should know about? Pop it on the board." />

      <div className="page-wrap" style={{ padding:'36px 28px 0', maxWidth:680, margin:'0 auto' }}>
        <div style={{ fontWeight:600, fontSize:14, marginBottom:14 }}>What are you adding?</div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(2,1fr)', gap:12, marginBottom:32 }}>
          {SUBMIT_TYPES.map(s => {
            const on = type === s.key;
            return (
              <button type="button" key={s.key} onClick={() => setType(s.key)} className="card"
                style={{ padding:'18px', display:'flex', flexDirection:'column', gap:10, cursor:'pointer', textAlign:'left',
                  borderColor: on ? s.tint : 'var(--line)', background: on ? `${s.tint}12` : '#fffdf6',
                  boxShadow: on ? `0 0 0 2px ${s.tint} inset` : undefined, border:'1.5px solid' }}>
                <span style={{ color:s.tint }}><s.Icon size={26}/></span>
                <div>
                  <div style={{ fontFamily:'var(--display)', fontWeight:700, fontSize:17 }}>{s.label}</div>
                  <div style={{ color:'var(--ink-soft)', fontSize:13.5, marginTop:4 }}>{s.blurb}</div>
                </div>
              </button>
            );
          })}
        </div>

        {type === 'sale' ? (
          <div className="card" style={{ padding:'28px 32px', display:'flex', alignItems:'center', justifyContent:'space-between', gap:24, flexWrap:'wrap' }}>
            <div>
              <div style={{ fontFamily:'var(--display)', fontWeight:700, fontSize:20, marginBottom:6 }}>
                Add a Garage Sale
              </div>
              <p style={{ color:'var(--ink-soft)', margin:0, fontSize:15 }}>
                A short form right on the map page — about 2 minutes, no sign-in needed.
              </p>
            </div>
            <button onClick={openSaleForm} className="btn btn-primary" style={{ fontSize:16, padding:'14px 22px' }}>
              <IconArrow size={18}/> Open the form
            </button>
          </div>
        ) : (
          <ListingForm key={type} type={type} />
        )}

        <div style={{ display:'flex', gap:10, marginTop:20, padding:'16px 18px', background:'var(--paper-2)', borderRadius:12, border:'1.5px solid var(--line)' }}>
          <span style={{ color:'var(--spruce-soft)', flexShrink:0 }}><IconHeart size={20}/></span>
          <p style={{ margin:0, fontSize:13.5, color:'var(--ink-soft)' }}>
            Listings are reviewed before they go live. Thanks for helping keep FraserFinds trustworthy and useful.
          </p>
        </div>
        <div style={{ height:60 }}/>
      </div>
    </div>
  );
}

window.Pages = window.Pages || {};
window.Pages.Submit = Submit;
