/* global React */
// ClientPicker — composant GLOBAL partagé par tous les modules (Règle n°3.a)
// Recherche unifiée parmi 101 Odoo + 105 AE contacts + organisations
// Retourne un objet normalisé { source, id, name, email, phone, contactId, organizationId, odooId }
// Permet de créer inline un nouveau client s'il n'existe pas
//
// Usage :
//   <window.ClientPicker value={client} onChange={(c) => setClient(c)} placeholder="Rechercher client…" />
//
// Value retournée :
//   { source: 'odoo' | 'ae_contact' | 'ae_org' | 'new',
//     id,                  // id unique dans sa source
//     name,                // nom affichable
//     email, phone, city, zip, street,
//     firstName, lastName, // si contact
//     isCompany,           // bool
//     odooId,              // externalId Odoo (pour propagation)
//     contactId,           // id Contact AE (pour propagation)
//     organizationId }     // id Organization AE

(function () {
  const { useState, useEffect, useMemo, useRef } = React;
  const API = () => (window.AE_API && window.AE_API.BASE) || '';

  // Cache global (évite de recharger 101 Odoo à chaque ouverture)
  let _cache = { odoo: null, ae: null, orgs: null, ts: 0 };
  async function loadAll(force) {
    const FRESH = 60_000; // 1 min
    if (!force && _cache.ts && Date.now() - _cache.ts < FRESH && _cache.odoo) return _cache;
    try {
      const [odoo, ae, orgs] = await Promise.all([
        fetch(`${API()}/api/odoo/partners?limit=500`).then(r => r.json()).catch(() => ({ partners: [] })),
        fetch(`${API()}/api/contacts`).then(r => r.json()).catch(() => []),
        fetch(`${API()}/api/organizations`).then(r => r.json()).catch(() => []),
      ]);
      _cache = {
        odoo: odoo?.partners || [],
        ae: Array.isArray(ae) ? ae : [],
        orgs: Array.isArray(orgs) ? orgs : [],
        ts: Date.now(),
      };
    } catch (_) { /* noop */ }
    return _cache;
  }
  // Expose cache-invalidator
  window.AE_CLIENT_CACHE = {
    refresh: () => loadAll(true),
    get: () => _cache,
  };

  function normalize(src, o) {
    if (src === 'odoo') {
      return {
        source: 'odoo',
        id: o.id, odooId: o.id,
        name: o.name || `${o.firstName || ''} ${o.lastName || ''}`.trim() || '(sans nom)',
        firstName: o.firstName || null, lastName: o.lastName || null,
        email: o.email || null, phone: o.phone || o.mobile || null,
        mobile: o.mobile || null, city: o.city || null, zip: o.zip || null, street: o.street || null,
        company: o.company_name || null, isCompany: !!o.is_company,
        contactId: null, organizationId: null,
      };
    }
    if (src === 'ae_contact') {
      return {
        source: 'ae_contact',
        id: o.id, contactId: o.id,
        name: o.fullName || `${o.firstName || ''} ${o.lastName || ''}`.trim(),
        firstName: o.firstName, lastName: o.lastName,
        email: o.email, phone: o.phone, mobile: o.mobile,
        city: o.city || null, zip: o.zip || null, street: o.street || null,
        odooId: o.odooId || null, organizationId: o.organizationId || null,
        isCompany: false,
      };
    }
    if (src === 'ae_org') {
      return {
        source: 'ae_org',
        id: o.id, organizationId: o.id,
        name: o.name,
        email: o.email, phone: o.phone,
        city: o.city || null, zip: o.zip || null, street: o.address || null,
        siret: o.siret, website: o.website,
        odooId: o.odooId || null, contactId: null,
        isCompany: true,
      };
    }
    return null;
  }

  function ClientPicker({ value, onChange, placeholder, required, autoFocus, sourceHint, compact }) {
    const [q, setQ] = useState(value?.name || '');
    const [open, setOpen] = useState(false);
    const [items, setItems] = useState({ odoo: [], ae: [], orgs: [] });
    const [creating, setCreating] = useState(false);
    const [draft, setDraft] = useState({ firstName: '', lastName: '', email: '', phone: '', company: '' });
    const [saving, setSaving] = useState(false);
    const ref = useRef(null);

    useEffect(() => {
      loadAll().then(c => setItems({ odoo: c.odoo || [], ae: c.ae || [], orgs: c.orgs || [] }));
    }, []);

    useEffect(() => {
      if (value?.name && value.name !== q) setQ(value.name);
    }, [value?.id, value?.source]);

    useEffect(() => {
      const close = (e) => { if (ref.current && !ref.current.contains(e.target)) { setOpen(false); setCreating(false); } };
      document.addEventListener('mousedown', close);
      return () => document.removeEventListener('mousedown', close);
    }, []);

    const results = useMemo(() => {
      const str = (q || '').toLowerCase().trim();
      const mkStr = (o, extra) => [o.name, o.firstName, o.lastName, o.fullName, o.email, o.phone, o.mobile, o.city, o.company, o.company_name, o.siret, extra].filter(Boolean).join(' ').toLowerCase();
      const odoo = items.odoo.filter(o => !str || mkStr(o, 'odoo').includes(str)).slice(0, 20).map(o => normalize('odoo', o));
      const ae = items.ae.filter(o => !str || mkStr(o, 'ae').includes(str)).slice(0, 15).map(o => normalize('ae_contact', o));
      const orgs = items.orgs.filter(o => !str || mkStr(o, 'org').includes(str)).slice(0, 10).map(o => normalize('ae_org', o));
      return { odoo, ae, orgs, total: odoo.length + ae.length + orgs.length };
    }, [q, items]);

    const pick = (c) => {
      setQ(c.name);
      onChange && onChange(c);
      setOpen(false);
    };

    const createNew = async () => {
      if (!draft.firstName && !draft.lastName && !draft.company) { alert('Saisir au moins un nom ou une société'); return; }
      setSaving(true);
      try {
        // Upsert organization si company
        let orgId = null;
        if (draft.company) {
          const existing = items.orgs.find(o => (o.name || '').toLowerCase() === draft.company.toLowerCase());
          if (existing) orgId = existing.id;
          else {
            const org = await fetch(`${API()}/api/organizations`, {
              method: 'POST', headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ name: draft.company, email: draft.email || null, phone: draft.phone || null }),
            }).then(r => r.json()).catch(() => null);
            if (org?.id) orgId = org.id;
          }
        }
        // Upsert contact (dédup par email si fourni)
        let contact = null;
        if (draft.email) {
          contact = items.ae.find(c => (c.email || '').toLowerCase() === draft.email.toLowerCase());
        }
        if (!contact) {
          const r = await fetch(`${API()}/api/contacts`, {
            method: 'POST', headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              firstName: draft.firstName || null, lastName: draft.lastName || null,
              email: draft.email || null, phone: draft.phone || null,
              organizationId: orgId,
            }),
          }).then(r => r.json()).catch(() => null);
          if (r?.id) contact = r;
        }
        await loadAll(true);
        const c2 = window.AE_CLIENT_CACHE.get();
        setItems({ odoo: c2.odoo || [], ae: c2.ae || [], orgs: c2.orgs || [] });
        if (contact) {
          const norm = normalize('ae_contact', contact);
          pick(norm);
        } else if (orgId) {
          const o = (c2.orgs || []).find(x => x.id === orgId);
          if (o) pick(normalize('ae_org', o));
        }
        setCreating(false);
        setDraft({ firstName: '', lastName: '', email: '', phone: '', company: '' });
      } catch (e) {
        alert('⚠ ' + e.message);
      } finally { setSaving(false); }
    };

    const rowStyle = (active) => ({
      display: 'grid', gridTemplateColumns: 'auto 1fr auto', gap: 8, alignItems: 'center',
      padding: '6px 10px', fontSize: 11, cursor: 'pointer',
      borderBottom: '1px solid var(--hairline)',
      background: active ? 'var(--signal-tint)' : 'transparent',
    });
    const badge = (txt, color) => <span style={{ fontSize: 8, padding: '1px 5px', background: `var(--${color}-tint, ${color})`, color: `var(--${color}-deep, ${color})`, borderRadius: 3, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.4 }}>{txt}</span>;

    return (
      <div ref={ref} style={{ position: 'relative', width: '100%' }}>
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <input
            value={q}
            autoFocus={autoFocus}
            placeholder={placeholder || 'Rechercher client (Odoo + Audits Énergies)…'}
            onChange={e => { setQ(e.target.value); setOpen(true); if (!e.target.value) onChange && onChange(null); }}
            onFocus={() => setOpen(true)}
            style={{
              flex: 1, padding: compact ? '5px 8px' : '7px 10px', fontSize: 12,
              border: '1px solid ' + (required && !value ? 'var(--rouge)' : 'var(--line-2)'),
              borderRadius: 4, background: 'var(--paper)', color: 'var(--ink)', fontFamily: 'inherit',
            }}
          />
          {value && (
            <button type="button" onClick={() => { setQ(''); onChange && onChange(null); }} title="Effacer" style={{ fontSize: 11, padding: '4px 8px', background: 'var(--paper-2)', border: '1px solid var(--line-2)', borderRadius: 4, cursor: 'pointer' }}>✕</button>
          )}
        </div>

        {value && !open && (
          <div style={{ marginTop: 4, fontSize: 10, color: 'var(--ink-4)', display: 'flex', gap: 8, alignItems: 'center' }}>
            {value.source === 'odoo' && badge('🟣 Odoo #' + value.odooId, 'plasma')}
            {value.source === 'ae_contact' && badge('⚡ AE #' + value.contactId, 'signal')}
            {value.source === 'ae_org' && badge('🏢 Orga #' + value.organizationId, 'plasma')}
            {value.source === 'new' && badge('✨ Nouveau', 'signal')}
            <span>{value.email || '—'} · {value.phone || '—'}</span>
          </div>
        )}

        {open && (
          <div style={{
            position: 'absolute', top: '100%', left: 0, right: 0, zIndex: 1000,
            marginTop: 2, maxHeight: 320, overflowY: 'auto',
            background: 'var(--paper)', border: '1px solid var(--line-2)', borderRadius: 6,
            boxShadow: '0 8px 24px -4px rgba(0,0,0,0.12)',
          }}>
            {creating ? (
              <div style={{ padding: 12, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
                <div style={{ gridColumn: '1 / -1', fontSize: 11, fontWeight: 600, color: 'var(--ink-3)', marginBottom: 4 }}>
                  ✨ Créer un nouveau client
                </div>
                <input placeholder="Prénom" value={draft.firstName} onChange={e => setDraft(d => ({ ...d, firstName: e.target.value }))} style={{ padding: '6px 8px', fontSize: 11, border: '1px solid var(--line-2)', borderRadius: 4, background: 'var(--paper)' }} />
                <input placeholder="Nom" value={draft.lastName} onChange={e => setDraft(d => ({ ...d, lastName: e.target.value }))} style={{ padding: '6px 8px', fontSize: 11, border: '1px solid var(--line-2)', borderRadius: 4, background: 'var(--paper)' }} />
                <input placeholder="Société (orga)" value={draft.company} onChange={e => setDraft(d => ({ ...d, company: e.target.value }))} style={{ gridColumn: '1 / -1', padding: '6px 8px', fontSize: 11, border: '1px solid var(--line-2)', borderRadius: 4, background: 'var(--paper)' }} />
                <input placeholder="Email" type="email" value={draft.email} onChange={e => setDraft(d => ({ ...d, email: e.target.value }))} style={{ padding: '6px 8px', fontSize: 11, border: '1px solid var(--line-2)', borderRadius: 4, background: 'var(--paper)' }} />
                <input placeholder="Téléphone" value={draft.phone} onChange={e => setDraft(d => ({ ...d, phone: e.target.value }))} style={{ padding: '6px 8px', fontSize: 11, border: '1px solid var(--line-2)', borderRadius: 4, background: 'var(--paper)' }} />
                <div style={{ gridColumn: '1 / -1', display: 'flex', gap: 6, justifyContent: 'flex-end', marginTop: 4 }}>
                  <button type="button" onClick={() => setCreating(false)} disabled={saving} style={{ padding: '5px 10px', fontSize: 11, background: 'var(--paper-2)', border: '1px solid var(--line-2)', borderRadius: 4 }}>Annuler</button>
                  <button type="button" onClick={createNew} disabled={saving} style={{ padding: '5px 12px', fontSize: 11, background: 'var(--signal)', color: 'var(--ink)', border: 'none', borderRadius: 4, fontWeight: 600 }}>{saving ? '…' : '✓ Créer & lier'}</button>
                </div>
              </div>
            ) : (
              <>
                {/* Odoo */}
                {results.odoo.length > 0 && (
                  <>
                    <div style={{ padding: '4px 10px', fontSize: 9, fontWeight: 600, color: '#714B67', textTransform: 'uppercase', letterSpacing: 0.5, background: 'var(--plasma-tint)' }}>🟣 Odoo ({results.odoo.length})</div>
                    {results.odoo.map(c => (
                      <div key={'o' + c.id} onClick={() => pick(c)} style={rowStyle(value?.source === 'odoo' && value.id === c.id)}>
                        <span>{c.isCompany ? '🏢' : '👤'}</span>
                        <div>
                          <div style={{ fontWeight: 500 }}>{c.name}</div>
                          <div style={{ fontSize: 10, color: 'var(--ink-4)' }}>{c.email || c.phone || c.city || '—'}</div>
                        </div>
                        <span className="mono" style={{ fontSize: 9, color: 'var(--ink-4)' }}>#{c.id}</span>
                      </div>
                    ))}
                  </>
                )}
                {/* AE contacts */}
                {results.ae.length > 0 && (
                  <>
                    <div style={{ padding: '4px 10px', fontSize: 9, fontWeight: 600, color: 'var(--signal-deep)', textTransform: 'uppercase', letterSpacing: 0.5, background: 'var(--signal-tint)' }}>⚡ Audits Énergies ({results.ae.length})</div>
                    {results.ae.map(c => (
                      <div key={'a' + c.id} onClick={() => pick(c)} style={rowStyle(value?.source === 'ae_contact' && value.id === c.id)}>
                        <span>👤</span>
                        <div>
                          <div style={{ fontWeight: 500 }}>{c.name}</div>
                          <div style={{ fontSize: 10, color: 'var(--ink-4)' }}>{c.email || c.phone || '—'}{c.odooId ? ` · Odoo #${c.odooId}` : ''}</div>
                        </div>
                        <span className="mono" style={{ fontSize: 9, color: 'var(--ink-4)' }}>#{c.id}</span>
                      </div>
                    ))}
                  </>
                )}
                {/* Orgas */}
                {results.orgs.length > 0 && (
                  <>
                    <div style={{ padding: '4px 10px', fontSize: 9, fontWeight: 600, color: 'var(--plasma-deep, #6b4a98)', textTransform: 'uppercase', letterSpacing: 0.5, background: 'var(--plasma-tint)' }}>🏢 Organisations ({results.orgs.length})</div>
                    {results.orgs.map(c => (
                      <div key={'g' + c.id} onClick={() => pick(c)} style={rowStyle(value?.source === 'ae_org' && value.id === c.id)}>
                        <span>🏢</span>
                        <div>
                          <div style={{ fontWeight: 500 }}>{c.name}</div>
                          <div style={{ fontSize: 10, color: 'var(--ink-4)' }}>{c.siret || c.city || c.email || '—'}</div>
                        </div>
                        <span className="mono" style={{ fontSize: 9, color: 'var(--ink-4)' }}>#{c.id}</span>
                      </div>
                    ))}
                  </>
                )}
                {results.total === 0 && (
                  <div style={{ padding: 12, fontSize: 11, color: 'var(--ink-4)', textAlign: 'center' }}>
                    Aucun résultat pour « {q} »
                  </div>
                )}
                <button type="button" onClick={() => { setCreating(true); setDraft(d => ({ ...d, lastName: q.trim() || d.lastName })); }} style={{
                  width: '100%', padding: '8px 10px', fontSize: 11, fontWeight: 600,
                  background: 'var(--paper-2)', color: 'var(--signal-deep)',
                  border: 'none', borderTop: '1px solid var(--line-2)', cursor: 'pointer', textAlign: 'left',
                }}>
                  ✨ Créer un nouveau client {q.trim() ? `« ${q.trim()} »` : ''} (upsert Contact + Organisation)
                </button>
              </>
            )}
          </div>
        )}
      </div>
    );
  }

  // Helper : propager un client sélectionné dans toutes les entités liées (Règle 3.a)
  // À appeler après création d'une Opportunité/Projet/Étude/Visite/Devis
  async function propagate(entityType, entityId, client) {
    if (!client || !entityId) return;
    // Upsert contact si le client vient d'Odoo et n'existe pas encore en AE
    if (client.source === 'odoo' && !client.contactId) {
      const existing = (_cache.ae || []).find(c => c.odooId === client.odooId || (client.email && c.email === client.email));
      if (!existing) {
        const [firstName, ...rest] = (client.name || '').split(' ');
        await fetch(`${API()}/api/contacts`, {
          method: 'POST', headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            firstName, lastName: rest.join(' ') || null,
            email: client.email, phone: client.phone, mobile: client.mobile,
            odooId: client.odooId,
          }),
        }).then(r => r.json()).catch(() => {});
        await loadAll(true);
      }
    }
    // Hydrate les caches des autres modules
    if (window.AE_API?.hydrate) window.AE_API.hydrate();
  }

  window.ClientPicker = ClientPicker;
  window.AE_CLIENT_PICKER = { normalize, propagate, loadAll };
})();
