/* global React */
const { useState: useStateP, useEffect: useEffectP, useMemo: useMemoP, useRef: useRefP } = React;

// ---------- DetailPanel ----------
function DetailPanel({ person, family, onClose, onEdit, onDelete, onSelect, onAddRelative }) {
  const { Icon, Avatar } = window;
  const byId = useMemoP(() => new Map(family.people.map(p => [p.id, p])), [family]);

  // Compute relations
  const parents = (person.parents || []).map(id => byId.get(id)).filter(Boolean);
  const spouses = (person.spouses || []).map(id => byId.get(id)).filter(Boolean);
  const children = family.people.filter(p => (p.parents || []).includes(person.id));

  // Siblings: people sharing at least one parent (excluding self)
  const siblings = family.people.filter(p => {
    if (p.id === person.id) return false;
    return (p.parents || []).some(pid => (person.parents || []).includes(pid));
  });

  const [menuOpen, setMenuOpen] = useStateP(false);

  const dates = (() => {
    const b = person.birthDate;
    const d = person.deathDate;
    if (b && d) return `${b} – ${d}`;
    if (b) return `b. ${b}`;
    if (d) return `d. ${d}`;
    return '';
  })();

  return (
    <>
      <div className="panel-backdrop" onClick={onClose}/>
      <div className="panel">
        <div className="panel-header">
          <h3 className="panel-title">Profile</h3>
          <button className="btn btn-ghost btn-icon" title="More" onClick={() => setMenuOpen(v => !v)} data-menu-anchor>
            <Icon name="more"/>
          </button>
          <button className="btn btn-ghost btn-icon" title="Close" onClick={onClose}>
            <Icon name="close"/>
          </button>
        </div>
        {menuOpen && (
          <Menu anchor={{ x: 'auto', y: 56 }} onClose={() => setMenuOpen(false)}>
            <button className="menu-item" onClick={() => { setMenuOpen(false); onEdit(); }}>
              <Icon name="edit"/> Edit profile
            </button>
            <div className="menu-sep"/>
            <button className="menu-item" onClick={() => { setMenuOpen(false); onAddRelative('parent'); }}>
              <Icon name="plus"/> Add parent
            </button>
            <button className="menu-item" onClick={() => { setMenuOpen(false); onAddRelative('spouse'); }}>
              <Icon name="plus"/> Add partner
            </button>
            <button className="menu-item" onClick={() => { setMenuOpen(false); onAddRelative('child'); }}>
              <Icon name="plus"/> Add child
            </button>
            <button className="menu-item" onClick={() => { setMenuOpen(false); onAddRelative('sibling'); }}>
              <Icon name="plus"/> Add sibling
            </button>
            <div className="menu-sep"/>
            <button className="menu-item danger" onClick={() => { setMenuOpen(false); onDelete(); }}>
              <Icon name="trash"/> Delete person
            </button>
          </Menu>
        )}

        <div className="panel-body">
          <div className="detail-hero">
            <Avatar person={person} />
            <h2>{person.name || 'Unnamed'}</h2>
            {person.nickname && <p className="nick">“{person.nickname}”</p>}
            {dates && <p className="dates">{dates}</p>}
          </div>

          {person.location && (
            <div className="detail-row">
              <span className="detail-label">Location</span>
              <span className="detail-value">{person.location}</span>
            </div>
          )}

          {person.notes && (
            <>
              <div className="section-head">Notes</div>
              <div className="notes">{person.notes}</div>
            </>
          )}

          {(parents.length > 0 || spouses.length > 0 || children.length > 0 || siblings.length > 0) && (
            <div className="section-head" style={{ marginTop: 28 }}>Relations</div>
          )}

          {parents.length > 0 && (
            <RelGroup label="Parents" people={parents} onSelect={onSelect}/>
          )}
          {spouses.length > 0 && (
            <RelGroup label={spouses.length > 1 ? "Partners" : "Partner"} people={spouses} onSelect={onSelect}/>
          )}
          {siblings.length > 0 && (
            <RelGroup label="Siblings" people={siblings} onSelect={onSelect}/>
          )}
          {children.length > 0 && (
            <RelGroup label="Children" people={children} onSelect={onSelect}/>
          )}
        </div>

        <div className="panel-footer">
          <button className="btn btn-ghost" onClick={() => onAddRelative('child')}>
            <Icon name="plus" size={14}/> Relative
          </button>
          <button className="btn btn-primary" onClick={onEdit}>
            <Icon name="edit" size={14}/> Edit
          </button>
        </div>
      </div>
    </>
  );
}

function RelGroup({ label, people, onSelect }) {
  const { Avatar } = window;
  return (
    <div className="detail-row">
      <span className="detail-label">{label}</span>
      <div className="detail-value">
        <div className="relations-list">
          {people.map(p => (
            <button key={p.id} className="relation-chip" onClick={() => onSelect(p)}>
              <Avatar person={p}/>
              <span>{p.name}{p.nickname ? ` “${p.nickname}”` : ''}</span>
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

// ---------- EditPanel ----------
function EditPanel({ person, family, isNew, suggestedRelation, onSave, onCancel }) {
  const { Icon, Avatar } = window;
  const { resizeImageFile, newId } = window.FamilyData;

  const [form, setForm] = useStateP(() => ({
    id: person.id || newId(),
    name: person.name || '',
    nickname: person.nickname || '',
    photo: person.photo || null,
    birthDate: person.birthDate || '',
    deathDate: person.deathDate || '',
    location: person.location || '',
    notes: person.notes || '',
    parents: person.parents || [],
    spouses: person.spouses || [],
    color: person.color || null,
  }));
  const [activeTab, setActiveTab] = useStateP(suggestedRelation || 'parent');
  const [imgErr, setImgErr] = useStateP('');
  const fileRef = useRefP();

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

  const handleFile = async (file) => {
    if (!file) return;
    if (!file.type.startsWith('image/')) { setImgErr('Please choose an image file.'); return; }
    try {
      const dataUrl = await resizeImageFile(file, 480, 0.82);
      // Rough size check (1.4x base64 expansion)
      if (dataUrl.length > 600 * 1024) {
        // Try smaller
        const smaller = await resizeImageFile(file, 320, 0.75);
        set('photo', smaller);
      } else {
        set('photo', dataUrl);
      }
      setImgErr('');
    } catch (e) {
      setImgErr('Could not read that image.');
    }
  };

  // Relations are editable for both new and existing people.
  const showRelations = true;

  const peopleSorted = useMemoP(() =>
    family.people
      .filter(p => p.id !== form.id)
      .slice()
      .sort((a, b) => (a.name || '').localeCompare(b.name || '')),
    [family, form.id]);

  const toggleParent = (pid) => {
    const has = form.parents.includes(pid);
    set('parents', has ? form.parents.filter(x => x !== pid) : [...form.parents, pid].slice(0, 2));
  };
  const toggleSpouse = (pid) => {
    const has = form.spouses.includes(pid);
    set('spouses', has ? form.spouses.filter(x => x !== pid) : [...form.spouses, pid]);
  };

  const submit = (e) => {
    e && e.preventDefault();
    if (!form.name.trim()) return;
    onSave(form);
  };

  return (
    <>
      <div className="panel-backdrop" onClick={onCancel}/>
      <form className="panel" onSubmit={submit}>
        <div className="panel-header">
          <h3 className="panel-title">{isNew ? 'Add person' : 'Edit person'}</h3>
          <button type="button" className="btn btn-ghost btn-icon" title="Close" onClick={onCancel}>
            <Icon name="close"/>
          </button>
        </div>

        <div className="panel-body">
          {/* Photo */}
          <div className="photo-edit">
            <Avatar person={form}/>
            <div className="photo-edit-buttons">
              <button type="button" className="btn" onClick={() => fileRef.current && fileRef.current.click()}>
                <Icon name="camera" size={14}/> {form.photo ? 'Change photo' : 'Upload photo'}
              </button>
              {form.photo && (
                <button type="button" className="btn btn-ghost" onClick={() => set('photo', null)}>
                  Remove photo
                </button>
              )}
              <input
                ref={fileRef}
                type="file"
                accept="image/*"
                style={{ display: 'none' }}
                onChange={(e) => handleFile(e.target.files[0])}
              />
              {imgErr && <span style={{ fontSize: 12, color: 'var(--danger)' }}>{imgErr}</span>}
            </div>
          </div>

          <div className="form-grid">
            <div className="form-row">
              <label>Full name</label>
              <input className="field-input" autoFocus value={form.name}
                onChange={e => set('name', e.target.value)} placeholder="e.g. Eleanor Whitfield"/>
            </div>
            <div className="form-row">
              <label>Nickname</label>
              <input className="field-input" value={form.nickname}
                onChange={e => set('nickname', e.target.value)} placeholder="e.g. Ellie"/>
            </div>
            <div className="two-col">
              <div className="form-row">
                <label>Born</label>
                <input className="field-input" value={form.birthDate}
                  onChange={e => set('birthDate', e.target.value)} placeholder="YYYY or YYYY-MM-DD"/>
              </div>
              <div className="form-row">
                <label>Died</label>
                <input className="field-input" value={form.deathDate}
                  onChange={e => set('deathDate', e.target.value)} placeholder="(if applicable)"/>
              </div>
            </div>
            <div className="form-row">
              <label>Location</label>
              <input className="field-input" value={form.location}
                onChange={e => set('location', e.target.value)} placeholder="City, region"/>
            </div>
            <div className="form-row">
              <label>Notes</label>
              <textarea className="field-input" value={form.notes}
                onChange={e => set('notes', e.target.value)}
                placeholder="A few sentences — stories, memories, anything you'd like to remember."/>
            </div>
          </div>

          {showRelations && (
            <>
              <div className="section-head" style={{ marginTop: 24 }}>Relations</div>
              <div className="relation-picker">
                <div className="relation-tabs">
                  <button type="button" className={`relation-tab ${activeTab === 'parent' ? 'active' : ''}`}
                    onClick={() => setActiveTab('parent')}>Parents</button>
                  <button type="button" className={`relation-tab ${activeTab === 'spouse' ? 'active' : ''}`}
                    onClick={() => setActiveTab('spouse')}>Partner</button>
                </div>
                <div className="relation-content">
                  {activeTab === 'parent' && (
                    <>
                      <p style={{ fontSize: 13, color: 'var(--ink-soft)', margin: '0 0 6px' }}>
                        Pick up to two parents already in the tree.
                      </p>
                      <PersonPickList
                        people={peopleSorted}
                        selected={form.parents}
                        onToggle={toggleParent}/>
                    </>
                  )}
                  {activeTab === 'spouse' && (
                    <>
                      <p style={{ fontSize: 13, color: 'var(--ink-soft)', margin: '0 0 6px' }}>
                        Pick a partner already in the tree (optional).
                      </p>
                      <PersonPickList
                        people={peopleSorted}
                        selected={form.spouses}
                        onToggle={toggleSpouse}/>
                    </>
                  )}
                </div>
              </div>
            </>
          )}
        </div>

        <div className="panel-footer">
          <button type="button" className="btn btn-ghost" onClick={onCancel}>Cancel</button>
          <button type="submit" className="btn btn-primary" disabled={!form.name.trim()}>
            <Icon name="check" size={14}/> {isNew ? 'Add to tree' : 'Save'}
          </button>
        </div>
      </form>
    </>
  );
}

function PersonPickList({ people, selected, onToggle }) {
  const { Avatar } = window;
  const [q, setQ] = useStateP('');
  const filtered = q
    ? people.filter(p =>
        (p.name || '').toLowerCase().includes(q.toLowerCase()) ||
        (p.nickname || '').toLowerCase().includes(q.toLowerCase()))
    : people;
  return (
    <>
      <input className="field-input" placeholder="Search people…" value={q}
        onChange={e => setQ(e.target.value)} style={{ padding: '8px 12px', fontSize: 13 }}/>
      <div className="person-pick-list">
        {filtered.length === 0 && (
          <div style={{ padding: 16, fontSize: 13, color: 'var(--ink-mute)', textAlign: 'center' }}>
            No matches.
          </div>
        )}
        {filtered.map(p => (
          <button
            type="button"
            key={p.id}
            className={`person-pick-row ${selected.includes(p.id) ? 'selected' : ''}`}
            onClick={() => onToggle(p.id)}>
            <Avatar person={p}/>
            <span style={{ flex: 1 }}>{p.name}{p.nickname ? ` “${p.nickname}”` : ''}</span>
            {selected.includes(p.id) && <Icon name="check" size={14}/>}
          </button>
        ))}
      </div>
    </>
  );
}

// ---------- Settings panel ----------
function SettingsPanel({ onClose, onReset, onLogout }) {
  const { Icon } = window;
  const [step, setStep] = useStateP('main');
  const [oldPw, setOldPw] = useStateP('');
  const [newPw, setNewPw] = useStateP('');
  const [confirm, setConfirm] = useStateP('');
  const [err, setErr] = useStateP('');
  const [busy, setBusy] = useStateP(false);
  const [pwSaved, setPwSaved] = useStateP(false);

  const submitPw = async (e) => {
    e.preventDefault();
    setErr('');
    if (newPw.length < 4) { setErr('New password must be at least 4 characters.'); return; }
    if (newPw !== confirm) { setErr('Passwords don\'t match.'); return; }
    setBusy(true);
    try {
      const r = await fetch('/api/password', {
        method: 'POST',
        credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ oldPassword: oldPw, newPassword: newPw }),
      });
      const body = await r.json().catch(() => ({}));
      if (!r.ok) { setErr(body.error || 'Could not update password.'); setBusy(false); return; }
      setBusy(false);
      setPwSaved(true);
      setOldPw(''); setNewPw(''); setConfirm('');
      setTimeout(() => { setPwSaved(false); setStep('main'); }, 1200);
    } catch (e) {
      setErr('Network error.'); setBusy(false);
    }
  };

  return (
    <>
      <div className="panel-backdrop" onClick={onClose}/>
      <div className="panel">
        <div className="panel-header">
          <h3 className="panel-title">Settings</h3>
          <button className="btn btn-ghost btn-icon" onClick={onClose}><Icon name="close"/></button>
        </div>
        <div className="panel-body">
          {step === 'main' && (
            <>
              <div className="section-head">Account</div>
              <button className="menu-item" style={{ width: '100%', marginBottom: 4 }} onClick={() => setStep('changepw')}>
                <Icon name="settings"/> Change password
              </button>
              <button className="menu-item" style={{ width: '100%' }} onClick={onLogout}>
                <Icon name="logout"/> Lock the tree
              </button>

              <div className="section-head" style={{ marginTop: 28 }}>Tree</div>
              <p style={{ fontSize: 13.5, color: 'var(--ink-soft)', lineHeight: 1.5, margin: '0 0 12px' }}>
                The tree lives on Cloudflare. Everyone with the password sees the same names,
                photos, and notes — so be kind, and don't tell cousin Greg about his page until
                you're ready.
              </p>
              <button className="menu-item danger" style={{ width: '100%' }} onClick={() => setStep('confirm-reset')}>
                <Icon name="trash"/> Reset everything…
              </button>
            </>
          )}

          {step === 'changepw' && pwSaved && (
            <div style={{ padding: '24px 0', textAlign: 'center' }}>
              <Icon name="check" size={32}/>
              <div style={{ marginTop: 10, fontFamily: 'var(--font-serif)', fontSize: 18 }}>Password updated.</div>
            </div>
          )}

          {step === 'changepw' && !pwSaved && (
            <form onSubmit={submitPw} className="form-grid">
              <div className="form-row">
                <label>Current password</label>
                <input type="password" className="field-input" value={oldPw} onChange={e => setOldPw(e.target.value)} autoFocus/>
              </div>
              <div className="form-row">
                <label>New password</label>
                <input type="password" className="field-input" value={newPw} onChange={e => setNewPw(e.target.value)}/>
              </div>
              <div className="form-row">
                <label>Confirm new password</label>
                <input type="password" className="field-input" value={confirm} onChange={e => setConfirm(e.target.value)}/>
              </div>
              {err && <div style={{ color: 'var(--danger)', fontSize: 13 }}>{err}</div>}
              <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 8 }}>
                <button type="button" className="btn btn-ghost" onClick={() => setStep('main')}>Back</button>
                <button type="submit" className="btn btn-primary" disabled={busy}>Update password</button>
              </div>
            </form>
          )}

          {step === 'confirm-reset' && (
            <>
              <p style={{ fontSize: 14.5, lineHeight: 1.55 }}>
                This wipes the whole tree from Cloudflare — every person, photo, note, and the family
                password — for everyone. There's no undo.
              </p>
              <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', marginTop: 18 }}>
                <button className="btn btn-ghost" onClick={() => setStep('main')}>Cancel</button>
                <button className="btn" style={{ background: 'var(--danger)', color: '#fff', borderColor: 'var(--danger)' }}
                  onClick={onReset}>Yes, reset everything</button>
              </div>
            </>
          )}
        </div>
      </div>
    </>
  );
}

Object.assign(window, { DetailPanel, EditPanel, SettingsPanel, PersonPickList });
