/**
 * KAP DSI — Client API v5 (Sociétés / Contacts / Documents)
 */
const KAPData = (() => {
  const TK_CRM    = 'kapdsi_crm_token';
  const TK_CLIENT = 'kapdsi_client_token';

  function apiBase() {
    return window.location.pathname
      .replace(/\/(crm|hub|espace-client|admin)(\/.*)?$/, '')
      .replace(/\/$/, '');
  }
  function apiUrl(action, params = {}) {
    return apiBase() + '/api.php?' + new URLSearchParams({ action, ...params }).toString();
  }

  async function req(action, body = null, params = {}, tk = null) {
    const token = tk ? localStorage.getItem(tk) : null;
    const opts = { method: body ? 'POST' : 'GET', headers: { 'Content-Type': 'application/json' } };
    if (token) opts.headers['X-KAP-Token'] = token;
    if (body)  opts.body = JSON.stringify(body);
    let r;
    try { r = await fetch(apiUrl(action, params), opts); }
    catch (e) { throw new Error('Erreur réseau : ' + e.message); }
    let data;
    try { data = await r.json(); }
    catch {
      const raw = await r.text().catch(() => '(vide)');
      console.error('Non-JSON [' + action + ']:', raw);
      throw new Error('Réponse invalide (HTTP ' + r.status + '). Voir console F12.');
    }
    if (!data.ok) throw new Error(data.error || 'Erreur inconnue');
    return data;
  }

  // Upload multipart (documents)
  async function upload(formData) {
    const token = localStorage.getItem(TK_CRM);
    const r = await fetch(apiUrl('doc_upload'), {
      method: 'POST',
      headers: token ? { 'X-KAP-Token': token } : {},
      body: formData,
    });
    const data = await r.json();
    if (!data.ok) throw new Error(data.error || 'Erreur upload');
    return data;
  }

  const crm    = (a, b=null, p={}) => req(a, b, p, TK_CRM);
  const client = (a, b=null, p={}) => req(a, b, p, TK_CLIENT);
  const pub    = (a, b=null, p={}) => req(a, b, p, null);

  // ── Auth CRM ─────────────────────────────────────────────────
  const crmLogin = async (login, password, rememberMe=false) => {
    const d = await pub('crm_login', { login, password, remember_me: rememberMe });
    if (d.token) {
      localStorage.setItem(TK_CRM, d.token);
      if (rememberMe) localStorage.setItem('kapdsi_crm_remember', '1');
      else localStorage.removeItem('kapdsi_crm_remember');
    }
    return d;
  };
  const crmLogout = async () => { await crm('crm_logout').catch(()=>{}); localStorage.removeItem(TK_CRM); };
  const crmCheck  = () => crm('crm_check');
  const crmChangePwd = (cur, nw) => crm('crm_change_password', { currentPassword: cur, newPassword: nw });
  const crmRevokeAll  = ()           => crm('crm_revoke_all');

  // ── Utilisateurs CRM ─────────────────────────────────────────
  const crmUsersList  = ()     => crm('crm_users_list');
  const crmUserCreate = (data) => crm('crm_user_create', data);
  const crmUserUpdate = (data) => crm('crm_user_update', data);
  const crmUserDelete = (id)   => crm('crm_user_delete', { id });

  // ── Dashboard ─────────────────────────────────────────────────
  const dashboard = () => crm('crm_dashboard');

  // ── Sociétés ──────────────────────────────────────────────────
  const getSocietes   = (p={})   => crm('societes_list',   null, p);
  const getSociete    = (id)     => crm('societe_get',     null, { id });
  const createSociete = (data)   => crm('societe_create',  data);
  const updateSociete = (data)   => crm('societe_update',  data);
  const deleteSociete = (id)     => crm('societe_delete',  { id });

  // ── Contacts ──────────────────────────────────────────────────
  const getContacts   = (p={})   => crm('contacts_list',   null, p);
  const createContact = (data)   => crm('contact_create',  data);
  const updateContact = (data)   => crm('contact_update',  data);
  const deleteContact = (id)     => crm('contact_delete',  { id });

  // ── Documents ─────────────────────────────────────────────────
  const uploadDoc     = (fd) => upload(fd);            // FormData
  const deleteDoc     = (id) => crm('doc_delete', { id });

  // ── Factures (upload multipart) ───────────────────────────────
  async function uploadFacture(formData) {
    const token = localStorage.getItem(TK_CRM);
    const r = await fetch(apiUrl('facture_add'), {
      method: 'POST',
      headers: token ? { 'X-KAP-Token': token } : {},
      body: formData,   // FormData — pas de Content-Type manuel (boundary auto)
    });
    const data = await r.json().catch(async () => {
      const raw = await r.text().catch(() => '(vide)');
      console.error('Non-JSON [facture_add]:', raw);
      throw new Error('Réponse invalide (HTTP ' + r.status + ')');
    });
    if (!data.ok) throw new Error(data.error || 'Erreur upload facture');
    return data;
  }
  function downloadDoc(id, type = 'doc') {
    const token = localStorage.getItem(TK_CRM) || localStorage.getItem(TK_CLIENT);
    window.open(apiBase() + '/api.php?action=doc_download&id=' + id + '&type=' + type + (token ? '&_t=' + token : ''), '_blank');
  }

  // ── Interactions ──────────────────────────────────────────────
  const addInteraction    = (data) => crm('interaction_add',    data);
  const deleteInteraction = (id)   => crm('interaction_delete', { id });

  // ── Missions ──────────────────────────────────────────────────
  const getMissions   = (p={})   => crm('missions_list',  null, p);
  const addMission    = (data)   => crm('mission_add',    data);
  const updateMission = (data)   => crm('mission_update', data);
  const deleteMission = (id)     => crm('mission_delete', { id });

  // ── Factures ──────────────────────────────────────────────────
  const getFactures      = (p={})       => crm('factures_list',   null, p);
  const addFacture       = (fd)         => uploadFacture(fd);      // FormData
  const setFactureStatut = (id, statut) => crm('facture_statut',  { id, statut });
  const deleteFacture    = (id)         => crm('facture_delete',  { id });
  const sendInvite       = (contactId, siteUrl) => crm('send_invite', { contactId, siteUrl });

  // ── Espace client ─────────────────────────────────────────────
  const login = async (email, password) => {
    const d = await pub('login', { email, password });
    if (d.token) localStorage.setItem(TK_CLIENT, d.token);
    return d;
  };
  const logout = async () => { await client('logout').catch(()=>{}); localStorage.removeItem(TK_CLIENT); };
  const me           = ()                => client('me');
  const mesFactures  = ()                => client('mes_factures');
  const mesDocuments = ()                => client('mes_documents');
  const updateProfile   = (data)         => client('client_update_profile',  data);
  const changePassword  = (cur, nw)      => client('client_change_password', { currentPassword: cur, newPassword: nw });
  const forgotPassword  = (email, url)   => pub('forgot_password', { email, siteUrl: url });
  const resetPassword   = async (token, pwd) => {
    const d = await pub('reset_password', { token, password: pwd });
    if (d.token) localStorage.setItem(TK_CLIENT, d.token);
    return d;
  };
  const activate = async (token, pwd) => {
    const d = await pub('activate', { token, password: pwd });
    if (d.token) localStorage.setItem(TK_CLIENT, d.token);
    return d;
  };

  // ── Notes de frais ──────────────────────────────────────────────
  const ndfVehiculesList   = ()     => crm('ndf_vehicules_list');
  const ndfVehiculeSave    = (data) => crm('ndf_vehicule_save', data);
  const ndfVehiculeDelete  = (data) => crm('ndf_vehicule_delete', data);
  const ndfBaremesList     = (annee)=> crm('ndf_baremes_list', null, {annee:annee||new Date().getFullYear()});
  const ndfTauxKm          = (vehiculeId,annee) => crm('ndf_taux_km', null, {vehiculeId,annee:annee||new Date().getFullYear()});
  const ndfList            = (p={})=> crm('ndf_list', null, p);
  const ndfSave            = (data) => crm('ndf_save', data);
  const ndfDelete          = (data) => crm('ndf_delete', data);
  const ndfValider         = (data) => crm('ndf_valider', data);
  const ndfRembourser      = (data) => crm('ndf_rembourser', data);
  const ndfExtractReceipt  = (data) => crm('ndf_extract_receipt', data);

  // ── GED Google Drive ─────────────────────────────────────────────
  // ── GED Versioning ───────────────────────────────────────────────
  const gedFichierCreate  = (data) => crm('ged_fichier_create', data);
  const gedFichierGet     = (driveFileId) => crm('ged_fichier_get', null, {driveFileId});
  const gedFichierUpdate  = (data) => crm('ged_fichier_update', data);
  const gedNbVersionsSave = (data) => crm('ged_nb_versions_save', data);
  const gedMoveFile       = (data) => crm('ged_move_file', data);
  const gedPartageCreate  = (data) => crm('ged_partage_create', data);
  const gedPartagesList   = ()     => crm('ged_partages_list');
  const gedPartageRevoke  = (data) => crm('ged_partage_revoke', data);
  const gedPartageDelete  = (data) => crm('ged_partage_delete', data);
  const gedPartagesAvecMoi = ()    => crm('ged_partages_avec_moi');

  // ── Roadmap ───────────────────────────────────────────────────────
  const roadmapList        = ()     => crm('roadmap_list');
  const roadmapSave        = (data) => crm('roadmap_save', data);
  const roadmapGet         = (id)   => crm('roadmap_get', null, {id});
  const roadmapDelete      = (data) => crm('roadmap_delete', data);
  const roadmapItemSave    = (data) => crm('roadmap_item_save', data);
  const roadmapItemDelete  = (data) => crm('roadmap_item_delete', data);
  const roadmapItemsList   = ()     => crm('roadmap_items_list');

  // ── Notion ────────────────────────────────────────────────────────
  const notionPageGet    = (url)  => crm('notion_page_get', null, {url});

  // ── GED Inbox ─────────────────────────────────────────────────────
  const gedInboxRun        = ()     => crm('ged_inbox_run');
  const gedInboxLogs       = ()     => crm('ged_inbox_logs');
  const gedInboxBadgeReset = ()     => crm('ged_inbox_badge_reset');

  const gedFichierNewVersion = async (fichierId, file) => {
    const fd = new FormData();
    fd.append('file', file);
    fd.append('fichierId', fichierId);
    const token = localStorage.getItem(TK_CRM);
    const r = await fetch(apiBase()+'/api.php?action=ged_fichier_new_version', {
      method:'POST', body:fd, headers: token ? {'X-KAP-Token':token} : {}
    });
    if(!r.ok) throw new Error(await r.text());
    const d = await r.json();
    if(!d.ok) throw new Error(d.error||'Upload failed');
    return d;
  };

  const gedGroupesList    = ()     => crm('ged_groupes_list');
  const gedGroupeGet      = (id)   => crm('ged_groupe_get', null, {id});
  const gedGroupeSave     = (data) => crm('ged_groupe_save', data);
  const gedGroupeDelete   = (data) => crm('ged_groupe_delete', data);
  const gedItemDroitsGet  = (itemId) => crm('ged_item_droits_get', null, {itemId});
  const gedItemDroitSave  = (data) => crm('ged_item_droit_save', data);
  const gedItemDroitDelete= (data) => crm('ged_item_droit_delete', data);
  const gedUserAccess     = (itemId, parentIds) => crm('ged_user_access', null, {itemId, parentIds:(parentIds||[]).join(',')});
  // ── GED Google Drive ─────────────────────────────────────────────
  const gedList         = (params) => crm('ged_list', null, params);
  const gedFolderCreate = (data)   => crm('ged_folder_create', data);
  const gedRename       = (data)   => crm('ged_rename', data);
  const gedDelete       = (data)   => crm('ged_delete', data);
  const gedSearch       = (q)      => crm('ged_search', null, {q});
  const gedDownloadLink = (fileId) => crm('ged_download_link', null, {fileId});
  const gedDroitsList   = ()       => crm('ged_droits_list');
  const gedDroitSave    = (data)   => crm('ged_droit_save', data);
  const gedDroitDelete  = (data)   => crm('ged_droit_delete', data);
  const gedSettingsGet  = ()       => crm('ged_settings_get');
  const gedSettingsSave = (data)   => crm('ged_settings_save', data);
  const gedOauthStart   = ()       => crm('ged_oauth_start');
  const gedOauthRevoke  = ()       => crm('ged_oauth_revoke', {});

  const gedUpload = async (file, parentId) => {
    const fd = new FormData();
    fd.append('file', file);
    fd.append('parentId', parentId);
    const token = localStorage.getItem(TK_CRM);
    const r = await fetch(apiBase()+'/api.php?action=ged_upload', {
      method:'POST', body:fd,
      headers: token ? {'X-KAP-Token':token} : {}
    });
    if(!r.ok) throw new Error(await r.text());
    const d = await r.json();
    if(!d.ok) throw new Error(d.error||'Upload failed');
    return d;
  };

  // ── Roadmap ──────────────────────────────────────────────────────


  // ── Navigation & accès modules ───────────────────────────────────
  const navOrderGet      = ()     => crm('nav_order_get');
  const navOrderSave     = (data) => crm('nav_order_save', data);
  const userModulesGet   = (userId) => crm('user_modules_get', null, {userId});
  const userModulesSave  = (data) => crm('user_modules_save', data);

  // ── Projets ──────────────────────────────────────────────────────
  const projetsList        = ()     => crm('projets_list');
  const projetGet          = (id)   => crm('projet_get', null, {id});
  const projetSave         = (data) => crm('projet_save', data);
  const projetDelete       = (data) => crm('projet_delete', data);
  const phaseSave          = (data) => crm('phase_save', data);
  const phaseDelete        = (data) => crm('phase_delete', data);
  const tacheSave          = (data) => crm('tache_save', data);
  const tacheDelete        = (data) => crm('tache_delete', data);
  const tacheStatut        = (data) => crm('tache_statut', data);
  const commentaireSave    = (data) => crm('commentaire_save', data);
  const commentaireDelete  = (data) => crm('commentaire_delete', data);

  // ── Listes de diffusion ─────────────────────────────────────────
  const diffusionListesList  = ()     => crm('diffusion_listes_list');
  const diffusionListeGet    = (id)   => crm('diffusion_liste_get', null, {id});
  const diffusionListeSave   = (data) => crm('diffusion_liste_save', data);
  const diffusionListeDelete = (data) => crm('diffusion_liste_delete', data);
  const diffusionMembresSet  = (data) => crm('diffusion_membres_set', data);
  const diffusionMembresAdd  = (data) => crm('diffusion_membres_add', data);

  // ── Campagnes email ──────────────────────────────────────────────
  const campagnesList          = ()     => crm('campagnes_list');
  const campagneGet            = (id)   => crm('campagne_get', null, {id});
  const campagneCreate         = (data) => crm('campagne_create', data);
  const campagneUpdate         = (data) => crm('campagne_update', data);
  const campagneDestinatairesSet=(data) => crm('campagne_destinataires_set', data);
  const campagneSend           = (data) => crm('campagne_send', data);
  const campagneDelete         = (id)   => crm('campagne_delete', {id});
  const campagneStatsDetail    = (id)   => crm('campagne_stats_detail', null, {id});

  // ── Brevo Inbound ───────────────────────────────────────────────
  const setupBrevoInbound    = ()  => crm('setup_brevo_inbound');
  const setupBrevoCampagnes      = ()  => crm('setup_brevo_campagnes');
  const setupBrevoTransactionnel = ()  => crm('setup_brevo_transactionnel');
  const listBrevoWebhooks  = ()  => crm('list_brevo_webhooks');

  // ── LinkedIn ─────────────────────────────────────────────────
  const linkedinExtract = (data) => crm('linkedin_extract', data);

  // ── Droits espace client ─────────────────────────────────────
  const societeUpdateAccess = (data) => crm('societe_update_access', data);
  const contactUpdateAccess = (data) => crm('contact_update_access', data);

  // ── Paramètres applicatifs ─────────────────────────────────────
  const appSettingsGet    = ()     => crm('app_settings_get');
  const appSettingsUpdate = (data) => crm('app_settings_update', data);

  // ── Paramètres de notification ───────────────────────────────
  const notifSettingsGet    = ()     => crm('notif_settings_get');
  const notifSettingsUpdate = (data) => crm('notif_settings_update', data);

  // ── Tickets CRM ───────────────────────────────────────────────
  const ticketsList       = (p={})         => crm('tickets_list',          null, p);
  const ticketGet         = (id)           => crm('ticket_get',            null, { id });
  async function ticketCreate(formData) {
    const isFD = formData instanceof FormData;
    const token = localStorage.getItem(TK_CRM);
    if (isFD) {
      const r = await fetch(apiUrl('ticket_create'), {
        method: 'POST', headers: token ? {'X-KAP-Token': token} : {}, body: formData,
      });
      const data = await r.json().catch(async()=>{throw new Error('Réponse invalide (HTTP '+r.status+')')});
      if (!data.ok) throw new Error(data.error||'Erreur'); return data;
    }
    return crm('ticket_create', formData);
  }
  const ticketUpdateStatut= (data)         => crm('ticket_update_statut',  data);
  const ticketAssign      = (data)         => crm('ticket_assign',         data);
  async function ticketMessageAdd(formData) {
    // Supporte FormData (avec fichier) ou objet JSON (sans fichier)
    const isFD = formData instanceof FormData;
    // Priorité au token client si présent et qu'on est dans l'espace client
    // Si les deux tokens existent (Hub ouvert dans un autre onglet), préférer le client
    const isClientPage = window.location.pathname.includes('/espace-client');
    const token = isClientPage
      ? (localStorage.getItem(TK_CLIENT) || localStorage.getItem(TK_CRM))
      : (localStorage.getItem(TK_CRM) || localStorage.getItem(TK_CLIENT));
    if (isFD) {
      const r = await fetch(apiUrl('ticket_message_add'), {
        method: 'POST',
        headers: token ? { 'X-KAP-Token': token } : {},
        body: formData,
      });
      const data = await r.json().catch(async()=>{throw new Error('Réponse invalide (HTTP '+r.status+')')});
      if (!data.ok) throw new Error(data.error||'Erreur');
      return data;
    }
    return req('ticket_message_add', formData, {}, TK_CRM in localStorage ? TK_CRM : TK_CLIENT);
  }
  const ticketReopen = (id) => crm('ticket_reopen', { id });
  function ticketFileDownload(msgId) {
    const token = localStorage.getItem(TK_CRM) || localStorage.getItem(TK_CLIENT);
    window.open(apiUrl('ticket_file_download', { id: msgId }) + (token ? '&_t=' + token : ''), '_blank');
  }
  const ticketDelete      = (id)           => crm('ticket_delete',         { id });
  // Tickets espace client
  const mesTickets        = ()             => client('mes_tickets');
  const monTicket         = (id)           => client('mon_ticket',         null, { id });
  async function ticketClientCreate(formData) {
    const isFD = formData instanceof FormData;
    const token = localStorage.getItem(TK_CLIENT);
    if (isFD) {
      const r = await fetch(apiUrl('ticket_client_create'), {
        method: 'POST', headers: token ? {'X-KAP-Token': token} : {}, body: formData,
      });
      const data = await r.json().catch(async()=>{throw new Error('Réponse invalide (HTTP '+r.status+')')});
      if (!data.ok) throw new Error(data.error||'Erreur'); return data;
    }
    return client('ticket_client_create', formData);
  }

  // ── Comptabilité ─────────────────────────────────────────────
  const comptaList   = (p={})   => crm('compta_list',             null, p);
  const comptaPL     = (p={})   => crm('compta_pl',               null, p);
  const comptaUpdate = (data)   => crm('compta_update',           data);
  const comptaStatut = (id, st) => crm('compta_statut_paiement',  { id, statut: st });
  const comptaDelete = (id)     => crm('compta_delete',           { id });

  async function comptaAdd(formData) {
    const token = localStorage.getItem(TK_CRM);
    const r = await fetch(apiUrl('compta_add'), {
      method: 'POST',
      headers: token ? { 'X-KAP-Token': token } : {},
      body: formData,
    });
    const data = await r.json().catch(async () => {
      console.error('Non-JSON [compta_add]:', await r.text().catch(()=>''));
      throw new Error('Réponse invalide (HTTP ' + r.status + ')');
    });
    if (!data.ok) throw new Error(data.error || 'Erreur');
    return data;
  }

  function comptaDownload(id) {
    const token = localStorage.getItem(TK_CRM);
    window.open(apiUrl('compta_download', { id }) + (token ? '&_t=' + token : ''), '_blank');
  }
  function comptaExportCSV(params={}) {
    const token = localStorage.getItem(TK_CRM);
    window.open(apiUrl('compta_export_csv', params) + (token ? '&_t=' + token : ''), '_blank');
  }
  function comptaExportPDF(params={}) {
    const token = localStorage.getItem(TK_CRM);
    window.open(apiUrl('compta_export_pdf', params) + (token ? '&_t=' + token : ''), '_blank');
  }

  return {
    crmLogin, crmLogout, crmCheck, crmChangePwd, crmRevokeAll,
    crmUsersList, crmUserCreate, crmUserUpdate, crmUserDelete,
    dashboard,
    getSocietes, getSociete, createSociete, updateSociete, deleteSociete,
    getContacts, createContact, updateContact, deleteContact,
    uploadDoc, deleteDoc, downloadDoc,
    addInteraction, deleteInteraction,
    getMissions, addMission, updateMission, deleteMission,
    getFactures, addFacture, setFactureStatut, deleteFacture,
    sendInvite,
    login, logout, me, mesFactures, mesDocuments,
    updateProfile, changePassword, forgotPassword, resetPassword, activate,
    // Comptabilité
    comptaList, comptaPL, comptaAdd, comptaUpdate, comptaStatut, comptaDelete,
    comptaDownload, comptaExportCSV, comptaExportPDF,
    // Droits espace client
    ndfVehiculesList, ndfVehiculeSave, ndfVehiculeDelete,
    ndfBaremesList, ndfTauxKm, ndfList, ndfSave, ndfDelete,
    ndfValider, ndfRembourser, ndfExtractReceipt,
    gedFichierCreate, gedFichierGet, gedFichierUpdate, gedFichierNewVersion, gedNbVersionsSave,
    gedMoveFile, gedPartageCreate, gedPartagesList, gedPartageRevoke, gedPartageDelete, gedPartagesAvecMoi,
    roadmapList, roadmapSave, roadmapGet, roadmapDelete, roadmapItemSave, roadmapItemDelete, roadmapItemsList,
    notionPageGet,
    gedInboxRun, gedInboxLogs, gedInboxBadgeReset,
    gedGroupesList, gedGroupeGet, gedGroupeSave, gedGroupeDelete,
    gedItemDroitsGet, gedItemDroitSave, gedItemDroitDelete, gedUserAccess,
    gedList, gedFolderCreate, gedRename, gedDelete, gedSearch, gedDownloadLink, gedUpload,
    gedDroitsList, gedDroitSave, gedDroitDelete, gedSettingsGet, gedSettingsSave, gedOauthStart, gedOauthRevoke,
    navOrderGet, navOrderSave, userModulesGet, userModulesSave,
    projetsList, projetGet, projetSave, projetDelete,
    phaseSave, phaseDelete, tacheSave, tacheDelete, tacheStatut,
    commentaireSave, commentaireDelete,
    diffusionListesList, diffusionListeGet, diffusionListeSave, diffusionListeDelete,
    diffusionMembresSet, diffusionMembresAdd,
    campagnesList, campagneGet, campagneCreate, campagneUpdate,
    campagneDestinatairesSet, campagneSend, campagneDelete, campagneStatsDetail,
    setupBrevoInbound, setupBrevoCampagnes, setupBrevoTransactionnel, listBrevoWebhooks,
    linkedinExtract,
    societeUpdateAccess, contactUpdateAccess,
    // Paramètres de notification
    notifSettingsGet, notifSettingsUpdate,
    // Paramètres applicatifs
    appSettingsGet, appSettingsUpdate,
    // Tickets CRM
    ticketsList, ticketGet, ticketCreate, ticketUpdateStatut, ticketAssign, ticketMessageAdd, ticketReopen, ticketDelete,
    ticketFileDownload,
    // Tickets espace client
    mesTickets, monTicket, ticketClientCreate,
  };
})();
