/* =========================================================================
   Nexus Autoparts — Public Catalog (catalog-public.js)
   Vehicle hierarchy navigation: Brand > Model > Year > Engine > Category > Group > Parts
   No auth, no cart, no prices — public browsing only.
   ========================================================================= */

(function () {
  'use strict';

  // ── State ──
  var state = {
    level: 'brands',       // brands | models | years | engines | categories | groups | part_types | parts | search
    brand: null,           // {id, name}
    model: null,           // {id, name}
    year: null,            // {id, value}
    engine: null,          // {id_mye, name, trim}

    // OEM mode (TecDoc) state — integer IDs
    category: null,        // {id, name}
    group: null,           // {id, name}
    partType: null,        // {slug, name} ← 3rd subcategory level

    // Local mode (Nexpart) state — string slugs. Parallel to the OEM state
    // so toggle switching mid-nav doesn't trash either branch.
    nxGroup: null,         // {slug, name} ← top-level Nexpart group
    nxSubgroup: null,      // {slug, name} ← Nexpart subgroup
    nxPartType: null,      // {slug, name} ← Nexpart part type

    region: 'north-america',
    mode: (localStorage.getItem('catalog_mode') === 'local' ? 'local' : 'oem'),
    page: 1,
    totalPages: 1,
  };

  // ── Catalog mode toggle (OEM / Local) ──
  function updateModeToggleUI() {
    document.querySelectorAll('#modeToggle button').forEach(function (b) {
      b.classList.toggle('is-active', b.getAttribute('data-mode') === state.mode);
    });
  }

  window.setCatalogMode = function (mode) {
    if (mode !== 'oem' && mode !== 'local') return;
    if (mode === state.mode) return;
    state.mode = mode;
    localStorage.setItem('catalog_mode', mode);
    updateModeToggleUI();

    // Smart reset: if vehicle already picked, stay at categories in the new mode.
    var hasVehicle = !!(state.engine && state.engine.id_mye);

    // Clear category-and-below state from BOTH branches
    state.category = state.group = state.partType = null;
    state.nxGroup = state.nxSubgroup = state.nxPartType = null;
    state.page = 1;

    if (hasVehicle) {
      state.level = 'categories';
      loadCategoriesForMode();
      return;
    }

    // No vehicle — full reset back to brand selection
    state.brand = state.model = state.year = state.engine = null;
    state.level = 'brands';
    loadBrands();
  };

  // ── Region selector (global) ──
  window.setRegion = function (region) {
    state.region = region;
    document.querySelectorAll('.region-btn').forEach(function (b) {
      b.classList.toggle('is-active', b.dataset.region === region);
    });
    // Reload brands with new region
    state.brand = state.model = state.year = state.engine = null;
    state.category = state.group = state.partType = null;
    state.nxGroup = state.nxSubgroup = state.nxPartType = null;
    loadBrands();
  };

  var API = '/api/catalog';
  var content = document.getElementById('content');
  var breadcrumbEl = document.getElementById('breadcrumb');
  var searchInput = document.getElementById('searchInput');

  // Check URL for brand param
  var urlParams = new URLSearchParams(window.location.search);
  var initBrandId = urlParams.get('brand');

  // ── Init ──
  updateModeToggleUI();
  if (initBrandId) {
    // Load brands, find the one matching, then navigate
    fetch(API + '/brands?mode=' + state.mode)
      .then(function (r) { return r.json(); })
      .then(function (brands) {
        var found = brands.find(function (b) { return b.id_brand == initBrandId; });
        if (found) {
          state.brand = { id: found.id_brand, name: found.name_brand };
          state.level = 'models';
          loadModels();
        } else {
          loadBrands();
        }
      })
      .catch(function () { loadBrands(); });
  } else {
    loadBrands();
  }

  // Enter on search
  // ── Smart search detector ──
  function detectQueryType(raw) {
    if (!raw) return 'keyword';
    var q = raw.trim();
    var compact = q.replace(/[\s\-]/g, '').toUpperCase();
    if (/^[A-HJ-NPR-Z0-9]{17}$/.test(compact)) return 'vin';
    if (/^[A-Z]{3}[-\s]?\d{3,4}$/.test(q.toUpperCase())) return 'plate';
    var hasLowercase = /[a-z]/.test(q);
    if (hasLowercase) return 'keyword';
    var tokens = q.split(/\s+/);
    var hasYear = tokens.some(function (t) { return /^(19|20)\d{2}$/.test(t); });
    if (hasYear && tokens.length > 1) return 'keyword';
    var qUpper = q.toUpperCase();
    if (/^[A-Z0-9]{2,}[\-\/][A-Z0-9]{2,}([\-\/][A-Z0-9]+)*$/.test(qUpper) && compact.length >= 6) return 'part_number';
    if (tokens.length >= 2 && tokens.every(function (t) { return /^[A-Z0-9]{1,}$/.test(t); }) && compact.length >= 6) return 'part_number';
    if (/^[A-Z0-9]{8,}$/.test(compact) && /[A-Z]/.test(compact) && /\d/.test(compact)) return 'part_number';
    return 'keyword';
  }

  // Smart search hint
  var searchHint = document.createElement('div');
  searchHint.style.cssText = 'display:none;padding:3px 10px;font-size:12px;color:var(--color-text-accent);background:var(--color-primary-muted);border:1px dashed var(--color-border-accent);border-radius:4px;margin-top:4px;';
  searchInput.parentElement.after(searchHint);

  searchInput.addEventListener('input', function () {
    var q = this.value.trim();
    if (q.length >= 3) {
      var type = detectQueryType(q);
      var hints = { vin: '🚗 VIN detectado', plate: '🔖 Placa detectada', part_number: '🔩 Numero de parte', keyword: null };
      if (hints[type]) { searchHint.textContent = hints[type]; searchHint.style.display = ''; }
      else { searchHint.style.display = 'none'; }
    } else {
      searchHint.style.display = 'none';
    }
  });

  searchInput.addEventListener('keydown', function (e) {
    if (e.key === 'Enter') doSearch();
  });

  // ── Theme toggle (global) ──
  window.toggleTheme = function () {
    var html = document.documentElement;
    var cur = html.getAttribute('data-theme');
    var next = cur === 'industrial' ? 'modern' : 'industrial';
    html.setAttribute('data-theme', next);
    localStorage.setItem('nexus-theme', next);
  };

  // ── Search (global) ──
  window.doSearch = function () {
    var q = searchInput.value.trim();
    if (!q || q.length < 2) return;
    state.level = 'search';
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Buscando...</div>';
    fetch(API + '/search?q=' + encodeURIComponent(q))
      .then(function (r) { return r.json(); })
      .then(function (data) { renderSearchResults(data); })
      .catch(function () { content.innerHTML = '<div class="empty">Error en la busqueda.</div>'; });
  };

  // ── Detail modal (global) ──
  window.openDetail = function (partId) {
    var modal = document.getElementById('detailModal');
    var body = document.getElementById('detailBody');
    body.innerHTML = '<div class="loading">Cargando detalle...</div>';
    modal.classList.add('open');
    fetch(API + '/part/' + partId)
      .then(function (r) { return r.json(); })
      .then(function (d) { renderDetail(d, body); })
      .catch(function () { body.innerHTML = '<div class="empty">Error cargando detalle.</div>'; });
  };

  window.closeDetail = function () {
    document.getElementById('detailModal').classList.remove('open');
  };

  // Close modal on backdrop click
  document.getElementById('detailModal').addEventListener('click', function (e) {
    if (e.target === this) closeDetail();
  });

  // ── Breadcrumb ──
  function renderBreadcrumb() {
    var parts = [];
    parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'brands\')">Catalogo</a>');

    if (state.brand) {
      parts.push('<span class="sep">/</span>');
      parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'models\')">' + esc(state.brand.name) + '</a>');
    }
    if (state.model) {
      parts.push('<span class="sep">/</span>');
      parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'years\')">' + esc(state.model.name) + '</a>');
    }
    if (state.year) {
      parts.push('<span class="sep">/</span>');
      parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'engines\')">' + esc(String(state.year.value)) + '</a>');
    }
    if (state.engine) {
      parts.push('<span class="sep">/</span>');
      var engineLabel = state.engine.name + (state.engine.trim ? ' (' + state.engine.trim + ')' : '');
      parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'categories\')">' + esc(engineLabel) + '</a>');
    }
    // Category / subgroup / part type — rendered from EITHER the Nexpart
    // branch (nxGroup/nxSubgroup/nxPartType) or the OEM branch. Only one
    // should be populated at any time after a navigation reset.
    if (state.nxGroup) {
      parts.push('<span class="sep">/</span>');
      parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'nx_subgroups\')">' + esc(state.nxGroup.name) + '</a>');
    } else if (state.category) {
      parts.push('<span class="sep">/</span>');
      parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'groups\')">' + esc(state.category.name) + '</a>');
    }

    if (state.nxSubgroup) {
      parts.push('<span class="sep">/</span>');
      if (state.nxPartType) {
        parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'nx_part_types\')">' + esc(state.nxSubgroup.name) + '</a>');
      } else {
        parts.push('<span>' + esc(state.nxSubgroup.name) + '</span>');
      }
    } else if (state.group) {
      parts.push('<span class="sep">/</span>');
      if (state.partType) {
        parts.push('<a href="javascript:void(0)" onclick="catalogNav(\'part_types\')">' + esc(state.group.name) + '</a>');
      } else {
        parts.push('<span>' + esc(state.group.name) + '</span>');
      }
    }

    if (state.nxPartType) {
      parts.push('<span class="sep">/</span>');
      parts.push('<span>' + esc(state.nxPartType.name) + '</span>');
    } else if (state.partType) {
      parts.push('<span class="sep">/</span>');
      parts.push('<span>' + esc(state.partType.name) + '</span>');
    }

    if (state.level === 'search') {
      parts.push('<span class="sep">/</span>');
      parts.push('<span>Busqueda</span>');
    }

    breadcrumbEl.innerHTML = parts.join('');
  }

  // Helper: clears every state key at-or-below the category level, for
  // BOTH the OEM branch and the Nexpart branch. Used whenever we navigate
  // backward to an ancestor and need a clean slate below.
  function clearCatSubtree() {
    state.category = state.group = state.partType = null;
    state.nxGroup = state.nxSubgroup = state.nxPartType = null;
  }

  // Global nav — jump to any ancestor in the breadcrumb
  window.catalogNav = function (level) {
    if (level === 'brands') {
      state.brand = state.model = state.year = state.engine = null;
      clearCatSubtree();
      state.level = 'brands';
      loadBrands();
    } else if (level === 'models') {
      state.model = state.year = state.engine = null;
      clearCatSubtree();
      state.level = 'models';
      loadModels();
    } else if (level === 'years') {
      state.year = state.engine = null;
      clearCatSubtree();
      state.level = 'years';
      loadYears();
    } else if (level === 'engines') {
      state.engine = null;
      clearCatSubtree();
      state.level = 'engines';
      loadEngines();
    } else if (level === 'categories') {
      clearCatSubtree();
      state.level = 'categories';
      loadCategoriesForMode();
    // OEM branch back-nav
    } else if (level === 'groups') {
      state.group = state.partType = null;
      state.level = 'groups';
      loadGroups();
    } else if (level === 'part_types') {
      state.partType = null;
      state.level = 'part_types';
      loadPartTypes();
    // Nexpart branch back-nav
    } else if (level === 'nx_subgroups') {
      state.nxSubgroup = state.nxPartType = null;
      state.level = 'groups';
      loadNexpartSubgroups();
    } else if (level === 'nx_part_types') {
      state.nxPartType = null;
      state.level = 'part_types';
      loadNexpartPartTypes();
    }
  };

  // ── Data loaders ──

  function loadBrands() {
    state.level = 'brands';
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando marcas...</div>';
    fetch(API + '/brands?region=' + (state.region || 'north-america') + '&mode=' + state.mode)
      .then(function (r) { return r.json(); })
      .then(function (brands) {
        var html = '<h2>Selecciona una Marca</h2><div class="nav-grid">';
        brands.forEach(function (b) {
          html += '<div class="nav-card" onclick="selectBrand(' + b.id_brand + ',\'' + escAttr(b.name_brand) + '\')">';
          html += '<span class="name">' + esc(b.name_brand) + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando marcas.</div>'; });
  }

  window.selectBrand = function (id, name) {
    state.brand = { id: id, name: name };
    state.level = 'models';
    loadModels();
  };

  function loadModels() {
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando modelos...</div>';
    fetch(API + '/models?brand_id=' + state.brand.id)
      .then(function (r) { return r.json(); })
      .then(function (models) {
        var html = '<h2>' + esc(state.brand.name) + ' — Modelos</h2><div class="nav-grid">';
        models.forEach(function (m) {
          html += '<div class="nav-card" onclick="selectModel(' + m.id_model + ',\'' + escAttr(m.name_model) + '\')">';
          html += '<span class="name">' + esc(m.name_model) + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando modelos.</div>'; });
  }

  window.selectModel = function (id, name) {
    state.model = { id: id, name: name };
    state.level = 'years';
    loadYears();
  };

  function loadYears() {
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando anos...</div>';
    fetch(API + '/years?model_id=' + state.model.id)
      .then(function (r) { return r.json(); })
      .then(function (years) {
        var html = '<h2>' + esc(state.brand.name) + ' ' + esc(state.model.name) + ' — Anos</h2><div class="nav-grid">';
        years.forEach(function (y) {
          html += '<div class="nav-card" onclick="selectYear(' + y.id_year + ',' + y.year_car + ')">';
          html += '<span class="name">' + y.year_car + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando anos.</div>'; });
  }

  window.selectYear = function (id, value) {
    state.year = { id: id, value: value };
    state.level = 'engines';
    loadEngines();
  };

  function loadEngines() {
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando motores...</div>';
    fetch(API + '/engines?model_id=' + state.model.id + '&year_id=' + state.year.id)
      .then(function (r) { return r.json(); })
      .then(function (engines) {
        var html = '<h2>' + esc(state.brand.name) + ' ' + esc(state.model.name) + ' ' + state.year.value + ' — Motor</h2>';
        html += '<div class="nav-grid">';
        engines.forEach(function (e) {
          var label = e.name_engine + (e.trim_level ? ' (' + e.trim_level + ')' : '');
          html += '<div class="nav-card" onclick="selectEngine(' + e.id_mye + ',\'' + escAttr(e.name_engine) + '\',\'' + escAttr(e.trim_level || '') + '\')">';
          html += '<span class="name">' + esc(label) + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando motores.</div>'; });
  }

  window.selectEngine = function (id_mye, name, trim) {
    state.engine = { id_mye: id_mye, name: name, trim: trim };
    state.level = 'categories';
    loadCategoriesForMode();
  };

  // ── Mode dispatcher (OEM vs Nexpart Local) ──
  function loadCategoriesForMode() {
    if (state.mode === 'local') {
      loadNexpartCategories();
    } else {
      loadCategories();
    }
  }

  // ══════════════════════════════════════════════════════════════
  // NEXPART (Local mode) parallel navigation
  // ══════════════════════════════════════════════════════════════

  function loadNexpartCategories() {
    state.level = 'categories';
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando categorias Local...</div>';
    fetch(API + '/categories?mode=local&mye_id=' + state.engine.id_mye)
      .then(function (r) { return r.json(); })
      .then(function (resp) {
        var cats = (resp && resp.data) || [];
        if (!cats.length) {
          content.innerHTML = '<h2>Categorias (Local)</h2><div class="empty">Ninguna parte de este vehiculo mapea al catalogo Local.</div>';
          return;
        }
        var html = '<h2>Categorias <span style="font-size:var(--text-body-sm);color:var(--color-text-muted);">(Local · ' + cats.length + ')</span></h2>';
        html += '<div class="nav-grid">';
        cats.forEach(function (c) {
          html += '<div class="nav-card" onclick="selectNxGroup(\'' + escAttr(c.slug) + '\',\'' + escAttr(c.name) + '\')">';
          html += '<span class="name">' + esc(c.name) + '</span>';
          html += '<span class="count">' + c.part_count + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando categorias Local.</div>'; });
  }

  window.selectNxGroup = function (slug, name) {
    state.nxGroup = { slug: slug, name: name };
    state.nxSubgroup = null;
    state.nxPartType = null;
    state.level = 'groups';
    loadNexpartSubgroups();
  };

  function loadNexpartSubgroups() {
    state.level = 'groups';
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando subcategorias...</div>';
    var url = API + '/groups?mode=local&mye_id=' + state.engine.id_mye
            + '&category_slug=' + encodeURIComponent(state.nxGroup.slug);
    fetch(url)
      .then(function (r) { return r.json(); })
      .then(function (resp) {
        var subs = (resp && resp.data) || [];
        if (!subs.length) {
          content.innerHTML = '<h2>' + esc(state.nxGroup.name) + '</h2><div class="empty">Sin subcategorias.</div>';
          return;
        }
        var html = '<h2>' + esc(state.nxGroup.name) + ' <span style="font-size:var(--text-body-sm);color:var(--color-text-muted);">(' + subs.length + ' subcategorias)</span></h2>';
        html += '<div class="nav-grid">';
        subs.forEach(function (s) {
          html += '<div class="nav-card" onclick="selectNxSubgroup(\'' + escAttr(s.slug) + '\',\'' + escAttr(s.name) + '\')">';
          html += '<span class="name">' + esc(s.name) + '</span>';
          html += '<span class="count">' + s.part_count + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando subcategorias.</div>'; });
  }

  window.selectNxSubgroup = function (slug, name) {
    state.nxSubgroup = { slug: slug, name: name };
    state.nxPartType = null;
    state.level = 'part_types';
    loadNexpartPartTypes();
  };

  function loadNexpartPartTypes() {
    state.level = 'part_types';
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando tipos de parte...</div>';
    var url = API + '/part-types?mode=local&mye_id=' + state.engine.id_mye
            + '&group_slug=' + encodeURIComponent(state.nxGroup.slug)
            + '&subgroup_slug=' + encodeURIComponent(state.nxSubgroup.slug);
    fetch(url)
      .then(function (r) { return r.json(); })
      .then(function (resp) {
        var pts = (resp && resp.data) || [];
        if (!pts.length) {
          content.innerHTML = '<h2>' + esc(state.nxSubgroup.name) + '</h2><div class="empty">Sin tipos de parte.</div>';
          return;
        }
        // Single part type → auto-drill-down
        if (pts.length === 1) {
          state.nxPartType = { slug: pts[0].slug, name: pts[0].name };
          state.level = 'parts';
          state.page = 1;
          loadParts();
          return;
        }
        var html = '<h2>' + esc(state.nxSubgroup.name) + ' <span style="font-size:var(--text-body-sm);color:var(--color-text-muted);">(' + pts.length + ' tipos)</span></h2>';
        html += '<div class="nav-grid">';
        pts.forEach(function (t) {
          var img = t.sample_image
            ? '<img src="' + esc(t.sample_image) + '" alt="" style="width:24px;height:24px;object-fit:contain;margin-right:6px;vertical-align:middle;" onerror="this.style.display=\'none\'">'
            : '';
          html += '<div class="nav-card" onclick="selectNxPartType(\'' + escAttr(t.slug) + '\',\'' + escAttr(t.name) + '\')">';
          html += '<span class="name">' + img + esc(t.name) + '</span>';
          html += '<span class="count">' + t.variant_count + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando tipos de parte.</div>'; });
  }

  window.selectNxPartType = function (slug, name) {
    state.nxPartType = { slug: slug, name: name };
    state.level = 'parts';
    state.page = 1;
    loadParts();
  };

  function loadCategories() {
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando categorias...</div>';
    fetch(API + '/categories?mye_id=' + state.engine.id_mye)
      .then(function (r) { return r.json(); })
      .then(function (cats) {
        if (!cats.length) {
          content.innerHTML = '<h2>Categorias</h2><div class="empty">No se encontraron categorias con partes para este vehiculo.</div>';
          return;
        }
        var html = '<h2>Categorias</h2><div class="nav-grid">';
        cats.forEach(function (c) {
          html += '<div class="nav-card" onclick="selectCategory(' + c.id_part_category + ',\'' + escAttr(c.name) + '\')">';
          html += '<span class="name">' + esc(c.name) + '</span>';
          html += '<span class="count">' + c.part_count + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando categorias.</div>'; });
  }

  window.selectCategory = function (id, name) {
    state.category = { id: id, name: name };
    state.level = 'groups';
    loadGroups();
  };

  function loadGroups() {
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando grupos...</div>';
    fetch(API + '/groups?mye_id=' + state.engine.id_mye + '&category_id=' + state.category.id)
      .then(function (r) { return r.json(); })
      .then(function (groups) {
        if (!groups.length) {
          content.innerHTML = '<h2>' + esc(state.category.name) + '</h2><div class="empty">No se encontraron sub-grupos.</div>';
          return;
        }
        var html = '<h2>' + esc(state.category.name) + '</h2><div class="nav-grid">';
        groups.forEach(function (g) {
          html += '<div class="nav-card" onclick="selectGroup(' + g.id_part_group + ',\'' + escAttr(g.name) + '\')">';
          html += '<span class="name">' + esc(g.name) + '</span>';
          html += '<span class="count">' + g.part_count + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando grupos.</div>'; });
  }

  window.selectGroup = function (id, name) {
    state.group = { id: id, name: name };
    state.partType = null;
    state.level = 'part_types';
    loadPartTypes();
  };

  // ── Part Types (3rd subcategory level — Nexpart-style) ──
  function loadPartTypes() {
    state.level = 'part_types';
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando tipos de parte...</div>';
    fetch(API + '/part-types?mye_id=' + state.engine.id_mye + '&group_id=' + state.group.id)
      .then(function (r) { return r.json(); })
      .then(function (resp) {
        var types = resp.data || [];
        if (!types.length) {
          // No types available — fall through to all parts in the group.
          state.level = 'parts'; state.page = 1;
          loadParts();
          return;
        }
        if (types.length === 1) {
          // Single type — auto-select and show parts directly.
          state.partType = { slug: types[0].slug, name: types[0].name };
          state.level = 'parts'; state.page = 1;
          loadParts();
          return;
        }
        var html = '<h2>' + esc(state.group.name) + ' <span style="font-size:var(--text-body-sm);color:var(--color-text-muted);">(' + types.length + ' tipos)</span></h2>';
        html += '<div class="nav-grid">';
        types.forEach(function (t) {
          var img = t.sample_image
            ? '<img src="' + esc(t.sample_image) + '" alt="" style="width:24px;height:24px;object-fit:contain;margin-right:6px;vertical-align:middle;" onerror="this.style.display=\'none\'">'
            : '';
          html += '<div class="nav-card" onclick="selectPartType(\'' + escAttr(t.slug) + '\',\'' + escAttr(t.name) + '\')">';
          html += '<span class="name">' + img + esc(t.name) + '</span>';
          html += '<span class="count">' + t.variant_count + '</span>';
          html += '</div>';
        });
        html += '</div>';
        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando tipos de parte.</div>'; });
  }

  window.selectPartType = function (slug, name) {
    state.partType = { slug: slug, name: name };
    state.level = 'parts';
    state.page = 1;
    loadParts();
  };

  function loadParts() {
    renderBreadcrumb();
    content.innerHTML = '<div class="loading">Cargando partes...</div>';

    // Build URL based on which navigation branch the user took.
    // Nexpart branch uses slug-based params; OEM branch uses integer ids.
    var url;
    if (state.nxGroup && state.nxSubgroup && state.nxPartType) {
      url = API + '/parts?mode=local'
          + '&mye_id=' + state.engine.id_mye
          + '&page=' + state.page
          + '&nexpart_group=' + encodeURIComponent(state.nxGroup.slug)
          + '&nexpart_subgroup=' + encodeURIComponent(state.nxSubgroup.slug)
          + '&nexpart_part_type=' + encodeURIComponent(state.nxPartType.slug);
    } else {
      var ptParam = state.partType ? '&part_type=' + encodeURIComponent(state.partType.slug) : '';
      url = API + '/parts?mye_id=' + state.engine.id_mye
          + '&group_id=' + state.group.id
          + '&page=' + state.page
          + '&mode=' + state.mode
          + ptParam;
    }

    // The header title shows the deepest selected node, regardless of branch.
    var headerTitle = state.nxPartType ? state.nxPartType.name
                   : state.nxSubgroup ? state.nxSubgroup.name
                   : state.partType ? state.partType.name
                   : state.group ? state.group.name
                   : 'Partes';

    fetch(url)
      .then(function (r) { return r.json(); })
      .then(function (resp) {
        var parts = resp.data;
        var pag = resp.pagination;
        state.totalPages = pag.total_pages;
        var isLocal = (state.mode === 'local');

        if (!parts.length) {
          content.innerHTML = '<h2>' + esc(headerTitle) + '</h2><div class="empty">No se encontraron partes.</div>';
          return;
        }

        var html = '<h2>' + esc(headerTitle) + ' <span style="font-size:var(--text-body-sm);color:var(--color-text-muted);">(' + pag.total + ' partes)</span></h2>';
        html += '<div class="parts-list">';
        parts.forEach(function (p) {
          var tierClass = '';
          if (isLocal) {
            if (p.priority_tier === 1) tierClass = ' part-row--tier1';
            else if (p.priority_tier === 2) tierClass = ' part-row--tier2';
          }

          html += '<div class="part-row' + tierClass + '">';
          html += '<div>';

          // Manufacturer badge (local mode only)
          if (isLocal && p.manufacturer) {
            var tierStar = p.priority_tier === 1 ? '<span class="manu-tier">&#9733;</span>' : '';
            html += '<div class="part-manu"><span class="manu-name">' + esc(p.manufacturer) + '</span>' + tierStar + '</div>';
          }

          // SKU line
          if (isLocal && p.part_number) {
            html += '<div class="part-oem">' + esc(p.part_number) + '<span class="part-oem-sub"> &middot; OEM: ' + esc(p.oem_part_number) + '</span></div>';
          } else {
            html += '<div class="part-oem">' + esc(p.oem_part_number) + '</div>';
          }

          html += '<div class="part-name">' + esc(p.name || '') + '</div>';
          if (p.description) html += '<div class="part-desc">' + esc(p.description) + '</div>';

          // Stock badge (local mode)
          if (isLocal) {
            if (p.in_stock_network) {
              html += '<div class="part-stock part-stock--yes">En stock en ' + p.bodega_count + ' bodega' + (p.bodega_count > 1 ? 's' : '') + '</div>';
            } else {
              html += '<div class="part-stock part-stock--no">Consultar disponibilidad</div>';
            }
          }

          html += '<button class="part-detail-btn" onclick="openDetail(' + p.id_part + ')">Ver detalle y alternativas</button>';
          html += '</div>';
          if (p.image_url) {
            html += '<img class="part-img" src="' + esc(p.image_url) + '" alt="" loading="lazy" onerror="this.style.display=\'none\'">';
          }
          html += '</div>';
        });
        html += '</div>';

        // Pagination
        if (pag.total_pages > 1) {
          html += '<div class="pagination">';
          html += '<button ' + (state.page <= 1 ? 'disabled' : 'onclick="partsPage(' + (state.page - 1) + ')"') + '>&laquo; Anterior</button>';
          html += '<button disabled>Pagina ' + state.page + ' de ' + pag.total_pages + '</button>';
          html += '<button ' + (state.page >= pag.total_pages ? 'disabled' : 'onclick="partsPage(' + (state.page + 1) + ')"') + '>Siguiente &raquo;</button>';
          html += '</div>';
        }

        content.innerHTML = html;
      })
      .catch(function () { content.innerHTML = '<div class="empty">Error cargando partes.</div>'; });
  }

  window.partsPage = function (p) {
    state.page = p;
    loadParts();
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  // ── Search results ──
  function renderSearchResults(results) {
    renderBreadcrumb();
    if (!results.length) {
      content.innerHTML = '<h2>Busqueda</h2><div class="empty">No se encontraron resultados.</div>';
      return;
    }
    var html = '<h2>Resultados (' + results.length + ')</h2><div class="parts-list">';
    results.forEach(function (p) {
      html += '<div class="part-row">';
      html += '<div>';
      html += '<div class="part-oem">' + esc(p.oem_part_number) + '</div>';
      html += '<div class="part-name">' + esc(p.name || '') + '</div>';
      if (p.vehicle_info) html += '<div class="part-desc">' + esc(p.vehicle_info) + '</div>';
      html += '<button class="part-detail-btn" onclick="openDetail(' + p.id_part + ')">Ver detalle y alternativas</button>';
      html += '</div>';
      if (p.image_url) {
        html += '<img class="part-img" src="' + esc(p.image_url) + '" alt="" loading="lazy" onerror="this.style.display=\'none\'">';
      }
      html += '</div>';
    });
    html += '</div>';
    content.innerHTML = html;
  }

  // ── Part detail ──
  function renderDetail(d, body) {
    if (!d || !d.part) {
      body.innerHTML = '<div class="empty">Parte no encontrada.</div>';
      return;
    }
    var p = d.part;
    var html = '';
    html += '<div class="part-oem" style="font-size:var(--text-h5)">' + esc(p.oem_part_number) + '</div>';
    html += '<div class="part-name" style="font-size:var(--text-h4);margin-top:var(--space-2)">' + esc(p.name || '') + '</div>';
    if (p.category_name) html += '<div class="part-desc">' + esc(p.category_name) + (p.group_name ? ' / ' + esc(p.group_name) : '') + '</div>';
    if (p.description) html += '<div class="part-desc" style="margin-top:var(--space-3)">' + esc(p.description) + '</div>';
    if (p.image_url) {
      html += '<div style="margin-top:var(--space-4);text-align:center">';
      html += '<img src="' + esc(p.image_url) + '" alt="" style="max-width:300px;border-radius:var(--radius-md)" onerror="this.style.display=\'none\'">';
      html += '</div>';
    }

    // Alternatives
    if (d.alternatives && d.alternatives.length) {
      html += '<div class="detail-section">';
      html += '<h4>Alternativas y Cross-References (' + d.alternatives.length + ')</h4>';
      html += '<table class="alt-table"><thead><tr><th>Numero</th><th>Fabricante</th><th>Nombre</th><th>Tipo</th></tr></thead><tbody>';
      d.alternatives.forEach(function (a) {
        html += '<tr>';
        html += '<td style="font-family:var(--font-mono)">' + esc(a.part_number || '') + '</td>';
        html += '<td>' + esc(a.manufacturer || '') + '</td>';
        html += '<td>' + esc(a.name || '-') + '</td>';
        html += '<td>' + esc(a.type === 'aftermarket' ? 'Aftermarket' : 'Cross-Ref') + '</td>';
        html += '</tr>';
      });
      html += '</tbody></table></div>';
    }

    // Bodegas
    if (d.bodegas && d.bodegas.length) {
      html += '<div class="detail-section">';
      html += '<h4>Disponibilidad en Bodegas (' + d.bodegas.length + ')</h4>';
      html += '<table class="alt-table"><thead><tr><th>Bodega</th><th>Stock</th><th>Ubicacion</th></tr></thead><tbody>';
      d.bodegas.forEach(function (b) {
        html += '<tr>';
        html += '<td>' + esc(b.business_name || '') + '</td>';
        html += '<td>' + b.stock + '</td>';
        html += '<td>' + esc(b.location || '-') + '</td>';
        html += '</tr>';
      });
      html += '</tbody></table></div>';
    }

    body.innerHTML = html;
  }

  // ── Helpers ──
  function esc(s) {
    if (!s) return '';
    var d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
  }

  function escAttr(s) {
    return esc(s).replace(/'/g, "\\'").replace(/"/g, '&quot;');
  }

})();
