// ─────────────────────────────────────────────────────
// OUTILS CONSULTANT — Création et édition de recettes
// Interface simple : liste à gauche, éditeur à droite
// ─────────────────────────────────────────────────────

const ALLERGENES_OPTIONS = [
  { id: 'gluten', label: 'Gluten' },
  { id: 'lactose', label: 'Lactose' },
  { id: 'oeufs', label: 'Œufs' },
  { id: 'poissons', label: 'Poissons' },
  { id: 'crustaces', label: 'Crustacés' },
  { id: 'fruits_coque', label: 'Fruits à coque' },
  { id: 'sulfites', label: 'Sulfites' },
  { id: 'arachides', label: 'Arachides' },
  { id: 'soja', label: 'Soja' },
  { id: 'celeri', label: 'Céleri' },
  { id: 'moutarde', label: 'Moutarde' },
  { id: 'sesame', label: 'Sésame' },
  { id: 'mollusques', label: 'Mollusques' },
  { id: 'lupin', label: 'Lupin' },
];

const CATEGORIES_REC = ['Entrées', 'Plats', 'Desserts', 'Fromages', 'Sauces', 'Fonds', 'Amuse-bouches', 'Garnitures'];
const UNITES_REC = ['g', 'kg', 'ml', 'L', 'pcs', 'cs', 'cc', 'pincée'];

const ConsultantTools = ({ user, etablissement }) => {
  const etabId = etablissement?.id || 'etab-1';
  const [recettes, setRecettes] = React.useState(() => window.SB ? [] : scRead('sc_recettes', DEMO_DATA.recettes));
  const [selectedId, setSelectedId] = React.useState(null);
  const [search, setSearch] = React.useState('');
  const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false);

  // Filtrer par établissement
  const recettesEtab = recettes.filter(r => (r.etablissementId || 'etab-1') === etabId);

  // Chargement initial + realtime depuis Supabase
  React.useEffect(() => {
    if (!window.SB) return;
    let unsub = null, mounted = true;
    (async () => {
      try {
        const recs = await window.SB.db.listRecettes(etabId);
        if (mounted) {
          setRecettes(recs);
          if (!selectedId && recs[0]) setSelectedId(recs[0].id);
        }
      } catch (err) { console.error('[ConsultantTools load]', err); }
    })();
    unsub = window.SB.realtime.subscribe('recettes', async () => {
      try { const recs = await window.SB.db.listRecettes(etabId); if (mounted) setRecettes(recs); } catch(e) {}
    });
    return () => { mounted = false; unsub && unsub(); };
  }, [etabId]);

  // Si changement d'établissement rend selectedId invalide
  React.useEffect(() => {
    if (selectedId && !recettesEtab.find(r => r.id === selectedId)) {
      setSelectedId(recettesEtab[0]?.id || null);
    }
  }, [etabId, recettes.length]);

  // Recalcul des dérivés (foodCost, etc.) — local, pas de persistance auto
  React.useEffect(() => {
    recettes.forEach(r => {
      r.coutMatiere = (r.ingredients || []).reduce((s, i) => s + (Number(i.quantite) || 0) * (Number(i.prixUnit) || 0), 0);
      r.coutPortion = r.portions ? r.coutMatiere / r.portions : 0;
      r.foodCost = r.prixVente ? (r.coutPortion / r.prixVente * 100) : null;
      r.margeGrossePct = r.prixVente ? ((r.prixVente - r.coutPortion) / r.prixVente * 100) : null;
      if (r.tempsPreparation != null && r.tempsCuisson != null) {
        r.tempsTotal = Number(r.tempsPreparation) + Number(r.tempsCuisson);
      }
    });
    DEMO_DATA.recettes = recettes;
    if (!window.SB) scWrite('sc_recettes', recettes);
  }, [recettes]);

  const selected = recettes.find(r => r.id === selectedId);
  const filtered = recettesEtab.filter(r => search === '' || r.nom.toLowerCase().includes(search.toLowerCase()));

  // Debounce pour updateSelected → upsert Supabase 600ms après la dernière modif
  const saveTimerRef = React.useRef(null);
  const updateSelected = (updates) => {
    setRecettes(prev => prev.map(r => r.id === selectedId ? { ...r, ...updates } : r));
    if (window.SB) {
      if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
      saveTimerRef.current = setTimeout(async () => {
        const curr = recettesRef.current.find(r => r.id === selectedId);
        if (curr) {
          try { await window.SB.db.upsertRecette(curr); }
          catch (err) { console.error('[upsertRecette]', err); }
        }
      }, 600);
    }
  };
  // Ref mise à jour à chaque render pour accès dans le setTimeout
  const recettesRef = React.useRef(recettes);
  React.useEffect(() => { recettesRef.current = recettes; }, [recettes]);

  const createNew = async () => {
    const newRec = {
      id: 'rec-' + Date.now(),
      etablissementId: etabId,
      nom: 'Nouvelle recette',
      portions: 4,
      categorie: 'Plats',
      statut: 'brouillon',
      version: 1,
      prixVente: 0,
      tempsPreparation: 0,
      tempsCuisson: 0,
      tempsTotal: 0,
      allergenesIds: [],
      notesConsultant: '',
      modifie: new Date().toISOString().slice(0, 10),
      modifiePar: user.id,
      ingredients: [],
      etapes: [],
      dressage: '',
      conservation: '',
    };
    setRecettes(prev => [newRec, ...prev]);
    setSelectedId(newRec.id);
    if (window.SB) {
      try { await window.SB.db.upsertRecette(newRec); }
      catch (err) { alert('Erreur création : ' + err.message); }
    }
  };

  const duplicate = async () => {
    if (!selected) return;
    const copy = JSON.parse(JSON.stringify(selected));
    copy.id = 'rec-' + Date.now();
    copy.nom = selected.nom + ' (copie)';
    copy.version = 1;
    copy.statut = 'brouillon';
    copy.modifie = new Date().toISOString().slice(0, 10);
    copy.modifiePar = user.id;
    copy.ingredients = (copy.ingredients || []).map((i, idx) => ({ ...i, id: 'i' + Date.now() + '_' + idx }));
    setRecettes(prev => [copy, ...prev]);
    setSelectedId(copy.id);
    if (window.SB) {
      try { await window.SB.db.upsertRecette(copy); }
      catch (err) { alert('Erreur duplication : ' + err.message); }
    }
  };

  const deleteRecette = async () => {
    if (!selected) return;
    const idToDelete = selectedId;
    if (window.SB) {
      try { await window.SB.db.deleteRecette(idToDelete); }
      catch (err) { alert('Erreur suppression : ' + err.message); return; }
    }
    const next = recettes.filter(r => r.id !== idToDelete);
    setRecettes(next);
    setSelectedId(next[0]?.id || null);
    setShowDeleteConfirm(false);
  };

  // ═══ Synchronisation carte active ═══
  // État local des cartes pour que isRecetteActive se re-render quand on change
  const [cartesLocal, setCartesLocal] = React.useState(() => window.SB ? [] : scRead('sc_cartes', DEMO_DATA.cartes));

  React.useEffect(() => {
    if (!window.SB) return;
    let unsub = null, mounted = true;
    (async () => {
      try { const c = await window.SB.db.listCartes(etabId); if (mounted) setCartesLocal(c); } catch(e) {}
    })();
    unsub = window.SB.realtime.subscribe('cartes', async () => {
      try { const c = await window.SB.db.listCartes(etabId); if (mounted) setCartesLocal(c); } catch(e) {}
    });
    return () => { mounted = false; unsub && unsub(); };
  }, [etabId]);

  const toggleActifSurCarte = async (recette, actif) => {
    if (!recette) return;
    const source = window.SB ? cartesLocal : scRead('sc_cartes', DEMO_DATA.cartes);
    let carteEtab = source.find(c => (c.etablissementId || 'etab-1') === etabId);

    // Créer une carte par défaut si aucune n'existe
    if (!carteEtab) {
      carteEtab = {
        id: 'carte-' + etabId + '-' + Date.now(),
        etablissementId: etabId,
        nom: 'Carte principale',
        dateDebut: new Date().toISOString().slice(0, 10),
        dateFin: null,
        plats: [],
      };
    } else {
      // Cloner pour ne pas muter
      carteEtab = { ...carteEtab, plats: [...(carteEtab.plats || [])] };
    }

    if (actif) {
      if (!carteEtab.plats.find(p => p.recetteId === recette.id)) {
        carteEtab.plats.push({
          id: 'p-' + Date.now(),
          nom: recette.nom,
          categorie: recette.categorie,
          prix: recette.prixVente || 0,
          allergenes: recette.allergenesIds || [],
          recetteId: recette.id,
        });
      }
    } else {
      carteEtab.plats = carteEtab.plats.filter(p => p.recetteId !== recette.id);
    }

    if (window.SB) {
      try { await window.SB.db.upsertCarte(carteEtab); }
      catch (err) { alert('Erreur sync carte : ' + err.message); return; }
    } else {
      const cartes = scRead('sc_cartes', DEMO_DATA.cartes);
      const idx = cartes.findIndex(c => c.id === carteEtab.id);
      if (idx >= 0) cartes[idx] = carteEtab; else cartes.push(carteEtab);
      DEMO_DATA.cartes = cartes;
      scWrite('sc_cartes', cartes);
    }

    // Mettre à jour le statut local (sera persisté par le useEffect de recettes)
    const newStatut = actif ? 'active' : 'brouillon';
    setRecettes(prev => prev.map(r => r.id === recette.id ? { ...r, statut: newStatut } : r));
    if (window.SB) {
      try { await window.SB.db.upsertRecette({ ...recette, statut: newStatut }); } catch(e) {}
    }
  };

  const isRecetteActive = (recette) => {
    if (!recette) return false;
    const source = window.SB ? cartesLocal : scRead('sc_cartes', DEMO_DATA.cartes);
    const carteEtab = source.find(c => (c.etablissementId || 'etab-1') === etabId);
    return carteEtab?.plats?.some(p => p.recetteId === recette.id) || false;
  };

  // ═══ Import / Export XLSX ═══
  const downloadTemplate = () => {
    if (typeof XLSX === 'undefined') { alert('Bibliothèque XLSX non chargée.'); return; }
    const wb = XLSX.utils.book_new();
    // Feuille 1 : Recettes (exemple pré-rempli)
    const recettesRows = [
      ['Nom de la recette', 'Catégorie', 'Portions', 'Prix de vente (CHF)', 'Temps préparation (min)', 'Temps cuisson (min)', 'Allergènes (séparés par ;)', 'Notes consultant'],
      ['Risotto aux asperges', 'Plats', 4, 28.50, 15, 20, 'lactose', 'Servir chaud, décorer avec parmesan'],
      ['Mousse au chocolat', 'Desserts', 6, 12.00, 20, 0, 'lactose;oeufs', 'Préparer la veille'],
    ];
    const wsRecettes = XLSX.utils.aoa_to_sheet(recettesRows);
    wsRecettes['!cols'] = [{ wch: 30 }, { wch: 14 }, { wch: 10 }, { wch: 18 }, { wch: 22 }, { wch: 20 }, { wch: 25 }, { wch: 30 }];
    XLSX.utils.book_append_sheet(wb, wsRecettes, 'Recettes');

    // Feuille 2 : Ingrédients (liés par "Nom de la recette")
    const ingredientsRows = [
      ['Nom de la recette', 'Ingrédient', 'Quantité', 'Unité', 'Prix unitaire (CHF)', 'Catégorie'],
      ['Risotto aux asperges', 'Riz Arborio', 320, 'g', 0.012, 'Féculents'],
      ['Risotto aux asperges', 'Asperges vertes', 400, 'g', 0.018, 'Légumes'],
      ['Risotto aux asperges', 'Parmesan', 80, 'g', 0.045, 'Produits laitiers'],
      ['Risotto aux asperges', 'Bouillon de légumes', 1000, 'ml', 0.004, 'Autres'],
      ['Mousse au chocolat', 'Chocolat noir 70%', 200, 'g', 0.025, 'Autres'],
      ['Mousse au chocolat', 'Œufs', 4, 'pcs', 0.50, 'Autres'],
      ['Mousse au chocolat', 'Crème entière', 250, 'ml', 0.006, 'Produits laitiers'],
    ];
    const wsIng = XLSX.utils.aoa_to_sheet(ingredientsRows);
    wsIng['!cols'] = [{ wch: 30 }, { wch: 28 }, { wch: 10 }, { wch: 8 }, { wch: 20 }, { wch: 20 }];
    XLSX.utils.book_append_sheet(wb, wsIng, 'Ingrédients');

    // Feuille 3 : Étapes (liées par "Nom de la recette" avec ordre)
    const etapesRows = [
      ['Nom de la recette', 'Ordre', 'Description'],
      ['Risotto aux asperges', 1, 'Faire revenir l\'oignon dans l\'huile d\'olive'],
      ['Risotto aux asperges', 2, 'Ajouter le riz et nacrer pendant 2 minutes'],
      ['Risotto aux asperges', 3, 'Déglacer au vin blanc puis ajouter le bouillon louche par louche'],
      ['Risotto aux asperges', 4, 'Incorporer les asperges en fin de cuisson'],
      ['Risotto aux asperges', 5, 'Ajouter le parmesan hors du feu et rectifier l\'assaisonnement'],
      ['Mousse au chocolat', 1, 'Faire fondre le chocolat au bain-marie'],
      ['Mousse au chocolat', 2, 'Séparer les blancs des jaunes'],
      ['Mousse au chocolat', 3, 'Incorporer les jaunes au chocolat fondu'],
      ['Mousse au chocolat', 4, 'Monter les blancs en neige ferme'],
      ['Mousse au chocolat', 5, 'Incorporer délicatement les blancs au mélange chocolaté'],
      ['Mousse au chocolat', 6, 'Réfrigérer 4h minimum'],
    ];
    const wsEtapes = XLSX.utils.aoa_to_sheet(etapesRows);
    wsEtapes['!cols'] = [{ wch: 30 }, { wch: 8 }, { wch: 60 }];
    XLSX.utils.book_append_sheet(wb, wsEtapes, 'Étapes');

    // Feuille 4 : Instructions
    const instrRows = [
      ['Instructions d\'utilisation du template'],
      [''],
      ['1. Remplissez la feuille "Recettes" : une ligne = une recette'],
      ['2. Dans "Ingrédients", utilisez exactement le même "Nom de la recette" pour lier les ingrédients'],
      ['3. Dans "Étapes", idem — numérotez l\'ordre des étapes'],
      ['4. Catégories acceptées : Entrées, Plats, Desserts, Fromages, Sauces, Fonds, Amuse-bouches, Garnitures'],
      ['5. Allergènes acceptés (séparés par ;) : gluten, lactose, oeufs, poissons, crustaces, fruits_coque, sulfites, arachides, soja, celeri, moutarde, sesame, mollusques, lupin'],
      ['6. Unités acceptées : g, kg, ml, L, pcs, cs, cc, pincée'],
      ['7. Importez ensuite le fichier via le bouton "Importer XLSX" dans Outils consultant'],
      [''],
      ['Les recettes importées seront ajoutées à l\'établissement courant en tant que brouillons.'],
    ];
    const wsInstr = XLSX.utils.aoa_to_sheet(instrRows);
    wsInstr['!cols'] = [{ wch: 90 }];
    XLSX.utils.book_append_sheet(wb, wsInstr, 'Instructions');

    XLSX.writeFile(wb, 'template-recettes-samper.xlsx');
  };

  // Parser pour fiche recette unique (format Samper interne)
  // Détection des sections par mots-clés : "Produit :", "Ingrédients :", "Étapes", "Astuce"
  const parseFicheUnique = (rows) => {
    // Extraire toutes les lignes [col1, col2] en ignorant les colonnes vides en début
    const lines = rows.map(r => {
      // Trouver les 2 premières cellules non-null
      const cells = (r || []).filter(c => c !== null && c !== undefined && String(c).trim() !== '');
      return cells;
    }).filter(cells => cells.length > 0);


    if (lines.length === 0) return null;

    // Ligne 1 : "Fiche Recette – Chaud/Froid/Dessert..."
    const headerStr = String(lines[0][0] || '').toLowerCase();
    let categorie = 'Plats';
    if (/froid|entr/i.test(headerStr)) categorie = 'Entrées';
    else if (/dessert|sucr/i.test(headerStr)) categorie = 'Desserts';
    else if (/fromage/i.test(headerStr)) categorie = 'Fromages';

    // Trouver nom : "Produit :" > "Plat :" > fallback
    let nom = '';
    let platParent = '';
    for (const l of lines) {
      const label = String(l[0] || '').toLowerCase().replace(/[:\s]+$/, '').trim();
      const val = String(l[1] || '').trim();
      if (label === 'produit' && val) nom = val;
      if (label === 'plat' && val) platParent = val;
    }
    if (!nom && platParent) nom = platParent;
    if (!nom) nom = 'Recette importée';

    // Trouver portions : ligne qui contient "X portions"
    let portions = 4;
    for (const l of lines) {
      const txt = l.join(' ').toLowerCase();
      const m = txt.match(/(\d+)\s*portions?/i);
      if (m) { portions = parseInt(m[1]) || 4; break; }
    }

    // Parse des sections : on itère ligne par ligne en gérant les états
    const ingredients = [];
    const etapes = [];
    let notesConsultant = '';
    let section = null; // null | 'ingredients' | 'etapes' | 'astuce'

    for (const l of lines) {
      const col1 = String(l[0] || '').trim();
      const col1Low = col1.toLowerCase();
      const col2 = l[1] !== undefined ? String(l[1]).trim() : '';

      // Détection des sections
      if (/^ingr[\u00e9e]dients?\s*:?/i.test(col1)) { section = 'ingredients'; continue; }
      if (/^[\u00e9e]tapes?\b/i.test(col1)) { section = 'etapes'; continue; }
      if (/^astuce/i.test(col1)) { section = 'astuce'; continue; }
      // Sections à ignorer une fois rencontrées (déjà lues via "Produit :" / "Plat :")
      if (['produit', 'plat', 'fiche recette', 'portions'].some(k => col1Low.startsWith(k))) continue;
      if (/^\d+\s*portions?$/i.test(col1)) continue;

      if (section === 'ingredients') {
        // Une ligne d'ingrédient : col1 = nom, col2 = quantité (ex "300 g", "1 L", "4 g")
        if (!col1) continue;
        const produit = col1;
        let quantite = 0, unite = 'g';
        if (col2) {
          // Parser "300 g" ou "1 L" ou "3kg" ou "1.5 L"
          const m = col2.match(/^([\d,.]+)\s*(.*)$/);
          if (m) {
            quantite = parseFloat(m[1].replace(',', '.')) || 0;
            unite = (m[2] || 'g').trim().toLowerCase();
            // Normaliser quelques unités courantes
            if (unite === 'kg') { quantite *= 1000; unite = 'g'; }
            else if (unite === 'l') { quantite *= 1000; unite = 'ml'; }
            else if (unite === 'cl') { quantite *= 10; unite = 'ml'; }
            else if (!['g', 'ml', 'pcs', 'cs', 'cc', 'tsp', 'tbsp', 'btl'].includes(unite)) unite = 'g';
          }
        }
        ingredients.push({
          id: 'i-' + Date.now() + '-' + ingredients.length,
          nom: produit,
          quantite,
          unite,
          prixUnit: 0,
          categorie: 'Autres',
        });
      } else if (section === 'etapes') {
        // Une étape : col1 est le texte. Si se termine par ":" c'est un sous-titre de section
        if (!col1) continue;
        etapes.push(col1);
      } else if (section === 'astuce') {
        if (col1) notesConsultant += (notesConsultant ? '\n' : '') + col1;
      }
    }


    return {
      nom,
      categorie,
      portions,
      prixVente: 0,
      tempsPreparation: 0,
      tempsCuisson: 0,
      tempsTotal: 0,
      statut: 'brouillon',
      version: 1,
      allergenesIds: [],
      notesConsultant: notesConsultant + (platParent && platParent !== nom ? (notesConsultant ? '\n\n' : '') + 'Accompagne : ' + platParent : ''),
      modifie: new Date().toISOString().slice(0, 10),
      ingredients,
      etapes,
      dressage: '',
      conservation: '',
    };
  };

  const handleImportXLSX = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    if (typeof XLSX === 'undefined') { alert('Bibliothèque XLSX non chargée.'); return; }

    const reader = new FileReader();
    reader.onload = async (evt) => {
      try {
        const data = new Uint8Array(evt.target.result);
        const wb = XLSX.read(data, { type: 'array' });

        // ─── DÉTECTION AUTOMATIQUE DU FORMAT ───
        // Format 1 (multi-recettes) : feuilles "Recettes", "Ingrédients", "Étapes"
        // Format 2 (fiche unique) : première cellule = "Fiche Recette – ..."
        const hasMultiFormat = wb.Sheets['Recettes'] || wb.SheetNames.some(n => n.toLowerCase().includes('recettes'));
        const firstSheet = wb.Sheets[wb.SheetNames[0]];
        const firstRows = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
        const firstCellText = String(firstRows?.[0]?.[1] || firstRows?.[0]?.[0] || '').trim();
        const isFicheUnique = /^fiche\s*recette/i.test(firstCellText);

        if (isFicheUnique) {
          // ═══ FORMAT FICHE UNIQUE (ex: "Sauce_vin_blanc_xérès.xlsx") ═══
          const recette = parseFicheUnique(firstRows);
          if (!recette) { alert('Impossible de parser cette fiche. Vérifiez le format.'); return; }
          recette.id = 'rec-' + Date.now();
          recette.etablissementId = etabId;
          recette.modifiePar = user.id;

          setRecettes(prev => [recette, ...prev]);
          setSelectedId(recette.id);

          if (window.SB) {
            try { await window.SB.db.upsertRecette(recette); }
            catch (err) { alert(`⚠ Recette créée localement mais erreur sync : ${err.message}`); return; }
          }
          alert(`✓ Recette "${recette.nom}" importée avec succès (${recette.ingredients.length} ingrédients, ${recette.etapes.length} étapes).`);
          return;
        }

        if (!hasMultiFormat) {
          alert('Format non reconnu.\n\nFormats acceptés :\n• Template multi-recettes (feuilles "Recettes" + "Ingrédients" + "Étapes")\n• Fiche unique commençant par "Fiche Recette – ..."');
          return;
        }

        // ═══ FORMAT MULTI-RECETTES (template original) ═══
        const shRec = wb.Sheets['Recettes'] || wb.Sheets[wb.SheetNames[0]];
        const shIng = wb.Sheets['Ingrédients'] || wb.Sheets['Ingredients'];
        const shEt = wb.Sheets['Étapes'] || wb.Sheets['Etapes'];

        if (!shRec) { alert('Feuille "Recettes" introuvable.'); return; }
        const rowsRec = XLSX.utils.sheet_to_json(shRec, { header: 1 });
        const rowsIng = shIng ? XLSX.utils.sheet_to_json(shIng, { header: 1 }) : [];
        const rowsEt = shEt ? XLSX.utils.sheet_to_json(shEt, { header: 1 }) : [];

        // Sauter l'en-tête
        const imported = [];
        for (let i = 1; i < rowsRec.length; i++) {
          const row = rowsRec[i];
          if (!row || !row[0]) continue;
          const nom = String(row[0]).trim();
          if (!nom) continue;

          const recette = {
            id: 'rec-' + Date.now() + '-' + i,
            etablissementId: etabId,
            nom,
            categorie: String(row[1] || 'Plats').trim(),
            portions: parseInt(row[2]) || 4,
            prixVente: parseFloat(row[3]) || 0,
            tempsPreparation: parseInt(row[4]) || 0,
            tempsCuisson: parseInt(row[5]) || 0,
            tempsTotal: (parseInt(row[4]) || 0) + (parseInt(row[5]) || 0),
            allergenesIds: row[6] ? String(row[6]).split(';').map(s => s.trim()).filter(Boolean) : [],
            notesConsultant: String(row[7] || '').trim(),
            statut: 'brouillon',
            version: 1,
            modifie: new Date().toISOString().slice(0, 10),
            modifiePar: user.id,
            dressage: '',
            conservation: '',
            ingredients: [],
            etapes: [],
          };

          // Ingrédients liés
          for (let j = 1; j < rowsIng.length; j++) {
            const r = rowsIng[j];
            if (!r || !r[0]) continue;
            if (String(r[0]).trim() === nom) {
              recette.ingredients.push({
                id: 'i' + Date.now() + '_' + i + '_' + j,
                nom: String(r[1] || '').trim(),
                quantite: parseFloat(r[2]) || 0,
                unite: String(r[3] || 'g').trim(),
                prixUnit: parseFloat(r[4]) || 0,
                categorie: String(r[5] || 'Autres').trim(),
              });
            }
          }

          // Étapes liées (triées par ordre)
          const etapesOf = [];
          for (let j = 1; j < rowsEt.length; j++) {
            const r = rowsEt[j];
            if (!r || !r[0]) continue;
            if (String(r[0]).trim() === nom) {
              etapesOf.push({ ordre: parseInt(r[1]) || 999, desc: String(r[2] || '').trim() });
            }
          }
          etapesOf.sort((a, b) => a.ordre - b.ordre);
          recette.etapes = etapesOf.map(e => e.desc).filter(Boolean);

          imported.push(recette);
        }

        if (imported.length === 0) { alert('Aucune recette valide trouvée dans le fichier.'); return; }
        setRecettes(prev => [...imported, ...prev]);
        setSelectedId(imported[0].id);

        // Push vers Supabase si configuré
        if (window.SB) {
          try {
            for (const rec of imported) {
              await window.SB.db.upsertRecette(rec);
            }
          } catch (err) {
            alert(`⚠ Import réussi localement mais erreur de synchronisation : ${err.message}`);
            return;
          }
        }

        alert(`✓ ${imported.length} recette${imported.length > 1 ? 's' : ''} importée${imported.length > 1 ? 's' : ''} avec succès.`);
      } catch (err) {
        console.error(err);
        alert('Erreur lors de l\'import : ' + err.message);
      }
    };
    reader.readAsArrayBuffer(file);
    e.target.value = ''; // reset input
  };

  // ── Actions ingrédients
  const addIngredient = () => {
    if (!selected) return;
    const newIng = { id: 'i' + Date.now(), nom: '', quantite: 0, unite: 'g', prixUnit: 0, categorie: 'Autres' };
    updateSelected({ ingredients: [...selected.ingredients, newIng] });
  };

  const updateIngredient = (idx, field, value) => {
    const updated = [...selected.ingredients];
    updated[idx] = { ...updated[idx], [field]: value };
    updateSelected({ ingredients: updated });
  };

  const removeIngredient = (idx) => {
    const updated = selected.ingredients.filter((_, i) => i !== idx);
    updateSelected({ ingredients: updated });
  };

  // ── Actions étapes
  const addEtape = () => {
    if (!selected) return;
    updateSelected({ etapes: [...selected.etapes, ''] });
  };

  const updateEtape = (idx, value) => {
    const updated = [...selected.etapes];
    updated[idx] = value;
    updateSelected({ etapes: updated });
  };

  const removeEtape = (idx) => {
    updateSelected({ etapes: selected.etapes.filter((_, i) => i !== idx) });
  };

  const moveEtape = (idx, direction) => {
    const updated = [...selected.etapes];
    const newIdx = idx + direction;
    if (newIdx < 0 || newIdx >= updated.length) return;
    [updated[idx], updated[newIdx]] = [updated[newIdx], updated[idx]];
    updateSelected({ etapes: updated });
  };

  // ── Allergènes toggle
  const toggleAllergene = (aid) => {
    const current = selected.allergenesIds || [];
    const next = current.includes(aid) ? current.filter(a => a !== aid) : [...current, aid];
    updateSelected({ allergenesIds: next });
  };

  // ── Calculs dérivés pour affichage live
  const coutMatiere = selected ? (selected.ingredients || []).reduce((s, i) => s + (Number(i.quantite) || 0) * (Number(i.prixUnit) || 0), 0) : 0;
  const coutPortion = selected && selected.portions ? coutMatiere / selected.portions : 0;
  const foodCost = selected && selected.prixVente ? (coutPortion / selected.prixVente * 100) : null;
  const margeBrute = selected && selected.prixVente ? selected.prixVente - coutPortion : 0;
  const tempsTotal = selected ? (Number(selected.tempsPreparation) || 0) + (Number(selected.tempsCuisson) || 0) : 0;

  return (
    <div style={cts.root}>
      {/* Colonne gauche : liste */}
      <div style={cts.leftCol} className="no-print">
        <div style={cts.leftHeader}>
          <button style={cts.newBtn} onClick={createNew}>+ Nouvelle recette</button>
          <input
            style={cts.search}
            placeholder="Rechercher…"
            value={search}
            onChange={e => setSearch(e.target.value)}
          />
          <div style={{display:'flex', gap:6, marginTop:8}}>
            <button style={{...cts.ghostBtn, flex:1, fontSize:11, padding:'6px 8px'}} onClick={downloadTemplate}>📄 Template XLSX</button>
            <label style={{...cts.ghostBtn, flex:1, fontSize:11, padding:'6px 8px', textAlign:'center', cursor:'pointer'}}>
              📥 Importer XLSX
              <input type="file" accept=".xlsx,.xls" style={{display:'none'}} onChange={handleImportXLSX}/>
            </label>
          </div>
        </div>
        <div style={cts.leftList}>
          {filtered.length === 0 && (
            <div style={{padding: 16, fontSize: 12, color: 'var(--text2)'}}>Aucune recette.</div>
          )}
          {filtered.map(r => (
            <div
              key={r.id}
              style={{ ...cts.recetteItem, ...(selectedId === r.id ? cts.recetteItemActive : {}) }}
              onClick={() => setSelectedId(r.id)}
            >
              <div style={cts.recItemName}>{r.nom}</div>
              <div style={cts.recItemMeta}>
                {r.categorie} · {r.portions || '?'} p. · v{r.version || 1}
                {r.foodCost && (
                  <span style={{ marginLeft: 6, color: r.foodCost < 30 ? '#16a34a' : r.foodCost < 35 ? '#d97706' : '#dc2626', fontWeight: 600 }}>
                    {' '}FC {r.foodCost.toFixed(1)}%
                  </span>
                )}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Colonne droite : éditeur */}
      {!selected ? (
        <div style={cts.emptyState}>
          <div style={{ fontSize: 40, opacity: 0.4 }}>📖</div>
          <div style={{ fontSize: 16, fontWeight: 600, color: 'var(--text)', fontFamily: 'var(--font-serif)' }}>Aucune recette sélectionnée</div>
          <div style={{ fontSize: 13, color: 'var(--text2)' }}>Créez une nouvelle recette ou sélectionnez-en une dans la liste.</div>
          <button style={cts.newBtn} onClick={createNew}>+ Nouvelle recette</button>
        </div>
      ) : (
        <div style={cts.rightCol}>
          {/* Actions bar */}
          <div style={cts.actionBar} className="no-print">
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              <button style={cts.ghostBtn} onClick={duplicate}>⧉ Dupliquer</button>
              <button style={{...cts.ghostBtn, color: '#dc2626', borderColor: '#fca5a5'}} onClick={() => setShowDeleteConfirm(true)}>🗑 Supprimer</button>
            </div>
            <div style={{ flex: 1 }} />
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              <button style={cts.ghostBtn} onClick={() => PDFUtils.printElement('consultant-recette-print', 'Fiche recette ' + selected.nom)}>🖨 Imprimer</button>
              <button style={cts.ghostBtn} onClick={() => PDFUtils.exportElementToPdf('consultant-recette-print', `recette-${selected.nom.replace(/[^a-z0-9]/gi,'_')}.pdf`)}>⬇ Export PDF</button>
            </div>
          </div>

          <div id="consultant-recette-print" style={cts.printZone}>
            {/* Header édition */}
            <div style={cts.header}>
              <div style={{flex: 1}}>
                <input
                  type="text"
                  value={selected.nom}
                  onChange={e => updateSelected({ nom: e.target.value })}
                  style={cts.titleInput}
                  placeholder="Nom de la recette"
                />
                <div style={{display: 'flex', gap: 14, marginTop: 8, alignItems: 'center', flexWrap: 'wrap'}}>
                  <div style={cts.inlineField}>
                    <label>Catégorie</label>
                    <select value={selected.categorie || 'Plats'} onChange={e => updateSelected({ categorie: e.target.value })} style={cts.inlineInput}>
                      {CATEGORIES_REC.map(c => <option key={c} value={c}>{c}</option>)}
                    </select>
                  </div>
                  <div style={cts.inlineField}>
                    <label>Statut</label>
                    <select value={selected.statut || 'brouillon'} onChange={e => updateSelected({ statut: e.target.value })} style={cts.inlineInput}>
                      <option value="brouillon">Brouillon</option>
                      <option value="active">Active</option>
                      <option value="archivée">Archivée</option>
                    </select>
                  </div>
                  <div style={cts.inlineField}>
                    <label>Version</label>
                    <input type="number" min="1" value={selected.version || 1} onChange={e => updateSelected({ version: Number(e.target.value) })} style={{...cts.inlineInput, width: 60}} />
                  </div>
                  <div style={{...cts.inlineField, marginLeft:'auto'}}>
                    <label style={{fontSize:11, fontWeight:600, color:'#15803d'}}>Publier sur la carte active</label>
                    <label style={{display:'flex', alignItems:'center', gap:8, cursor:'pointer', padding:'6px 10px', background: isRecetteActive(selected) ? '#dcfce7' : '#f3f4f6', border:'1px solid', borderColor: isRecetteActive(selected) ? '#86efac' : 'var(--border)', borderRadius:8}}>
                      <input type="checkbox"
                        checked={isRecetteActive(selected)}
                        onChange={e => toggleActifSurCarte(selected, e.target.checked)}
                        style={{accentColor:'#15803d'}}/>
                      <span style={{fontSize:12, fontWeight:600, color: isRecetteActive(selected) ? '#15803d' : 'var(--text2)'}}>
                        {isRecetteActive(selected) ? '✓ Visible sur la carte' : 'Non publiée'}
                      </span>
                    </label>
                  </div>
                </div>
              </div>
            </div>

            {/* Grille principale */}
            <div style={cts.grid}>
              {/* Bloc paramètres */}
              <div style={cts.card}>
                <div style={cts.cardTitle}>Paramètres</div>
                <div style={cts.paramGrid}>
                  <div style={cts.field}>
                    <label style={cts.label}>Portions</label>
                    <input type="number" min="1" value={selected.portions || 1} onChange={e => updateSelected({ portions: Number(e.target.value) })} style={cts.input} />
                  </div>
                  <div style={cts.field}>
                    <label style={cts.label}>Prix vente (CHF)</label>
                    <input type="number" min="0" step="0.10" value={selected.prixVente || 0} onChange={e => updateSelected({ prixVente: Number(e.target.value) })} style={cts.input} />
                  </div>
                  <div style={cts.field}>
                    <label style={cts.label}>Temps prépa (min)</label>
                    <input type="number" min="0" value={selected.tempsPreparation || 0} onChange={e => updateSelected({ tempsPreparation: Number(e.target.value) })} style={cts.input} />
                  </div>
                  <div style={cts.field}>
                    <label style={cts.label}>Temps cuisson (min)</label>
                    <input type="number" min="0" value={selected.tempsCuisson || 0} onChange={e => updateSelected({ tempsCuisson: Number(e.target.value) })} style={cts.input} />
                  </div>
                  <div style={cts.field}>
                    <label style={cts.label}>Temps total (auto)</label>
                    <input type="text" value={`${tempsTotal} min`} disabled style={{ ...cts.input, background: 'var(--bg)', color: 'var(--accent)', fontWeight: 700 }} />
                  </div>
                </div>
              </div>

              {/* Bloc analyse économique */}
              <div style={cts.card}>
                <div style={cts.cardTitle}>Analyse économique</div>
                <div style={cts.kpiGrid}>
                  <div style={cts.kpiItem}>
                    <span style={cts.kpiLabel}>Coût matière total</span>
                    <strong style={{ color: 'var(--text)' }}>CHF {coutMatiere.toFixed(2)}</strong>
                  </div>
                  <div style={cts.kpiItem}>
                    <span style={cts.kpiLabel}>Coût par portion</span>
                    <strong style={{ color: 'var(--accent)' }}>CHF {coutPortion.toFixed(2)}</strong>
                  </div>
                  <div style={cts.kpiItem}>
                    <span style={cts.kpiLabel}>Food cost %</span>
                    <strong style={{ color: foodCost == null ? 'var(--text2)' : foodCost < 30 ? '#16a34a' : foodCost < 35 ? '#d97706' : '#dc2626' }}>
                      {foodCost == null ? '—' : foodCost.toFixed(1) + ' %'}
                    </strong>
                  </div>
                  <div style={cts.kpiItem}>
                    <span style={cts.kpiLabel}>Marge brute / portion</span>
                    <strong style={{ color: margeBrute >= 0 ? '#16a34a' : '#dc2626' }}>CHF {margeBrute.toFixed(2)}</strong>
                  </div>
                </div>
              </div>

              {/* Allergènes */}
              <div style={{...cts.card, gridColumn: '1/-1'}}>
                <div style={cts.cardTitle}>Allergènes</div>
                <div style={{ padding: 14, display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                  {ALLERGENES_OPTIONS.map(a => {
                    const active = (selected.allergenesIds || []).includes(a.id);
                    return (
                      <button
                        key={a.id}
                        onClick={() => toggleAllergene(a.id)}
                        style={{
                          padding: '5px 12px',
                          borderRadius: 20,
                          border: active ? '1px solid #d97706' : '1px solid var(--border)',
                          background: active ? '#fef3c7' : 'var(--surface)',
                          color: active ? '#92400e' : 'var(--text2)',
                          fontSize: 12,
                          fontWeight: active ? 700 : 500,
                          cursor: 'pointer',
                          fontFamily: 'var(--font)'
                        }}
                      >
                        {active ? '✓ ' : '+ '}{a.label}
                      </button>
                    );
                  })}
                </div>
              </div>

              {/* Ingrédients */}
              <div style={{...cts.card, gridColumn: '1/-1'}}>
                <div style={{...cts.cardTitle, display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
                  <span>Ingrédients ({selected.ingredients.length})</span>
                  <button style={cts.smallBtn} onClick={addIngredient}>+ Ingrédient</button>
                </div>
                <div style={{padding: 14}}>
                  <div style={cts.ingHead}>
                    <span>Nom</span>
                    <span>Qté</span>
                    <span>Unité</span>
                    <span>Prix / unité</span>
                    <span>Coût</span>
                    <span></span>
                  </div>
                  {selected.ingredients.length === 0 && (
                    <div style={{ padding: '12px 0', fontSize: 13, color: 'var(--text2)', fontStyle: 'italic' }}>
                      Aucun ingrédient. Cliquez sur "+ Ingrédient" pour commencer.
                    </div>
                  )}
                  {selected.ingredients.map((ing, idx) => (
                    <div key={ing.id} style={cts.ingRow}>
                      <input type="text" value={ing.nom} onChange={e => updateIngredient(idx, 'nom', e.target.value)} placeholder="Ingrédient" style={cts.ingInput} />
                      <input type="number" min="0" step="0.01" value={ing.quantite} onChange={e => updateIngredient(idx, 'quantite', Number(e.target.value))} style={cts.ingInput} />
                      <select value={ing.unite} onChange={e => updateIngredient(idx, 'unite', e.target.value)} style={cts.ingInput}>
                        {UNITES_REC.map(u => <option key={u} value={u}>{u}</option>)}
                      </select>
                      <input type="number" min="0" step="0.001" value={ing.prixUnit} onChange={e => updateIngredient(idx, 'prixUnit', Number(e.target.value))} style={cts.ingInput} />
                      <span style={{fontSize: 13, fontWeight: 600, color: 'var(--text)', alignSelf: 'center'}}>
                        CHF {((Number(ing.quantite) || 0) * (Number(ing.prixUnit) || 0)).toFixed(2)}
                      </span>
                      <button onClick={() => removeIngredient(idx)} style={cts.deleteLineBtn} title="Supprimer">✕</button>
                    </div>
                  ))}
                </div>
              </div>

              {/* Étapes */}
              <div style={{...cts.card, gridColumn: '1/-1'}}>
                <div style={{...cts.cardTitle, display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
                  <span>Étapes de préparation ({selected.etapes.length})</span>
                  <button style={cts.smallBtn} onClick={addEtape}>+ Étape</button>
                </div>
                <div style={{padding: 14}}>
                  {selected.etapes.length === 0 && (
                    <div style={{ padding: '12px 0', fontSize: 13, color: 'var(--text2)', fontStyle: 'italic' }}>
                      Aucune étape. Cliquez sur "+ Étape" pour détailler la préparation.
                    </div>
                  )}
                  {selected.etapes.map((etape, idx) => (
                    <div key={idx} style={cts.etapeRow}>
                      <div style={cts.etapeNum}>{idx + 1}</div>
                      <textarea
                        value={etape}
                        onChange={e => updateEtape(idx, e.target.value)}
                        placeholder="Décrire l'étape…"
                        rows={2}
                        style={cts.etapeInput}
                      />
                      <div style={{display: 'flex', flexDirection: 'column', gap: 4}}>
                        <button onClick={() => moveEtape(idx, -1)} disabled={idx === 0} style={cts.moveBtn} title="Monter">▲</button>
                        <button onClick={() => moveEtape(idx, 1)} disabled={idx === selected.etapes.length - 1} style={cts.moveBtn} title="Descendre">▼</button>
                      </div>
                      <button onClick={() => removeEtape(idx)} style={cts.deleteLineBtn} title="Supprimer">✕</button>
                    </div>
                  ))}
                </div>
              </div>

              {/* Notes & dressage */}
              <div style={cts.card}>
                <div style={cts.cardTitle}>Notes du consultant</div>
                <div style={{padding: 14}}>
                  <textarea
                    value={selected.notesConsultant || ''}
                    onChange={e => updateSelected({ notesConsultant: e.target.value })}
                    placeholder="Conseils techniques, points d'attention, tours de main…"
                    rows={5}
                    style={cts.textarea}
                  />
                </div>
              </div>
              <div style={cts.card}>
                <div style={cts.cardTitle}>Dressage & conservation</div>
                <div style={{padding: 14, display: 'flex', flexDirection: 'column', gap: 10}}>
                  <div>
                    <label style={cts.label}>Dressage</label>
                    <textarea
                      value={selected.dressage || ''}
                      onChange={e => updateSelected({ dressage: e.target.value })}
                      placeholder="Présentation de l'assiette…"
                      rows={2}
                      style={cts.textarea}
                    />
                  </div>
                  <div>
                    <label style={cts.label}>Conservation</label>
                    <textarea
                      value={selected.conservation || ''}
                      onChange={e => updateSelected({ conservation: e.target.value })}
                      placeholder="Durée, température, conditionnement…"
                      rows={2}
                      style={cts.textarea}
                    />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Modale suppression */}
      {showDeleteConfirm && (
        <div style={cts.overlay} onClick={() => setShowDeleteConfirm(false)}>
          <div style={cts.modal} onClick={e => e.stopPropagation()}>
            <div style={{padding: 20}}>
              <div style={{fontWeight: 700, fontSize: 16, fontFamily: 'var(--font-serif)', marginBottom: 10}}>Supprimer cette recette ?</div>
              <div style={{fontSize: 13, color: 'var(--text2)', marginBottom: 18}}>Vous êtes sur le point de supprimer <strong>{selected?.nom}</strong>. Cette action est irréversible.</div>
              <div style={{display: 'flex', gap: 8, justifyContent: 'flex-end'}}>
                <button style={cts.ghostBtn} onClick={() => setShowDeleteConfirm(false)}>Annuler</button>
                <button style={{...cts.newBtn, background: '#dc2626'}} onClick={deleteRecette}>Supprimer</button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

const cts = {
  root: { display: 'grid', gridTemplateColumns: '280px 1fr', gap: 16, height: 'calc(100vh - 120px)', minHeight: 600 },
  leftCol: { display: 'flex', flexDirection: 'column', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 12, overflow: 'hidden' },
  leftHeader: { padding: 12, borderBottom: '1px solid var(--border)', display: 'flex', flexDirection: 'column', gap: 8 },
  newBtn: { padding: '9px 14px', background: 'var(--accent)', color: '#fff', border: 'none', borderRadius: 8, fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: 'var(--font)' },
  search: { padding: '8px 12px', border: '1px solid var(--border)', borderRadius: 8, fontSize: 13, color: 'var(--text)', background: 'var(--bg)', fontFamily: 'var(--font)', outline: 'none' },
  leftList: { flex: 1, overflowY: 'auto' },
  recetteItem: { padding: '11px 14px', borderBottom: '1px solid var(--border)', cursor: 'pointer', transition: 'background .12s' },
  recetteItemActive: { background: 'var(--accent-light)', borderLeft: '3px solid var(--accent)' },
  recItemName: { fontSize: 13, fontWeight: 600, color: 'var(--text)', marginBottom: 3 },
  recItemMeta: { fontSize: 11, color: 'var(--text2)' },
  rightCol: { display: 'flex', flexDirection: 'column', gap: 16, overflowY: 'auto', paddingRight: 4 },
  emptyState: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 12, padding: 40, background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 12 },
  actionBar: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' },
  ghostBtn: { padding: '7px 14px', background: 'var(--surface)', border: '1px solid var(--border)', color: 'var(--text2)', borderRadius: 8, fontSize: 13, cursor: 'pointer', fontFamily: 'var(--font)' },
  printZone: { display: 'flex', flexDirection: 'column', gap: 16, background: 'transparent' },
  header: { background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 12, padding: '18px 22px' },
  titleInput: { width: '100%', fontSize: 22, fontWeight: 700, color: 'var(--text)', fontFamily: 'var(--font-serif)', border: 'none', background: 'transparent', outline: 'none', padding: 0 },
  inlineField: { display: 'flex', flexDirection: 'column', gap: 3 },
  inlineInput: { padding: '5px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: 12, background: 'var(--bg)', fontFamily: 'var(--font)', color: 'var(--text)' },
  grid: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 },
  card: { background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 12, overflow: 'hidden' },
  cardTitle: { padding: '12px 16px', borderBottom: '1px solid var(--border)', background: 'var(--bg)', fontSize: 12, fontWeight: 700, color: 'var(--text)', textTransform: 'uppercase', letterSpacing: 0.4 },
  paramGrid: { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: 12, padding: 14 },
  field: { display: 'flex', flexDirection: 'column', gap: 4 },
  label: { fontSize: 11, fontWeight: 600, color: 'var(--text2)', textTransform: 'uppercase', letterSpacing: 0.4 },
  input: { padding: '8px 12px', border: '1px solid var(--border)', borderRadius: 8, fontSize: 13, color: 'var(--text)', background: 'var(--bg)', fontFamily: 'var(--font)', outline: 'none', boxSizing: 'border-box', width: '100%' },
  kpiGrid: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, padding: 14 },
  kpiItem: { display: 'flex', flexDirection: 'column', gap: 4, padding: 10, background: 'var(--bg)', borderRadius: 8 },
  kpiLabel: { fontSize: 11, color: 'var(--text2)', fontWeight: 500 },
  smallBtn: { padding: '5px 12px', background: 'var(--accent)', color: '#fff', border: 'none', borderRadius: 6, fontSize: 12, fontWeight: 600, cursor: 'pointer', fontFamily: 'var(--font)' },
  ingHead: { display: 'grid', gridTemplateColumns: '2fr 80px 90px 110px 90px 32px', gap: 8, padding: '6px 0', borderBottom: '1px solid var(--border)', fontSize: 10, fontWeight: 700, color: 'var(--text2)', textTransform: 'uppercase', letterSpacing: 0.4 },
  ingRow: { display: 'grid', gridTemplateColumns: '2fr 80px 90px 110px 90px 32px', gap: 8, padding: '6px 0', alignItems: 'center' },
  ingInput: { padding: '6px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: 12, color: 'var(--text)', background: 'var(--bg)', fontFamily: 'var(--font)', outline: 'none', width: '100%', boxSizing: 'border-box' },
  deleteLineBtn: { width: 28, height: 28, border: '1px solid #fca5a5', background: 'none', color: '#dc2626', borderRadius: 6, cursor: 'pointer', fontSize: 13, padding: 0 },
  etapeRow: { display: 'flex', gap: 10, alignItems: 'flex-start', marginBottom: 10 },
  etapeNum: { width: 28, height: 28, borderRadius: '50%', background: 'var(--accent)', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, fontWeight: 700, flexShrink: 0, marginTop: 2 },
  etapeInput: { flex: 1, padding: '8px 12px', border: '1px solid var(--border)', borderRadius: 8, fontSize: 13, color: 'var(--text)', background: 'var(--bg)', fontFamily: 'var(--font)', outline: 'none', resize: 'vertical', lineHeight: 1.5 },
  moveBtn: { width: 22, height: 22, border: '1px solid var(--border)', background: 'var(--surface)', color: 'var(--text2)', borderRadius: 4, cursor: 'pointer', fontSize: 10, padding: 0 },
  textarea: { width: '100%', padding: '8px 12px', border: '1px solid var(--border)', borderRadius: 8, fontSize: 13, color: 'var(--text)', background: 'var(--bg)', fontFamily: 'var(--font)', outline: 'none', resize: 'vertical', boxSizing: 'border-box', lineHeight: 1.5 },
  overlay: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1000 },
  modal: { background: 'var(--surface)', borderRadius: 14, width: 420, maxWidth: '90vw', boxShadow: '0 20px 60px rgba(0,0,0,0.2)' },
};

// Responsive (mobile)
if (typeof window !== 'undefined' && window.innerWidth < 900) {
  cts.root = { ...cts.root, gridTemplateColumns: '1fr', height: 'auto' };
  cts.grid = { ...cts.grid, gridTemplateColumns: '1fr' };
}

Object.assign(window, { ConsultantTools });
