// Kundregistret — CRM-vyn, byggd efter prototypen vi tog fram tillsammans:
// rubrik med "Kundregister", flikarna Kunder / Att följa upp, kundlista till
// vänster, kundkort till höger med nyckeltal, bevakningsruta, offerthistorik,
// kontaktpersoner och en tidslinje där offerter och anteckningar blandas.
//
// All data kommer färdigräknad från servern (/api/customers, /api/customers/:id,
// /api/bevakningar) — listan behöver aldrig läsa in hela offerter för att visa
// ett belopp.

// Samma varmgula som prototypen använder för "väntar på svar".
const AMBER = '#b07514';

function kr(n) {
  return Math.round(Number(n) || 0).toLocaleString('sv-SE').replace(/,/g, ' ') + ' kr';
}
function idag() {
  const d = new Date(), p = n => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
}
function dagarTill(datum) {
  if (!datum) return null;
  return Math.round((new Date(datum + 'T12:00:00') - new Date(idag() + 'T12:00:00')) / 86400000);
}
function dagarSedan(datum) {
  const d = dagarTill(datum);
  return d == null ? null : -d;
}
const STATUS_FARG = {
  'Godkänd': { color: '#2b7d70', background: '#eef7f4', borderColor: '#9fcfc1' },
  'Skickad': { color: AMBER, background: '#fff7ed', borderColor: '#f0b866' },
  'Utkast': { color: 'var(--fg-muted)', background: 'var(--ulab-cool-grey)', borderColor: 'var(--border-strong)' },
  'Avslagen': { color: '#8a3b30', background: '#fdf0ee', borderColor: '#eab5ac' },
};
const STATUSAR = ['Utkast', 'Skickad', 'Godkänd', 'Avslagen'];

// Samma belopp visas likadant överallt: löpande avtal per månad, engångsköp netto.
function belopp(o) {
  return (o.total_monthly > 0 && (o.pricing_mode || 'kontant') !== 'kontant')
    ? kr(o.total_monthly) + '/mån'
    : kr(o.total_net);
}

function CustomerRegister({ user, onOpenOffer, onNewOfferForCustomer, valdKundId, onValjKund, onOpenSearch, onDeleteOffer }) {
  const [flik, setFlik] = React.useState('kunder');
  const [kunder, setKunder] = React.useState([]);
  const [visaArkiverade, setVisaArkiverade] = React.useState(false);
  const [sok, setSok] = React.useState('');
  const [kort, setKort] = React.useState(null);
  const [bevakningar, setBevakningar] = React.useState([]);
  const [visaAllasBevakningar, setVisaAllasBevakningar] = React.useState(false);
  const [fel, setFel] = React.useState('');
  const [laddarKort, setLaddarKort] = React.useState(false);
  const [ny, setNy] = React.useState('');
  const [nyKontakt, setNyKontakt] = React.useState(null); // null = formuläret stängt

  const laddaKunder = React.useCallback(() => {
    api(`/api/customers${visaArkiverade ? '?arkiverade=1' : ''}`)
      .then(setKunder)
      .catch(e => setFel(e.message || 'Kunde inte hämta kundregistret.'));
  }, [visaArkiverade]);

  const laddaBevakningar = React.useCallback(() => {
    api(`/api/bevakningar${visaAllasBevakningar ? '?all=1' : ''}`)
      .then(setBevakningar)
      .catch(e => setFel(e.message || 'Kunde inte hämta bevakningarna.'));
  }, [visaAllasBevakningar]);

  React.useEffect(() => { laddaKunder(); }, [laddaKunder]);
  React.useEffect(() => { laddaBevakningar(); }, [laddaBevakningar]);

  const laddaKort = React.useCallback((id) => {
    if (!id) { setKort(null); return; }
    setLaddarKort(true);
    api(`/api/customers/${id}`)
      .then(setKort)
      .catch(e => setFel(e.message || 'Kunde inte hämta kunden.'))
      .finally(() => setLaddarKort(false));
  }, []);

  React.useEffect(() => { laddaKort(valdKundId); setNyKontakt(null); }, [valdKundId, laddaKort]);
  React.useEffect(() => {
    if (!valdKundId && kunder.length) onValjKund(kunder[0].id);
  }, [kunder, valdKundId, onValjKund]);

  const listan = kunder.filter(k => {
    const q = sok.trim().toLowerCase();
    if (!q) return true;
    return (k.name + ' ' + (k.org_nr || '') + ' ' + (k.customer_no || '')).toLowerCase().includes(q);
  });

  const sparaAnteckning = async () => {
    const text = ny.trim();
    if (!text || !kort) return;
    try {
      await api(`/api/customers/${kort.id}/anteckningar`, { method: 'POST', body: JSON.stringify({ body: text }) });
      setNy('');
      laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte spara anteckningen.'); }
  };
  const taBortAnteckning = async (noteId) => {
    try {
      await api(`/api/customers/${kort.id}/anteckningar/${noteId}`, { method: 'DELETE' });
      laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte ta bort anteckningen.'); }
  };
  const sparaKontakt = async () => {
    if (!nyKontakt || !nyKontakt.name.trim()) return;
    try {
      await api(`/api/customers/${kort.id}/kontakter`, { method: 'POST', body: JSON.stringify(nyKontakt) });
      setNyKontakt(null);
      laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte spara kontaktpersonen.'); }
  };
  const taBortKontakt = async (id) => {
    try {
      await api(`/api/customers/${kort.id}/kontakter/${id}`, { method: 'DELETE' });
      laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte ta bort kontaktpersonen.'); }
  };
  // Redigera kundens uppgifter. Alla får rätta dem — ändringen syns på alla
  // kommande offerter till kunden, men rör inte redan skickade offerter, som
  // behåller de uppgifter de hade när de gick iväg.
  const [redigerar, setRedigerar] = React.useState(false);
  const [sparar, setSparar] = React.useState(false);
  React.useEffect(() => { setRedigerar(false); }, [kort && kort.id]);

  const sparaKund = async (falt) => {
    if (sparar) return;
    setSparar(true);
    try {
      await api(`/api/customers/${kort.id}`, { method: 'PUT', body: JSON.stringify(falt) });
      setFel('');
      setRedigerar(false);
      laddaKunder(); laddaKort(kort.id);
    } catch (e) {
      setFel(e.message || 'Kunde inte spara kunden.');
    } finally { setSparar(false); }
  };

  const arkivera = async () => {
    if (!kort) return;
    try {
      await api(`/api/customers/${kort.id}/arkivera`, {
        method: 'POST', body: JSON.stringify({ arkivera: !kort.archived_at }),
      });
      if (!kort.archived_at) setVisaArkiverade(true);
      laddaKunder(); laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte ändra kunden.'); }
  };
  // Ta bort en offert direkt från kundkortet. Raderingen är mjuk — offerten
  // hamnar i papperskorgen och går att ta tillbaka. Servern släpper bara
  // igenom den som är ansvarig säljare för offerten, eller en admin.
  const [raderar, setRaderar] = React.useState(null);
  const taBortOffert = async (offert) => {
    if (raderar) return;
    const ok = window.confirm(
      `Ta bort offert ${offert.number}${offert.subject ? ' — ' + offert.subject : ''}?\n\n` +
      'Den hamnar i papperskorgen och går att ta tillbaka därifrån.');
    if (!ok) return;
    setRaderar(offert.id);
    try {
      // Raderingen görs av App:s egen deleteOffer — då får vi samma
      // ångra-knapp i toasten som när man tar bort från offertlistan, och
      // det finns bara ett ställe i koden som raderar offerter.
      const gick = await onDeleteOffer(offert.id);
      if (gick) {
        setFel('');
        laddaKunder(); laddaBevakningar();
        if (kort) laddaKort(kort.id);
      }
    } finally { setRaderar(null); }
  };

  const bytStatus = async (offertId, status) => {
    try {
      await api(`/api/offers/${offertId}`, { method: 'PUT', body: JSON.stringify({ status }) });
      laddaKunder(); laddaBevakningar();
      if (kort) laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte ändra status.'); }
  };
  const bytBevakning = async (offertId, datum) => {
    try {
      await api(`/api/offers/${offertId}`, { method: 'PUT', body: JSON.stringify({ followUpAt: datum || null }) });
      laddaBevakningar();
      if (kort) laddaKort(kort.id);
    } catch (e) { setFel(e.message || 'Kunde inte ändra bevakningsdatum.'); }
  };

  // Exportera kundens offerthistorik som CSV (öppnas direkt i Excel).
  const exportera = () => {
    if (!kort) return;
    const rader = [['Nummer', 'Ämne', 'Datum', 'Status', 'Giltig till', 'Bevakas', 'Säljare', 'Belopp', 'Per månad']];
    for (const o of kort.offerter) {
      rader.push([o.number, o.subject || '', o.date || '', o.status, o.valid_until || '',
        o.follow_up_at || '', o.owner_name || '', Math.round(o.total_net || 0), Math.round(o.total_monthly || 0)]);
    }
    const csv = '﻿' + rader.map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(';')).join('\r\n');
    const url = URL.createObjectURL(new Blob([csv], { type: 'text/csv;charset=utf-8' }));
    const a = document.createElement('a');
    a.href = url;
    // Filnamnet hålls till vanliga tecken — åäö och mellanslag ställer till det
    // både i Utforskaren och när filen mejlas vidare.
    const filnamn = kort.name
      .replace(/[åäÅÄ]/g, 'a').replace(/[öÖ]/g, 'o').replace(/[éÉ]/g, 'e')
      .replace(/[^A-Za-z0-9-]+/g, '_').replace(/^_+|_+$/g, '');
    a.download = `offerthistorik-${filnamn || 'kund'}.csv`;
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 2000);
  };

  const forsenade = bevakningar.filter(b => { const d = dagarTill(b.follow_up_at); return d != null && d < 0; }).length;

  const vantarPaKortet = kort ? kort.offerter.filter(o => o.status === 'Skickad')
    .sort((a, b) => String(a.follow_up_at || a.valid_until || '').localeCompare(String(b.follow_up_at || b.valid_until || ''))) : [];
  const offereratTotalt = kort ? kort.offerter.filter(o => o.status !== 'Utkast').reduce((s, o) => s + (o.total_net || 0), 0) : 0;
  const senasteOffert = kort ? kort.offerter.reduce((m, o) => (o.date && o.date > m ? o.date : m), '') : '';
  const kundSedan = kort && kort.offerter.length ? kort.offerter[kort.offerter.length - 1].date.slice(0, 4) : '';

  const tidslinje = kort ? [
    ...kort.offerter.map(o => ({ d: o.date || '', typ: 'offert', o })),
    ...kort.anteckningar.map(a => ({ d: (a.created_at || '').slice(0, 10), typ: 'anteckning', a })),
  ].sort((x, y) => (x.d < y.d ? 1 : x.d > y.d ? -1 : 0)) : [];

  return (
    <div style={{ maxWidth: 1240, margin: '0 auto', padding: '24px 16px 56px', fontFamily: 'var(--font-sans)', color: 'var(--ulab-navy)' }}>
      {fel && (
        <div style={{ marginBottom: 16, padding: '10px 14px', background: '#fdf0ee', border: '1px solid #eab5ac', borderRadius: 5, fontSize: 13, display: 'flex', gap: 12, alignItems: 'center' }}>
          <span style={{ flex: 1 }}>{fel}</span>
          <button onClick={() => { setFel(''); laddaKunder(); laddaBevakningar(); if (valdKundId) laddaKort(valdKundId); }} style={knapp()}>Försök igen</button>
        </div>
      )}

      <header style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap', marginBottom: 8 }}>
        <div>
          <div style={eyebrow}>Offertverktyget</div>
          <h1 style={{ fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 30, margin: '4px 0 0', lineHeight: 1.15 }}>Kundregister</h1>
        </div>
        <div style={{ fontSize: 12, color: 'var(--fg-muted)', display: 'flex', alignItems: 'center', gap: 10 }}>
          <span>Inloggad som <b style={{ color: 'var(--ulab-navy)' }}>{user.name}</b>
            {user.role === 'admin' && <span style={{ marginLeft: 6, fontSize: 10, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: '#fff', background: 'var(--ulab-navy)', borderRadius: 999, padding: '1px 7px', verticalAlign: 'middle' }}>admin</span>}
          </span>
          <button onClick={onOpenSearch} style={{ ...knapp(), padding: '5px 10px', color: 'var(--fg-muted)', fontWeight: 500 }}>
            Sök allt <span style={tangent}>Ctrl</span> <span style={tangent}>K</span>
          </button>
        </div>
      </header>

      <nav role="tablist" style={{ display: 'flex', gap: 2, borderBottom: '1px solid var(--border-strong)', margin: '16px 0 20px', flexWrap: 'wrap' }}>
        <button role="tab" aria-selected={flik === 'kunder'} onClick={() => setFlik('kunder')} style={navflik(flik === 'kunder')}>
          Kunder <span style={{ opacity: .7, fontWeight: 500 }}>({kunder.length})</span>
        </button>
        <button role="tab" aria-selected={flik === 'bevakning'} onClick={() => setFlik('bevakning')} style={navflik(flik === 'bevakning')}>
          Att följa upp
          {bevakningar.length > 0 && (
            <span style={{
              display: 'inline-block', minWidth: 18, padding: '0 6px', marginLeft: 6, borderRadius: 999,
              background: forsenade ? 'var(--ulab-coral)' : AMBER, color: '#fff',
              fontSize: 10.5, fontWeight: 700, lineHeight: '18px', textAlign: 'center',
            }}>{bevakningar.length}</span>
          )}
        </button>
      </nav>

      {flik === 'kunder' ? (
        <div style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: 20, alignItems: 'start' }}>
          <aside style={panel}>
            <div style={{ padding: 14, borderBottom: '1px solid var(--border)' }}>
              <label htmlFor="kundsok" style={{ ...eyebrow, display: 'block', marginBottom: 6 }}>Sök kund</label>
              <input id="kundsok" type="search" value={sok} onChange={e => setSok(e.target.value)}
                placeholder="Namn, org.nr eller kundnr…" autoComplete="off" style={{
                  width: '100%', boxSizing: 'border-box', fontFamily: 'var(--font-sans)', fontSize: 13,
                  padding: '9px 11px', border: '1px solid var(--border-strong)', borderRadius: 4, color: 'var(--ulab-navy)',
                }} />
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8, fontSize: 11, color: 'var(--fg-subtle)', marginTop: 8 }}>
                <span>{listan.length} {listan.length === 1 ? 'kund' : 'kunder'}</span>
                <label style={{ display: 'flex', alignItems: 'center', gap: 5, cursor: 'pointer' }}>
                  <input type="checkbox" checked={visaArkiverade} onChange={e => setVisaArkiverade(e.target.checked)} /> Visa arkiverade
                </label>
              </div>
            </div>
            <div style={{ maxHeight: 560, overflow: 'auto' }}>
              {!listan.length && <div style={{ padding: '28px 14px', color: 'var(--fg-subtle)', fontSize: 13 }}>Ingen kund matchar sökningen.</div>}
              {listan.map(k => {
                const vald = k.id === valdKundId;
                return (
                  <button key={k.id} onClick={() => onValjKund(k.id)} aria-current={vald}
                    style={{
                      display: 'block', width: '100%', textAlign: 'left', cursor: 'pointer', border: 'none',
                      borderBottom: '1px solid var(--border)', padding: '11px 14px', fontFamily: 'var(--font-sans)',
                      background: vald ? 'var(--ulab-cream)' : 'transparent',
                      boxShadow: vald ? 'inset 3px 0 0 var(--ulab-coral)' : 'none',
                    }}>
                    <div style={{ fontSize: 13, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6 }}>
                      {k.name}{k.archived_at && <span style={arkivTagg}>Arkiverad</span>}
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--fg-subtle)', marginTop: 2, display: 'flex', justifyContent: 'space-between', gap: 8 }}>
                      <span>{k.antal_offerter} {k.antal_offerter === 1 ? 'offert' : 'offerter'}</span>
                      <span style={{ fontVariantNumeric: 'tabular-nums' }}>
                        {k.antal_forsenade
                          ? <b style={{ color: 'var(--ulab-coral)' }}>{k.antal_forsenade} försenad{k.antal_forsenade > 1 ? 'e' : ''}</b>
                          : k.antal_vantar
                            ? <b style={{ color: AMBER }}>{k.antal_vantar} väntar</b>
                            : (k.senaste_offert ? 'senast ' + k.senaste_offert : '—')}
                      </span>
                    </div>
                  </button>
                );
              })}
            </div>
          </aside>

          <section style={panel}>
            {!kort && <div style={{ padding: '28px 24px', color: 'var(--fg-subtle)', fontSize: 13 }}>{laddarKort ? 'Hämtar…' : 'Välj en kund i listan.'}</div>}
            {kort && (
              <React.Fragment>
                {redigerar ? (
                  <KundFormular kund={kort} onSpara={sparaKund} onAvbryt={() => setRedigerar(false)} sparar={sparar} />
                ) : (
                <div style={{ padding: '22px 24px 18px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>
                  <div>
                    <div style={eyebrow}>Kund</div>
                    <h2 style={{ fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 25, margin: '4px 0 0', lineHeight: 1.15 }}>
                      {kort.name}{kort.archived_at && <span style={arkivTagg}>Arkiverad</span>}
                    </h2>
                    <div style={{ height: 2, width: 34, background: 'var(--ulab-coral)', margin: '12px 0 0' }} />
                    <div style={{ display: 'flex', gap: 18, flexWrap: 'wrap', fontSize: 12, color: 'var(--fg-muted)', marginTop: 14 }}>
                      <span>Org.nr <b style={{ color: 'var(--ulab-navy)' }}>{kort.org_nr || '—'}</b></span>
                      {kundSedan && <span>Kund sedan <b style={{ color: 'var(--ulab-navy)' }}>{kundSedan}</b></span>}
                      <span>Kundnr Pyramid <b style={{ color: kort.customer_no ? 'var(--ulab-navy)' : 'var(--fg-subtle)', fontWeight: kort.customer_no ? 600 : 500 }}>
                        {kort.customer_no || 'kopplas senare'}</b></span>
                    </div>
                  </div>
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignSelf: 'flex-start' }}>
                  <button onClick={() => setRedigerar(true)} style={knapp()}
                    title="Ändra namn, org.nr, kundnr och kontaktuppgifter">Redigera uppgifter</button>
                  <button onClick={arkivera}
                    disabled={kort.canManage === false}
                    title={kort.canManage === false
                      ? (kort.ownerName
                          ? `${kort.name} är ${kort.ownerName}s kund — be hen eller en admin göra det`
                          : kort.lockReason === 'ingen'
                            ? `${kort.name} har offerter utan ansvarig säljare — bara en admin kan ta bort den`
                            : `Flera säljare har offererat till ${kort.name} — bara en admin kan ta bort den`)
                      : (kort.archived_at ? 'Ta tillbaka kunden i listan' : 'Kunden döljs ur listan men historiken finns kvar')}
                    style={{ ...knapp(), alignSelf: 'flex-start',
                      opacity: kort.canManage === false ? .5 : 1,
                      cursor: kort.canManage === false ? 'not-allowed' : 'pointer' }}>
                    {kort.archived_at ? 'Återaktivera kund' : 'Arkivera kund'}
                  </button>
                  </div>
                </div>
                )}

                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 1, background: 'var(--border)', borderBottom: '1px solid var(--border)' }}>
                  <Kpi etikett="Offererat totalt" varde={kr(offereratTotalt)} under="exkl. utkast" />
                  <Kpi etikett="Offerter" varde={String(kort.offerter.length)} under="genom åren" />
                  <Kpi etikett="Väntar på svar" varde={String(vantarPaKortet.length)}
                    under={vantarPaKortet.some(o => dagarTill(o.follow_up_at) < 0) ? 'någon är över datum' : (vantarPaKortet.length ? 'behöver följas upp' : 'inget utestående')}
                    farg={vantarPaKortet.some(o => dagarTill(o.follow_up_at) < 0) ? 'var(--ulab-coral)' : (vantarPaKortet.length ? AMBER : undefined)} />
                  <Kpi etikett="Senaste offert" varde={senasteOffert || '—'} litet
                    under={senasteOffert ? `${dagarSedan(senasteOffert)} dagar sedan` : 'ingen offert ännu'} />
                </div>

                {vantarPaKortet.length > 0 && (
                  <section style={block}>
                    <div style={{ background: '#fff7ed', border: '1px solid #f0b866', borderRadius: 5, padding: '12px 14px' }}>
                      <div style={{ ...blockRubrik, color: AMBER, marginBottom: 8 }}>Bevakning</div>
                      {vantarPaKortet.map((o, i) => {
                        const kvar = dagarTill(o.follow_up_at);
                        const sen = kvar != null && kvar < 0;
                        return (
                          <div key={o.id} style={{
                            display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12,
                            fontSize: 12.5, padding: '7px 0', flexWrap: 'wrap',
                            borderTop: i ? '1px solid rgba(240,184,102,.45)' : 'none',
                          }}>
                            <span>
                              <span style={{ cursor: 'pointer' }} onClick={() => onOpenOffer(o.id)}>{o.number} · {o.subject || 'Utan ämne'}</span>
                              <div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>
                                Skickad {o.date} · {dagarSedan(o.date)} dagar sedan{o.valid_until ? ` · giltig till ${o.valid_until}` : ''}
                              </div>
                            </span>
                            <span style={{ whiteSpace: 'nowrap', color: sen ? 'var(--ulab-coral)' : AMBER, fontWeight: sen ? 700 : 500, fontVariantNumeric: 'tabular-nums' }}>
                              Bevakas <input type="date" value={o.follow_up_at || ''} disabled={o.canEdit === false}
                                onChange={e => bytBevakning(o.id, e.target.value)}
                                style={{ fontFamily: 'var(--font-sans)', fontSize: 12, padding: '4px 7px', border: '1px solid #f0b866', borderRadius: 4, color: 'var(--ulab-navy)', background: '#fff' }} />
                              {' '}{kvar == null ? '' : sen ? `${Math.abs(kvar)} dagar sen` : `om ${kvar} dagar`}
                            </span>
                          </div>
                        );
                      })}
                    </div>
                  </section>
                )}

                <section style={block}>
                  <div style={blockRubrik}>Offerthistorik</div>
                  {!kort.offerter.length && <div style={{ fontSize: 13, color: 'var(--fg-subtle)' }}>Inga offerter ännu.</div>}
                  {kort.offerter.length > 0 && (
                    <div style={{ overflowX: 'auto' }}>
                      <table style={tabell}>
                        <thead>
                          <tr>
                            <th style={th}>Nummer</th><th style={th}>Ämne / säljare</th><th style={th}>Datum</th>
                            <th style={th}>Status</th><th style={{ ...th, textAlign: 'right' }}>Belopp</th>
                            <th style={{ ...th, width: 44 }}><span style={dold}>Ta bort</span></th>
                          </tr>
                        </thead>
                        <tbody>
                          {kort.offerter.map(o => (
                            <tr key={o.id}>
                              <td style={{ ...td, cursor: 'pointer', whiteSpace: 'nowrap' }} onClick={() => onOpenOffer(o.id)}>{o.number}</td>
                              <td style={{ ...td, cursor: 'pointer' }} onClick={() => onOpenOffer(o.id)}>
                                <span style={{ fontWeight: 600 }}>{o.subject || 'Utan ämne'}</span>
                                <div style={{ fontSize: 11, color: 'var(--fg-subtle)', marginTop: 2 }}>
                                  {o.owner_id === user.id ? '● Du' : `🔒 ${o.owner_name || 'annan säljare'}`}
                                </div>
                              </td>
                              <td style={{ ...td, whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums' }}>{o.date || '—'}</td>
                              <td style={td}><StatusVal offert={o} onChange={s => bytStatus(o.id, s)} /></td>
                              <td style={{ ...td, textAlign: 'right', fontWeight: 600, whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums' }}>{belopp(o)}</td>
                              <td style={{ ...td, textAlign: 'right' }}>
                                {o.canEdit === false ? (
                                  <span style={{ ...dold }}>Offerten tillhör {o.owner_name || 'en annan säljare'}</span>
                                ) : (
                                  <button
                                    onClick={() => taBortOffert(o)}
                                    disabled={raderar === o.id}
                                    title={`Ta bort offert ${o.number}`}
                                    aria-label={`Ta bort offert ${o.number}`}
                                    style={raderaKnapp}>×</button>
                                )}
                              </td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  )}
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 16 }}>
                    <button onClick={() => onNewOfferForCustomer(kort, null)} style={knapp('primar')}>Ny offert till {kort.name}</button>
                    {kort.offerter.length > 0 && (
                      <button onClick={() => onNewOfferForCustomer(kort, kort.offerter[0].id)} style={knapp()}>Utgå från senaste offerten</button>
                    )}
                    {kort.offerter.length > 0 && <button onClick={exportera} style={knapp()}>Exportera historiken</button>}
                  </div>
                </section>

                <section style={block}>
                  <div style={blockRubrik}>Kontaktpersoner</div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
                    {kort.contact && (
                      <div style={kontaktKort}>
                        <div style={{ fontWeight: 600, fontSize: 12.5 }}>{kort.contact}</div>
                        <div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>från senaste offerten</div>
                        <div style={{ fontSize: 11.5, color: 'var(--ulab-blue)', marginTop: 3 }}>{kort.email || kort.phone || ''}</div>
                      </div>
                    )}
                    {kort.kontakter.map(c => (
                      <div key={c.id} style={{ ...kontaktKort, position: 'relative' }}>
                        <div style={{ fontWeight: 600, fontSize: 12.5 }}>{c.name}</div>
                        <div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{c.role || 'kontaktperson'}</div>
                        <div style={{ fontSize: 11.5, color: 'var(--ulab-blue)', marginTop: 3 }}>{c.email || c.phone || ''}</div>
                        <button onClick={() => taBortKontakt(c.id)} title="Ta bort kontaktpersonen" aria-label={`Ta bort ${c.name}`}
                          style={{ position: 'absolute', top: 6, right: 8, background: 'none', border: 'none', color: 'var(--fg-subtle)', cursor: 'pointer', fontSize: 14, lineHeight: 1, padding: 0 }}>×</button>
                      </div>
                    ))}
                    {nyKontakt ? (
                      <div style={{ ...kontaktKort, minWidth: 240 }}>
                        {[['name', 'Namn'], ['role', 'Roll'], ['email', 'E-post'], ['phone', 'Telefon']].map(([f, etikett]) => (
                          <input key={f} value={nyKontakt[f]} placeholder={etikett} aria-label={etikett}
                            onChange={e => setNyKontakt(k => ({ ...k, [f]: e.target.value }))}
                            onKeyDown={e => { if (e.key === 'Enter') sparaKontakt(); if (e.key === 'Escape') setNyKontakt(null); }}
                            style={{ width: '100%', boxSizing: 'border-box', marginBottom: 5, fontFamily: 'var(--font-sans)', fontSize: 12, padding: '6px 8px', border: '1px solid var(--border-strong)', borderRadius: 3, color: 'var(--ulab-navy)' }} />
                        ))}
                        <div style={{ display: 'flex', gap: 6, marginTop: 4 }}>
                          <button onClick={sparaKontakt} style={{ ...knapp('primar'), padding: '6px 12px', fontSize: 12 }}>Spara</button>
                          <button onClick={() => setNyKontakt(null)} style={{ ...knapp(), padding: '6px 12px', fontSize: 12 }}>Avbryt</button>
                        </div>
                      </div>
                    ) : (
                      <button onClick={() => setNyKontakt({ name: '', role: '', email: '', phone: '' })}
                        style={{ ...kontaktKort, borderStyle: 'dashed', display: 'flex', alignItems: 'center', color: 'var(--fg-subtle)', background: 'transparent', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 12.5 }}>
                        + Lägg till kontaktperson
                      </button>
                    )}
                  </div>
                </section>

                <section style={{ ...block, borderBottom: 'none' }}>
                  <div style={blockRubrik}>Historik &amp; anteckningar</div>
                  <div style={{ position: 'relative', paddingLeft: 18 }}>
                    <div style={{ position: 'absolute', left: 4, top: 4, bottom: 4, width: 1, background: 'var(--border)' }} />
                    {!tidslinje.length && <div style={{ fontSize: 13, color: 'var(--fg-subtle)' }}>Inget att visa ännu.</div>}
                    {tidslinje.map((p, i) => (
                      <div key={i} style={{ position: 'relative', padding: '7px 0', fontSize: 12.5 }}>
                        <span style={{
                          position: 'absolute', left: -18, top: 14, width: 9, height: 9, borderRadius: '50%',
                          background: p.typ === 'offert' ? 'var(--ulab-blue)' : 'var(--ulab-cream)',
                          border: '2px solid #fff', boxShadow: p.typ === 'offert' ? 'none' : '0 0 0 1px var(--border-strong)',
                        }} />
                        <span style={{ color: 'var(--fg-subtle)', fontSize: 11, marginRight: 6, fontVariantNumeric: 'tabular-nums' }}>{p.d || '—'}</span>
                        {p.typ === 'offert' ? (
                          <React.Fragment>
                            <span style={{ fontWeight: 600, cursor: 'pointer' }} onClick={() => onOpenOffer(p.o.id)}>
                              {p.o.number} · {p.o.subject || 'Utan ämne'}
                            </span>
                            <span style={{ ...pill, ...STATUS_FARG[p.o.status], marginLeft: 8 }}>{p.o.status}</span>
                            <span style={{ marginLeft: 8 }}>{belopp(p.o)}</span>
                            <div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>{p.o.owner_id === user.id ? 'Du' : (p.o.owner_name || '')}</div>
                          </React.Fragment>
                        ) : (
                          <React.Fragment>
                            <span>{p.a.body}</span>
                            <div style={{ fontSize: 11, color: 'var(--fg-subtle)' }}>
                              {p.a.author_name || 'okänd'}
                              {(p.a.author_id === user.id || user.role === 'admin') && (
                                <button onClick={() => taBortAnteckning(p.a.id)} style={{
                                  marginLeft: 8, background: 'none', border: 'none', color: 'var(--fg-subtle)',
                                  cursor: 'pointer', fontSize: 11, textDecoration: 'underline', padding: 0,
                                }}>ta bort</button>
                              )}
                            </div>
                          </React.Fragment>
                        )}
                      </div>
                    ))}
                  </div>
                  <div style={{ marginTop: 12, display: 'flex', gap: 8, alignItems: 'flex-start' }}>
                    <textarea value={ny} onChange={e => setNy(e.target.value)} aria-label="Ny anteckning"
                      placeholder='Ny anteckning — t.ex. "Ringde Lars 17/9, återkommer efter budgetmötet"'
                      onKeyDown={e => { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') sparaAnteckning(); }}
                      style={{
                        flex: 1, fontFamily: 'var(--font-sans)', fontSize: 12.5, padding: '9px 11px', minHeight: 46,
                        border: '1px solid var(--border-strong)', borderRadius: 4, color: 'var(--ulab-navy)', resize: 'vertical',
                      }} />
                    <button onClick={sparaAnteckning} disabled={!ny.trim()}
                      style={{ ...knapp('primar'), opacity: ny.trim() ? 1 : .5, cursor: ny.trim() ? 'pointer' : 'not-allowed' }}>Spara</button>
                  </div>
                </section>
              </React.Fragment>
            )}
          </section>
        </div>
      ) : (
        <div style={panel}>
          <div style={{ padding: '22px 24px 18px', borderBottom: '1px solid var(--border)', display: 'flex', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>
            <div>
              <div style={eyebrow}>Alla kunder</div>
              <h2 style={{ fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 25, margin: '4px 0 0', lineHeight: 1.15 }}>Offerter som väntar på svar</h2>
              <div style={{ height: 2, width: 34, background: 'var(--ulab-coral)', margin: '12px 0 0' }} />
              <div style={{ fontSize: 12, color: 'var(--fg-muted)', marginTop: 14, maxWidth: 640 }}>
                Sorterat på bevakningsdatum — det som ska ringas först ligger överst. Datumet sätts automatiskt
                tio dagar fram när du markerar en offert som skickad, och går att ändra här.
              </div>
            </div>
            <label style={{ display: 'flex', gap: 6, alignItems: 'center', fontSize: 12, color: 'var(--fg-muted)', alignSelf: 'flex-start' }}>
              <input type="checkbox" checked={visaAllasBevakningar} onChange={e => setVisaAllasBevakningar(e.target.checked)} /> Visa allas
            </label>
          </div>
          <section style={{ ...block, borderBottom: 'none' }}>
            {!bevakningar.length && <div style={{ fontSize: 13, color: 'var(--fg-subtle)' }}>Inget väntar på svar just nu.</div>}
            {bevakningar.length > 0 && (
              <div style={{ overflowX: 'auto' }}>
                <table style={tabell}>
                  <thead>
                    <tr>
                      <th style={th}>Bevakas</th><th style={th}>Kund</th><th style={th}>Offert</th><th style={th}>Skickad</th>
                      <th style={th}>Väntat</th><th style={th}>Giltig till</th><th style={th}>Säljare</th><th style={th}>Status</th>
                      <th style={{ ...th, textAlign: 'right' }}>Belopp</th>
                    </tr>
                  </thead>
                  <tbody>
                    {bevakningar.map(b => {
                      const kvar = dagarTill(b.follow_up_at);
                      const sen = kvar != null && kvar < 0;
                      const utgangen = b.valid_until && dagarTill(b.valid_until) < 0;
                      return (
                        <tr key={b.id}>
                          <td style={{ ...td, whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums', color: sen ? 'var(--ulab-coral)' : (kvar != null && kvar <= 3 ? AMBER : undefined), fontWeight: sen ? 700 : 400 }}>
                            <input type="date" value={b.follow_up_at || ''} disabled={b.canEdit === false}
                              onChange={e => bytBevakning(b.id, e.target.value)}
                              style={{ fontFamily: 'var(--font-sans)', fontSize: 12, padding: '3px 6px', border: '1px solid var(--border-strong)', borderRadius: 3, color: 'inherit', background: '#fff' }} />
                            <div style={{ fontSize: 11, marginTop: 2 }}>{kvar == null ? 'ingen bevakning' : sen ? `${Math.abs(kvar)} dagar sen` : kvar === 0 ? 'idag' : `om ${kvar} dagar`}</div>
                          </td>
                          <td style={{ ...td, fontWeight: 600 }}>{b.customer_name || '—'}</td>
                          <td style={{ ...td, cursor: 'pointer' }} onClick={() => onOpenOffer(b.id)}>{b.number} · {b.subject || 'Utan ämne'}</td>
                          <td style={{ ...td, whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums' }}>{b.date || '—'}</td>
                          <td style={{ ...td, whiteSpace: 'nowrap', fontWeight: 600, color: utgangen ? 'var(--ulab-coral)' : undefined }}>{dagarSedan(b.date)} dagar</td>
                          <td style={{ ...td, whiteSpace: 'nowrap' }}>
                            {b.valid_until || '—'}
                            {utgangen && <span style={{ ...pill, ...STATUS_FARG['Avslagen'], marginLeft: 6 }}>utgången</span>}
                          </td>
                          <td style={{ ...td, fontSize: 11, color: 'var(--fg-subtle)', whiteSpace: 'nowrap' }}>{b.owner_id === user.id ? '● Du' : `🔒 ${b.owner_name || ''}`}</td>
                          <td style={td}><StatusVal offert={b} onChange={s => bytStatus(b.id, s)} /></td>
                          <td style={{ ...td, textAlign: 'right', fontWeight: 600, whiteSpace: 'nowrap', fontVariantNumeric: 'tabular-nums' }}>{belopp(b)}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )}
          </section>
        </div>
      )}
    </div>
  );
}

function StatusVal({ offert, onChange }) {
  const farg = STATUS_FARG[offert.status] || STATUS_FARG['Utkast'];
  return (
    <select value={offert.status} disabled={offert.canEdit === false} aria-label="Status"
      title={offert.canEdit === false ? 'Offerten tillhör en annan säljare' : 'Byt status'}
      onChange={e => onChange(e.target.value)}
      style={{
        fontFamily: 'var(--font-sans)', fontSize: 11, fontWeight: 600, padding: '3px 6px',
        borderRadius: 999, border: '1px solid', cursor: offert.canEdit === false ? 'not-allowed' : 'pointer',
        opacity: offert.canEdit === false ? .55 : 1, ...farg,
      }}>
      {STATUSAR.map(s => <option key={s} value={s}>{s}</option>)}
    </select>
  );
}

function Kpi({ etikett, varde, under, farg, litet }) {
  return (
    <div style={{ background: '#fff', padding: '16px 20px' }}>
      <div style={{ fontSize: 10.5, fontWeight: 600, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--fg-subtle)' }}>{etikett}</div>
      <div style={{ fontFamily: 'var(--font-serif)', fontSize: litet ? 19 : 23, fontWeight: 500, marginTop: 6, lineHeight: 1.1, fontVariantNumeric: 'tabular-nums', color: farg }}>{varde}</div>
      <div style={{ fontSize: 11, color: 'var(--fg-subtle)', marginTop: 4 }}>{under}</div>
    </div>
  );
}

const panel = { background: '#fff', border: '1px solid var(--border)', borderRadius: 6, boxShadow: 'var(--shadow-card)' };
const eyebrow = { fontSize: 11, fontWeight: 600, letterSpacing: '.16em', textTransform: 'uppercase', color: 'var(--fg-muted)' };
const block = { padding: '20px 24px', borderBottom: '1px solid var(--border)' };
const blockRubrik = { fontSize: 11, fontWeight: 600, letterSpacing: '.14em', textTransform: 'uppercase', color: 'var(--fg-muted)', marginBottom: 12 };
const tabell = { width: '100%', borderCollapse: 'collapse', fontSize: 12.5 };
const th = { textAlign: 'left', fontSize: 10.5, fontWeight: 600, letterSpacing: '.1em', textTransform: 'uppercase', color: 'var(--fg-subtle)', padding: '0 10px 8px 0', whiteSpace: 'nowrap' };
const td = { padding: '10px 10px 10px 0', borderTop: '1px solid var(--border)', verticalAlign: 'top' };
const pill = { display: 'inline-block', padding: '2px 9px', borderRadius: 999, fontSize: 11, fontWeight: 600, border: '1px solid', whiteSpace: 'nowrap' };
const kontaktKort = { border: '1px solid var(--border)', borderRadius: 5, padding: '10px 13px', minWidth: 190, textAlign: 'left' };
// Formuläret för kundens uppgifter. Fälten hålls i eget tillstånd och
// rapporteras uppåt först när man sparar — avbryter man händer ingenting.
const KUNDFALT = [
  { f: 'name', e: 'Företagsnamn', bredd: '1 / -1' },
  { f: 'org_nr', e: 'Org.nr', ph: '556000-0000' },
  { f: 'customer_no', e: 'Kundnr i Pyramid', ph: 'kopplas senare' },
  { f: 'contact', e: 'Kontaktperson' },
  { f: 'email', e: 'E-post', typ: 'email' },
  { f: 'phone', e: 'Telefon' },
];
function KundFormular({ kund, onSpara, onAvbryt, sparar }) {
  const [v, setV] = React.useState(() => {
    const start = {};
    KUNDFALT.forEach(x => { start[x.f] = kund[x.f] || ''; });
    return start;
  });
  const [fel, setFel] = React.useState([]);
  const forstaRef = React.useRef(null);
  React.useEffect(() => { if (forstaRef.current) forstaRef.current.focus(); }, []);

  const bara = s => String(s || '').replace(/[^0-9]/g, '');
  const spara = () => {
    const f = [];
    if (!v.name.trim()) f.push('Företagsnamnet får inte vara tomt.');
    if (v.org_nr.trim() && bara(v.org_nr).length !== 10) f.push('Org.nr ska innehålla tio siffror.');
    if (v.email.trim() && !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(v.email.trim())) f.push('E-postadressen ser inte riktig ut.');
    if (f.length) { setFel(f); return; }
    const ut = {};
    KUNDFALT.forEach(x => { ut[x.f] = v[x.f].trim(); });
    // Org.nr skrivs alltid med bindestreck, så registret ser likadant ut.
    if (bara(ut.org_nr).length === 10) ut.org_nr = bara(ut.org_nr).replace(/^(\d{6})(\d{4})$/, '$1-$2');
    onSpara(ut);
  };

  return (
    <div style={{ padding: '22px 24px 20px', borderBottom: '1px solid var(--border)' }}>
      <div style={eyebrow}>Redigera kunduppgifter</div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: '14px 16px', marginTop: 14 }}>
        {KUNDFALT.map((x, n) => (
          <label key={x.f} style={{ display: 'flex', flexDirection: 'column', gap: 6, gridColumn: x.bredd || 'auto' }}>
            <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--ulab-navy)', letterSpacing: '.04em' }}>{x.e}</span>
            <input
              ref={n === 0 ? forstaRef : null}
              value={v[x.f]}
              type={x.typ || 'text'}
              placeholder={x.ph || ''}
              onChange={e => setV(s => ({ ...s, [x.f]: e.target.value }))}
              onKeyDown={e => { if (e.key === 'Enter') spara(); if (e.key === 'Escape') onAvbryt(); }}
              style={kundInp} />
          </label>
        ))}
      </div>
      {fel.length > 0 && (
        <div role="alert" style={felRuta}>
          {fel.map((f, n) => <div key={n}>{f}</div>)}
        </div>
      )}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 16, alignItems: 'center' }}>
        <button onClick={spara} disabled={sparar} style={knapp('primar')}>
          {sparar ? 'Sparar…' : 'Spara ändringarna'}</button>
        <button onClick={onAvbryt} disabled={sparar} style={knapp()}>Avbryt</button>
        <span style={{ fontSize: 11.5, color: 'var(--fg-muted)' }}>
          Ändringen gäller kommande offerter. Redan skickade offerter behåller sina uppgifter.
        </span>
      </div>
    </div>
  );
}
const kundInp = {
  fontFamily: 'var(--font-sans)', fontSize: 13.5, padding: '9px 11px', width: '100%',
  border: '1px solid var(--border-strong)', borderRadius: 'var(--radius-button)',
  background: '#fff', color: 'var(--ulab-navy)',
};
const felRuta = {
  marginTop: 14, background: '#fdf0ee', border: '1px solid #eab5ac', color: '#8a3b30',
  borderRadius: 'var(--radius-button)', padding: '10px 12px', fontSize: 12.5, lineHeight: 1.6,
};

// Dold för ögat men läsbar för skärmläsare — används på kolumnrubriken för
// ta bort-knappen och där knappen är utbytt mot en förklaring.
const dold = { position: 'absolute', width: 1, height: 1, overflow: 'hidden', clipPath: 'inset(50%)', whiteSpace: 'nowrap' };
const raderaKnapp = {
  width: 28, height: 28, lineHeight: 1, fontSize: 16, cursor: 'pointer',
  border: '1px solid transparent', background: 'transparent', color: 'var(--fg-subtle)',
  borderRadius: 'var(--radius-button)', fontFamily: 'var(--font-sans)',
};
const arkivTagg = { marginLeft: 8, fontSize: 9.5, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--fg-subtle)', border: '1px solid var(--border-strong)', borderRadius: 3, padding: '0 5px' };
const tangent = { fontSize: 10.5, fontWeight: 600, border: '1px solid var(--border-strong)', borderBottomWidth: 2, borderRadius: 4, padding: '1px 6px', color: 'var(--fg-muted)', background: '#fff', whiteSpace: 'nowrap' };
function knapp(sort) {
  const bas = {
    fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 600, padding: '9px 15px',
    borderRadius: 4, cursor: 'pointer', border: '1px solid transparent',
  };
  if (sort === 'primar') return { ...bas, background: 'var(--ulab-navy)', color: '#fff' };
  return { ...bas, background: '#fff', color: 'var(--ulab-navy)', borderColor: 'var(--border-strong)' };
}
function navflik(aktiv) {
  return {
    fontFamily: 'var(--font-sans)', fontSize: 13, fontWeight: 600, cursor: 'pointer',
    padding: '10px 18px', borderRadius: '5px 5px 0 0', marginBottom: -1,
    border: '1px solid ' + (aktiv ? 'var(--border-strong)' : 'transparent'),
    borderBottom: '1px solid ' + (aktiv ? '#fff' : 'transparent'),
    background: aktiv ? '#fff' : 'transparent',
    color: aktiv ? 'var(--ulab-navy)' : 'var(--fg-muted)',
  };
}

window.CustomerRegister = CustomerRegister;
