let currentPage={parts:1,aftermarket:1,crossref:1,fitment:1},categoriesCache=[],groupsCache=[],partsCache=[],manufacturersCache=[],brandsCache=[],pendingImportData=null,searchTimeout=null;const csvFormats={parts:{columns:["oem_part_number","name","name_es","group_id","description","description_es","weight_kg","material"],required:["oem_part_number","name","group_id"],example:"oem_part_number,name,name_es,group_id,description,description_es,weight_kg,material\n04465-33450,Brake Pad Set Front,Pastillas de Freno Delanteras,5,Front disc brake pads,Pastillas de freno de disco delanteras,1.2,Ceramic"},aftermarket:{columns:["oem_part_id","manufacturer_id","part_number","name","name_es","quality_tier","price_usd","warranty_months"],required:["oem_part_id","manufacturer_id","part_number"],example:"oem_part_id,manufacturer_id,part_number,name,name_es,quality_tier,price_usd,warranty_months\n1,3,BP-1234,Brake Pad Set,Pastillas de Freno,premium,45.99,24"},manufacturers:{columns:["name","type","quality_tier","country","website"],required:["name","type"],example:"name,type,quality_tier,country,website\nBrembo,aftermarket,premium,Italy,https://www.brembo.com"},categories:{columns:["name","name_es","slug","icon_name","display_order"],required:["name"],example:"name,name_es,slug,icon_name,display_order\nBrake System,Sistema de Frenos,brakes,brake,1"},groups:{columns:["category_id","name","name_es","display_order"],required:["category_id","name"],example:"category_id,name,name_es,display_order\n1,Brake Pads,Pastillas de Freno,1"},crossref:{columns:["part_id","cross_reference_number","reference_type","source","notes"],required:["part_id","cross_reference_number","reference_type"],example:"part_id,cross_reference_number,reference_type,source,notes\n1,D1210,interchange,Manufacturer,Compatible replacement"},fitment:{columns:["model_year_engine_id","part_id","quantity_required","position","fitment_notes"],required:["model_year_engine_id","part_id"],example:"model_year_engine_id,part_id,quantity_required,position,fitment_notes\n1,1,2,front,Fits all trims"}};function initSidebar(){const e=document.querySelectorAll(".sidebar-item");e.forEach((t=>{t.addEventListener("click",(()=>{showSection(t.dataset.section),e.forEach((e=>e.classList.remove("active"))),t.classList.add("active")}))}))}function showSection(e){document.querySelectorAll(".admin-section").forEach((e=>e.classList.remove("active")));const t=document.getElementById(`section-${e}`);if(t)switch(t.classList.add("active"),e){case"dashboard":loadDashboard();break;case"categories":loadCategories();break;case"groups":loadGroups();break;case"parts":loadParts();break;case"manufacturers":loadManufacturers();break;case"aftermarket":loadAftermarket();break;case"crossref":loadCrossRefs();break;case"fitment":loadFitment();break;case"diagrams":break;case"users":loadUsers()}document.querySelectorAll(".sidebar-item").forEach((t=>{t.classList.toggle("active",t.dataset.section===e)}))}function openModal(e){document.getElementById(e).classList.add("active")}function closeModal(e){document.getElementById(e).classList.remove("active")}function showAlert(e,t="success"){const a=document.getElementById("alertContainer"),n=document.createElement("div");n.className=`alert alert-${t}`,n.innerHTML=`${"success"===t?"✓":"✕"} ${e}`,a.appendChild(n),setTimeout((()=>n.remove()),5e3)}function debounceSearch(e){searchTimeout&&clearTimeout(searchTimeout),searchTimeout=setTimeout(e,300)}async function loadDashboard(){try{const e=await fetch("/api/admin/stats").then((e=>e.json()));document.getElementById("statCategories").textContent=e.categories||0,document.getElementById("statGroups").textContent=e.groups||0,document.getElementById("statParts").textContent=e.parts||0,document.getElementById("statAftermarket").textContent=e.aftermarket||0,document.getElementById("statManufacturers").textContent=e.manufacturers||0,document.getElementById("statFitment").textContent=e.fitment||0}catch(e){console.error("Error loading dashboard:",e)}}async function loadCategories(){try{const e=await fetch("/api/categories"),t=await e.json();categoriesCache=flattenCategories(t);const a=document.getElementById("categoriesTable");if(0===categoriesCache.length)return void(a.innerHTML='No hay categorías');a.innerHTML=categoriesCache.map((e=>`\n \n ${e.id}\n ${e.name}\n ${e.name_es||"-"}\n ${e.slug||"-"}\n ${e.icon_name||"-"}\n ${e.display_order||0}\n \n \n \n \n \n `)).join(""),updateCategorySelects()}catch(e){console.error("Error loading categories:",e),showAlert("Error al cargar categorías","error")}}function flattenCategories(e,t=0){let a=[];return e.forEach((e=>{a.push({...e,level:t}),e.children&&e.children.length>0&&(a=a.concat(flattenCategories(e.children,t+1)))})),a}function updateCategorySelects(){["groupCategoryFilter","groupCategory"].forEach((e=>{const t=document.getElementById(e);if(!t)return;const a=t.value,n=e.includes("Filter")?'':'';t.innerHTML=n+categoriesCache.map((e=>``)).join(""),t.value=a}))}function openCategoryModal(e=null){if(document.getElementById("categoryId").value="",document.getElementById("categoryName").value="",document.getElementById("categoryNameEs").value="",document.getElementById("categorySlug").value="",document.getElementById("categoryIcon").value="",document.getElementById("categoryOrder").value="0",document.getElementById("categoryModalTitle").textContent="Nueva Categoría",e){const t=categoriesCache.find((t=>t.id===e));t&&(document.getElementById("categoryId").value=t.id,document.getElementById("categoryName").value=t.name,document.getElementById("categoryNameEs").value=t.name_es||"",document.getElementById("categorySlug").value=t.slug||"",document.getElementById("categoryIcon").value=t.icon_name||"",document.getElementById("categoryOrder").value=t.display_order||0,document.getElementById("categoryModalTitle").textContent="Editar Categoría")}openModal("categoryModal")}function editCategory(e){openCategoryModal(e)}async function saveCategory(){const e=document.getElementById("categoryId").value,t={name:document.getElementById("categoryName").value,name_es:document.getElementById("categoryNameEs").value||null,slug:document.getElementById("categorySlug").value||null,icon_name:document.getElementById("categoryIcon").value||null,display_order:parseInt(document.getElementById("categoryOrder").value)||0};try{const a=e?`/api/admin/categories/${e}`:"/api/admin/categories",n=e?"PUT":"POST",r=await fetch(a,{method:n,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("categoryModal"),showAlert(e?"Categoría actualizada":"Categoría creada"),loadCategories()}catch(e){showAlert(e.message,"error")}}async function deleteCategory(e){if(confirm("¿Estás seguro de eliminar esta categoría?"))try{if(!(await fetch(`/api/admin/categories/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Categoría eliminada"),loadCategories()}catch(e){showAlert(e.message,"error")}}async function loadGroups(){try{const e=document.getElementById("groupCategoryFilter").value;let t="/api/admin/groups";e&&(t+=`?category_id=${e}`);const a=await fetch(t),n=await a.json();groupsCache=n;const r=document.getElementById("groupsTable");if(0===n.length)return void(r.innerHTML='No hay grupos');r.innerHTML=n.map((e=>`\n \n ${e.id}\n ${e.name}\n ${e.name_es||"-"}\n ${e.category_name||"-"}\n ${e.display_order||0}\n \n \n \n \n \n `)).join(""),updateGroupSelects()}catch(e){console.error("Error loading groups:",e),showAlert("Error al cargar grupos","error")}}function updateGroupSelects(){["partGroupFilter","partGroup"].forEach((e=>{const t=document.getElementById(e);if(!t)return;const a=t.value,n=e.includes("Filter")?'':'';t.innerHTML=n+groupsCache.map((e=>``)).join(""),t.value=a}))}function openGroupModal(e=null){document.getElementById("groupId").value="",document.getElementById("groupName").value="",document.getElementById("groupNameEs").value="",document.getElementById("groupOrder").value="0",document.getElementById("groupModalTitle").textContent="Nuevo Grupo";if(document.getElementById("groupCategory").innerHTML=''+categoriesCache.map((e=>``)).join(""),e){const t=groupsCache.find((t=>t.id===e));t&&(document.getElementById("groupId").value=t.id,document.getElementById("groupName").value=t.name,document.getElementById("groupNameEs").value=t.name_es||"",document.getElementById("groupCategory").value=t.category_id,document.getElementById("groupOrder").value=t.display_order||0,document.getElementById("groupModalTitle").textContent="Editar Grupo")}openModal("groupModal")}function editGroup(e){openGroupModal(e)}async function saveGroup(){const e=document.getElementById("groupId").value,t={category_id:parseInt(document.getElementById("groupCategory").value),name:document.getElementById("groupName").value,name_es:document.getElementById("groupNameEs").value||null,display_order:parseInt(document.getElementById("groupOrder").value)||0};try{const a=e?`/api/admin/groups/${e}`:"/api/admin/groups",n=e?"PUT":"POST",r=await fetch(a,{method:n,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("groupModal"),showAlert(e?"Grupo actualizado":"Grupo creado"),loadGroups()}catch(e){showAlert(e.message,"error")}}async function deleteGroup(e){if(confirm("¿Estás seguro de eliminar este grupo?"))try{if(!(await fetch(`/api/admin/groups/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Grupo eliminado"),loadGroups()}catch(e){showAlert(e.message,"error")}}async function loadParts(){try{const e=document.getElementById("partSearch").value,t=document.getElementById("partGroupFilter").value;let a=`/api/parts?page=${currentPage.parts}&per_page=20`;e&&(a+=`&search=${encodeURIComponent(e)}`),t&&(a+=`&group_id=${t}`);const n=await fetch(a),r=await n.json();partsCache=r.data||[];const o=document.getElementById("partsTable");if(0===partsCache.length)return o.innerHTML='No hay partes',void renderPagination("partsPagination",r.pagination,"parts",loadParts);o.innerHTML=partsCache.map((e=>`\n \n ${e.id}\n \n ${e.image_url?`${e.name}`:'📷'}\n \n ${e.oem_part_number}\n ${e.name}\n ${e.group_name||"-"}\n \n \n \n \n \n `)).join(""),renderPagination("partsPagination",r.pagination,"parts",loadParts),0===groupsCache.length&&await loadGroups()}catch(e){console.error("Error loading parts:",e),showAlert("Error al cargar partes","error")}}function openPartModal(e=null){document.getElementById("partId").value="",document.getElementById("partOemNumber").value="",document.getElementById("partName").value="",document.getElementById("partNameEs").value="",document.getElementById("partDescription").value="",document.getElementById("partDescriptionEs").value="",document.getElementById("partWeight").value="",document.getElementById("partMaterial").value="",document.getElementById("partModalTitle").textContent="Nueva Parte OEM",resetPartImagePreview();document.getElementById("partGroup").innerHTML=''+groupsCache.map((e=>``)).join(""),e&&fetchPartDetail(e),openModal("partModal")}async function fetchPartDetail(e){try{const t=await fetch(`/api/parts/${e}`),a=await t.json();document.getElementById("partId").value=a.id,document.getElementById("partOemNumber").value=a.oem_part_number,document.getElementById("partName").value=a.name,document.getElementById("partNameEs").value=a.name_es||"",document.getElementById("partGroup").value=a.group_id,document.getElementById("partDescription").value=a.description||"",document.getElementById("partDescriptionEs").value=a.description_es||"",document.getElementById("partModalTitle").textContent="Editar Parte OEM";const n=document.getElementById("partImagePreview");a.image_url?(n.innerHTML=`${a.name}`,document.getElementById("partImageUrl").value=a.image_url):resetPartImagePreview()}catch(e){console.error("Error fetching part:",e)}}function editPart(e){openPartModal(e)}async function savePart(){const e=document.getElementById("partId").value;let t=document.getElementById("partImageUrl").value||null;const a=document.getElementById("partImagePreview").querySelector("img");a&&a.src.startsWith("data:")&&(t=await uploadPartImage(a.src));const n={oem_part_number:document.getElementById("partOemNumber").value,name:document.getElementById("partName").value,name_es:document.getElementById("partNameEs").value||null,group_id:parseInt(document.getElementById("partGroup").value),description:document.getElementById("partDescription").value||null,description_es:document.getElementById("partDescriptionEs").value||null,weight_kg:parseFloat(document.getElementById("partWeight").value)||null,material:document.getElementById("partMaterial").value||null,image_url:t};try{const t=e?`/api/admin/parts/${e}`:"/api/admin/parts",a=e?"PUT":"POST",r=await fetch(t,{method:a,headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("partModal"),showAlert(e?"Parte actualizada":"Parte creada"),loadParts()}catch(e){showAlert(e.message,"error")}}function previewPartImage(e){const t=document.getElementById("partImagePreview");if(e.files&&e.files[0]){const a=new FileReader;a.onload=function(e){t.innerHTML=`Preview`},a.readAsDataURL(e.files[0])}}async function uploadPartImage(e){try{const t=await fetch("/api/admin/upload-image",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:e})});if(!t.ok)throw new Error("Error uploading image");return(await t.json()).url}catch(e){return console.error("Image upload failed:",e),null}}function resetPartImagePreview(){document.getElementById("partImagePreview").innerHTML='📷 Sin imagen',document.getElementById("partImageUrl").value="",document.getElementById("partImageFile").value=""}async function deletePart(e){if(confirm("¿Estás seguro de eliminar esta parte?"))try{if(!(await fetch(`/api/admin/parts/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Parte eliminada"),loadParts()}catch(e){showAlert(e.message,"error")}}async function loadManufacturers(){try{const e=await fetch("/api/manufacturers");manufacturersCache=await e.json();const t=document.getElementById("manufacturersTable");if(0===manufacturersCache.length)return void(t.innerHTML='No hay fabricantes');t.innerHTML=manufacturersCache.map((e=>`\n \n ${e.id}\n ${e.name}\n ${e.type||"-"}\n ${e.quality_tier||"-"}\n ${e.country||"-"}\n \n \n \n \n \n `)).join(""),updateManufacturerSelects()}catch(e){console.error("Error loading manufacturers:",e),showAlert("Error al cargar fabricantes","error")}}function updateManufacturerSelects(){const e=document.getElementById("aftermarketManufacturerFilter");if(e){const t=e.value;e.innerHTML=''+manufacturersCache.map((e=>``)).join(""),e.value=t}const t=document.getElementById("aftermarketManufacturer");t&&(t.innerHTML=''+manufacturersCache.map((e=>``)).join(""))}function openManufacturerModal(e=null){if(document.getElementById("manufacturerId").value="",document.getElementById("manufacturerName").value="",document.getElementById("manufacturerType").value="aftermarket",document.getElementById("manufacturerQuality").value="standard",document.getElementById("manufacturerCountry").value="",document.getElementById("manufacturerWebsite").value="",document.getElementById("manufacturerModalTitle").textContent="Nuevo Fabricante",e){const t=manufacturersCache.find((t=>t.id===e));t&&(document.getElementById("manufacturerId").value=t.id,document.getElementById("manufacturerName").value=t.name,document.getElementById("manufacturerType").value=t.type||"aftermarket",document.getElementById("manufacturerQuality").value=t.quality_tier||"standard",document.getElementById("manufacturerCountry").value=t.country||"",document.getElementById("manufacturerWebsite").value=t.website||"",document.getElementById("manufacturerModalTitle").textContent="Editar Fabricante")}openModal("manufacturerModal")}function editManufacturer(e){openManufacturerModal(e)}async function saveManufacturer(){const e=document.getElementById("manufacturerId").value,t={name:document.getElementById("manufacturerName").value,type:document.getElementById("manufacturerType").value,quality_tier:document.getElementById("manufacturerQuality").value,country:document.getElementById("manufacturerCountry").value||null,website:document.getElementById("manufacturerWebsite").value||null};try{const a=e?`/api/admin/manufacturers/${e}`:"/api/admin/manufacturers",n=e?"PUT":"POST",r=await fetch(a,{method:n,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("manufacturerModal"),showAlert(e?"Fabricante actualizado":"Fabricante creado"),loadManufacturers()}catch(e){showAlert(e.message,"error")}}async function deleteManufacturer(e){if(confirm("¿Estás seguro de eliminar este fabricante?"))try{if(!(await fetch(`/api/admin/manufacturers/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Fabricante eliminado"),loadManufacturers()}catch(e){showAlert(e.message,"error")}}async function loadAftermarket(){try{const e=document.getElementById("aftermarketSearch").value,t=document.getElementById("aftermarketManufacturerFilter").value;let a=`/api/aftermarket?page=${currentPage.aftermarket}&per_page=20`;e&&(a+=`&search=${encodeURIComponent(e)}`),t&&(a+=`&manufacturer_id=${t}`);const n=await fetch(a),r=await n.json(),o=document.getElementById("aftermarketTable");if(!r.data||0===r.data.length)return o.innerHTML='No hay partes aftermarket',void renderPagination("aftermarketPagination",r.pagination,"aftermarket",loadAftermarket);o.innerHTML=r.data.map((e=>`\n \n ${e.id}\n ${e.part_number}\n ${e.name||"-"}\n ${e.oem_part_number}\n ${e.manufacturer_name}\n ${e.quality_tier||"-"}\n ${e.price_usd?"$"+e.price_usd.toFixed(2):"-"}\n \n \n \n \n \n `)).join(""),renderPagination("aftermarketPagination",r.pagination,"aftermarket",loadAftermarket)}catch(e){console.error("Error loading aftermarket:",e),showAlert("Error al cargar partes aftermarket","error")}}async function openAftermarketModal(e=null){document.getElementById("aftermarketId").value="",document.getElementById("aftermarketPartNumber").value="",document.getElementById("aftermarketName").value="",document.getElementById("aftermarketNameEs").value="",document.getElementById("aftermarketQuality").value="standard",document.getElementById("aftermarketPrice").value="",document.getElementById("aftermarketWarranty").value="",document.getElementById("aftermarketModalTitle").textContent="Nueva Parte Aftermarket",await loadPartsForSelect("aftermarketOemPart"),updateManufacturerSelects(),openModal("aftermarketModal")}async function editAftermarket(e){await openAftermarketModal(e);try{const t=await fetch("/api/aftermarket?search=&per_page=200"),a=await t.json(),n=(a.data||a).find((t=>t.id===e));n&&(document.getElementById("aftermarketId").value=n.id,document.getElementById("aftermarketPartNumber").value=n.part_number||"",document.getElementById("aftermarketName").value=n.name||"",document.getElementById("aftermarketNameEs").value=n.name_es||"",document.getElementById("aftermarketQuality").value=n.quality_tier||"standard",document.getElementById("aftermarketPrice").value=n.price_usd||"",document.getElementById("aftermarketWarranty").value=n.warranty_months||"",n.oem_part_id&&(document.getElementById("aftermarketOemPart").value=n.oem_part_id),n.manufacturer_id&&(document.getElementById("aftermarketManufacturer").value=n.manufacturer_id),document.getElementById("aftermarketModalTitle").textContent="Editar Parte Aftermarket")}catch(e){console.error("Error loading aftermarket for edit:",e)}}async function saveAftermarket(){const e=document.getElementById("aftermarketId").value,t={oem_part_id:parseInt(document.getElementById("aftermarketOemPart").value),manufacturer_id:parseInt(document.getElementById("aftermarketManufacturer").value),part_number:document.getElementById("aftermarketPartNumber").value,name:document.getElementById("aftermarketName").value||null,name_es:document.getElementById("aftermarketNameEs").value||null,quality_tier:document.getElementById("aftermarketQuality").value,price_usd:parseFloat(document.getElementById("aftermarketPrice").value)||null,warranty_months:parseInt(document.getElementById("aftermarketWarranty").value)||null};try{const a=e?`/api/admin/aftermarket/${e}`:"/api/admin/aftermarket",n=e?"PUT":"POST",r=await fetch(a,{method:n,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("aftermarketModal"),showAlert(e?"Parte actualizada":"Parte creada"),loadAftermarket()}catch(e){showAlert(e.message,"error")}}async function deleteAftermarket(e){if(confirm("¿Estás seguro de eliminar esta parte aftermarket?"))try{if(!(await fetch(`/api/admin/aftermarket/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Parte eliminada"),loadAftermarket()}catch(e){showAlert(e.message,"error")}}async function loadCrossRefs(){try{const e=await fetch(`/api/admin/crossref?page=${currentPage.crossref}&per_page=20`),t=await e.json(),a=document.getElementById("crossrefTable");if(!t.data||0===t.data.length)return void(a.innerHTML='No hay cross-references');a.innerHTML=t.data.map((e=>`\n \n ${e.id}\n ${e.oem_part_number} - ${e.part_name}\n ${e.cross_reference_number}\n ${e.reference_type}\n ${e.source||"-"}\n \n \n \n \n \n `)).join(""),renderPagination("crossrefPagination",t.pagination,"crossref",loadCrossRefs)}catch(e){console.error("Error loading cross-refs:",e)}}async function openCrossRefModal(e=null){document.getElementById("crossrefId").value="",document.getElementById("crossrefNumber").value="",document.getElementById("crossrefType").value="interchange",document.getElementById("crossrefSource").value="",document.getElementById("crossrefNotes").value="",document.getElementById("crossrefModalTitle").textContent="Nueva Cross-Reference",await loadPartsForSelect("crossrefPart"),openModal("crossrefModal")}function editCrossRef(e){openCrossRefModal(e)}async function saveCrossRef(){const e=document.getElementById("crossrefId").value,t={part_id:parseInt(document.getElementById("crossrefPart").value),cross_reference_number:document.getElementById("crossrefNumber").value,reference_type:document.getElementById("crossrefType").value,source:document.getElementById("crossrefSource").value||null,notes:document.getElementById("crossrefNotes").value||null};try{const a=e?`/api/admin/crossref/${e}`:"/api/admin/crossref",n=e?"PUT":"POST",r=await fetch(a,{method:n,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("crossrefModal"),showAlert(e?"Referencia actualizada":"Referencia creada"),loadCrossRefs()}catch(e){showAlert(e.message,"error")}}async function deleteCrossRef(e){if(confirm("¿Estás seguro de eliminar esta referencia?"))try{if(!(await fetch(`/api/admin/crossref/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Referencia eliminada"),loadCrossRefs()}catch(e){showAlert(e.message,"error")}}async function loadFitment(){try{const e=document.getElementById("fitmentBrandFilter").value,t=document.getElementById("fitmentModelFilter").value;let a=`/api/admin/fitment?page=${currentPage.fitment}&per_page=20`;e&&(a+=`&brand=${encodeURIComponent(e)}`),t&&(a+=`&model=${encodeURIComponent(t)}`);const n=await fetch(a),r=await n.json(),o=document.getElementById("fitmentTable");if(!r.data||0===r.data.length)return o.innerHTML='No hay fitments',void renderPagination("fitmentPagination",r.pagination,"fitment",loadFitment);o.innerHTML=r.data.map((e=>`\n \n ${e.id}\n ${e.brand} ${e.model} ${e.year} - ${e.engine}\n ${e.oem_part_number} - ${e.part_name}\n ${e.quantity_required}\n ${e.position||"-"}\n \n \n \n \n `)).join(""),renderPagination("fitmentPagination",r.pagination,"fitment",loadFitment)}catch(e){console.error("Error loading fitment:",e)}}async function loadFitmentModels(){const e=document.getElementById("fitmentBrandFilter").value,t=document.getElementById("fitmentModelFilter");if(!e)return t.innerHTML='',void loadFitment();try{const a=await fetch(`/api/models?brand=${encodeURIComponent(e)}`),n=await a.json();t.innerHTML=''+n.map((e=>``)).join(""),loadFitment()}catch(e){console.error("Error loading models:",e)}}async function openFitmentModal(){document.getElementById("fitmentId").value="",document.getElementById("fitmentQuantity").value="1",document.getElementById("fitmentPosition").value="",document.getElementById("fitmentNotes").value="",document.getElementById("fitmentModalTitle").textContent="Nuevo Fitment",await loadVehiclesForSelect("fitmentVehicle"),await loadPartsForSelect("fitmentPart"),openModal("fitmentModal")}async function saveFitment(){const e=document.getElementById("fitmentId").value,t={model_year_engine_id:parseInt(document.getElementById("fitmentVehicle").value),part_id:parseInt(document.getElementById("fitmentPart").value),quantity_required:parseInt(document.getElementById("fitmentQuantity").value)||1,position:document.getElementById("fitmentPosition").value||null,fitment_notes:document.getElementById("fitmentNotes").value||null};try{const a=e?`/api/admin/fitment/${e}`:"/api/admin/fitment",n=e?"PUT":"POST",r=await fetch(a,{method:n,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok){const e=await r.json();throw new Error(e.error||"Error al guardar")}closeModal("fitmentModal"),showAlert(e?"Fitment actualizado":"Fitment creado"),loadFitment()}catch(e){showAlert(e.message,"error")}}async function deleteFitment(e){if(confirm("¿Estás seguro de eliminar este fitment?"))try{if(!(await fetch(`/api/admin/fitment/${e}`,{method:"DELETE"})).ok)throw new Error("Error al eliminar");showAlert("Fitment eliminado"),loadFitment()}catch(e){showAlert(e.message,"error")}}async function loadPartsForSelect(e){const t=document.getElementById(e);if(t)try{const e=await fetch("/api/parts?per_page=100"),a=await e.json();t.innerHTML=''+(a.data||[]).map((e=>``)).join("")}catch(e){console.error("Error loading parts for select:",e)}}async function loadVehiclesForSelect(e){const t=document.getElementById(e);if(t)try{const e=await fetch("/api/model-year-engine?per_page=100"),a=await e.json(),n=a.data||a;t.innerHTML=''+n.map((e=>``)).join("")}catch(e){console.error("Error loading vehicles for select:",e)}}async function loadBrands(){try{const e=await fetch("/api/brands");brandsCache=await e.json();const t=document.getElementById("fitmentBrandFilter");t&&(t.innerHTML=''+brandsCache.map((e=>``)).join(""))}catch(e){console.error("Error loading brands:",e)}}function renderPagination(e,t,a,n){const r=document.getElementById(e);if(!r||!t)return void(r.innerHTML="");const{page:o,total_pages:i}=t;if(i<=1)return void(r.innerHTML="");let d="";d+=``;const l=Math.max(1,o-2),c=Math.min(i,o+2);for(let e=l;e<=c;e++)d+=``;d+=``,r.innerHTML=d}function goToPage(e,t,a){currentPage[e]=t,window[a]()}function initDropZone(){const e=document.getElementById("dropZone"),t=document.getElementById("csvFile");e.addEventListener("click",(()=>t.click())),e.addEventListener("dragover",(t=>{t.preventDefault(),e.classList.add("dragover")})),e.addEventListener("dragleave",(()=>{e.classList.remove("dragover")})),e.addEventListener("drop",(t=>{t.preventDefault(),e.classList.remove("dragover");const a=t.dataTransfer.files[0];a&&a.name.endsWith(".csv")?handleCsvFile(a):showAlert("Por favor selecciona un archivo CSV","error")})),t.addEventListener("change",(e=>{const t=e.target.files[0];t&&handleCsvFile(t)}))}function initImportTypeChange(){document.getElementById("importType").addEventListener("change",updateCsvFormatHelp),updateCsvFormatHelp()}function updateCsvFormatHelp(){const e=document.getElementById("importType").value,t=csvFormats[e],a=document.getElementById("csvFormatHelp");t&&(a.innerHTML=`\n

Columnas requeridas: ${t.required.join(", ")}

\n

Todas las columnas: ${t.columns.join(", ")}

\n

Ejemplo:

\n
${t.example}
\n `)}function handleCsvFile(e){const t=new FileReader;t.onload=e=>{const t=parseCSV(e.target.result);t.length<2?showAlert("El archivo CSV debe tener al menos un encabezado y una fila de datos","error"):(pendingImportData=t,showImportPreview(t))},t.readAsText(e)}function parseCSV(e){const t=e.split(/\r?\n/).filter((e=>e.trim())),a=[];for(const e of t){const t=[];let n="",r=!1;for(let a=0;a"+t.map((e=>`${e}`)).join("")+"",document.getElementById("previewBody").innerHTML=a.map((e=>""+e.map((e=>`${e}`)).join("")+"")).join(""),document.getElementById("importPreview").style.display="block"}function cancelImport(){pendingImportData=null,document.getElementById("importPreview").style.display="none",document.getElementById("csvFile").value=""}async function executeImport(){if(!pendingImportData)return;const e=document.getElementById("importType").value,t=csvFormats[e],a=pendingImportData[0],n=pendingImportData.slice(1);for(const e of t.required)if(!a.includes(e))return void showAlert(`Falta columna requerida: ${e}`,"error");const r=n.map((e=>{const t={};return a.forEach(((a,n)=>{let r=e[n]||null;["id","category_id","group_id","part_id","oem_part_id","manufacturer_id","model_year_engine_id","display_order","quantity_required","warranty_months"].includes(a)?r=r?parseInt(r):null:["weight_kg","price_usd"].includes(a)&&(r=r?parseFloat(r):null),t[a]=r})),t}));try{const t=await fetch(`/api/admin/import/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({records:r})}),a=await t.json();if(!t.ok)throw new Error(a.error||"Error en la importación");showAlert(`Importados ${a.imported} registros exitosamente`),cancelImport(),loadDashboard()}catch(e){showAlert(e.message,"error")}}async function exportData(e){try{const t=await fetch(`/api/admin/export/${e}`),a=await t.json();if(!a.data||0===a.data.length)return void showAlert("No hay datos para exportar","error");const n=Object.keys(a.data[0]);let r=n.join(",")+"\n";for(const e of a.data)r+=n.map((t=>{let a=e[t];return null==a?"":(a=String(a),a.includes(",")||a.includes('"')||a.includes("\n")?'"'+a.replace(/"/g,'""')+'"':a)})).join(",")+"\n";const o=new Blob([r],{type:"text/csv;charset=utf-8;"}),i=document.createElement("a");i.href=URL.createObjectURL(o),i.download=`${e}_export_${(new Date).toISOString().slice(0,10)}.csv`,i.click(),showAlert(`Exportados ${a.data.length} registros`)}catch(e){showAlert("Error al exportar: "+e.message,"error")}}document.addEventListener("DOMContentLoaded",(()=>{initSidebar(),initDropZone(),initImportTypeChange(),loadDashboard()})),loadBrands();let bulkSelectedMYEId=null,bulkAvailableParts=[];async function initBulkEditor(){const e=document.getElementById("bulkBrand");e&&brandsCache.length>0&&(e.innerHTML=''+brandsCache.map((e=>``)).join("")),0===categoriesCache.length&&await loadCategories();const t=document.getElementById("bulkCategory");t&&(t.innerHTML=''+categoriesCache.map((e=>``)).join(""))}async function loadBulkModels(){const e=document.getElementById("bulkBrand").value,t=document.getElementById("bulkModel"),a=document.getElementById("bulkYear"),n=document.getElementById("bulkEngine");if(t.innerHTML='',a.innerHTML='',n.innerHTML='',document.getElementById("bulkVehicleSelected").style.display="none",e)try{const a=await fetch(`/api/models?brand=${encodeURIComponent(e)}`),n=await a.json();t.innerHTML=''+n.map((e=>``)).join("")}catch(e){console.error("Error loading models:",e)}}async function loadBulkYears(){const e=document.getElementById("bulkBrand").value,t=document.getElementById("bulkModel").value,a=document.getElementById("bulkYear"),n=document.getElementById("bulkEngine");if(a.innerHTML='',n.innerHTML='',document.getElementById("bulkVehicleSelected").style.display="none",e&&t)try{const n=await fetch(`/api/years?brand=${encodeURIComponent(e)}&model=${encodeURIComponent(t)}`),r=await n.json();a.innerHTML=''+r.map((e=>``)).join("")}catch(e){console.error("Error loading years:",e)}}async function loadBulkEngines(){const e=document.getElementById("bulkBrand").value,t=document.getElementById("bulkModel").value,a=document.getElementById("bulkYear").value,n=document.getElementById("bulkEngine");if(n.innerHTML='',document.getElementById("bulkVehicleSelected").style.display="none",e&&t&&a)try{const r=await fetch(`/api/engines?brand=${encodeURIComponent(e)}&model=${encodeURIComponent(t)}&year=${a}`),o=(await r.json(),await fetch(`/api/model-year-engine?brand=${encodeURIComponent(e)}&model=${encodeURIComponent(t)}&year=${a}&per_page=100`)),i=await o.json(),d=i.data||i;n.innerHTML=''+d.map((e=>``)).join("")}catch(e){console.error("Error loading engines:",e)}}async function selectBulkVehicle(){const e=document.getElementById("bulkEngine").value;if(!e)return void(document.getElementById("bulkVehicleSelected").style.display="none");bulkSelectedMYEId=parseInt(e);const t=document.getElementById("bulkBrand").value,a=document.getElementById("bulkModel").value,n=document.getElementById("bulkYear").value,r=document.getElementById("bulkEngine").options[document.getElementById("bulkEngine").selectedIndex].text;document.getElementById("bulkVehicleName").textContent=`${t} ${a} ${n} - ${r}`,document.getElementById("bulkMYEId").textContent=e,document.getElementById("bulkVehicleSelected").style.display="block",await initBulkEditor(),await loadBulkParts()}async function loadBulkParts(){const e=document.getElementById("bulkPartsContainer"),t=document.getElementById("bulkCategory").value;e.innerHTML='

Cargando partes...

';try{let a="/api/parts?per_page=100";t&&(a+=`&category_id=${t}`);const n=await fetch(a),r=await n.json();if(bulkAvailableParts=r.data||[],0===bulkAvailableParts.length)return void(e.innerHTML='

No hay partes disponibles en esta categoría.

');const o=await fetch(`/api/admin/fitment?mye_id=${bulkSelectedMYEId}&per_page=500`),i=await o.json(),d=new Set((i.data||[]).map((e=>e.part_id)));e.innerHTML=bulkAvailableParts.map((e=>`\n
\n \n
\n
${e.oem_part_number}
\n
${e.name}
\n
${e.group_name||""} · ${e.category_name||""}
\n
\n \n
\n `)).join(""),updateBulkSelectedCount()}catch(t){console.error("Error loading parts:",t),e.innerHTML='

Error al cargar partes

'}}function toggleBulkPart(e,t){const a=e.querySelector('input[type="checkbox"]');a.disabled||(a.checked=!a.checked,e.classList.toggle("selected",a.checked),updateBulkSelectedCount())}function updateBulkSelectedCount(){const e=document.querySelectorAll('#bulkPartsContainer input[type="checkbox"]:checked:not(:disabled)');document.getElementById("bulkSelectedCount").textContent=`${e.length} partes seleccionadas`}async function saveBulkFitments(){if(!bulkSelectedMYEId)return void showAlert("Selecciona un vehículo primero","error");const e=document.querySelectorAll("#bulkPartsContainer .bulk-part-item"),t=[];if(e.forEach((e=>{const a=e.querySelector('input[type="checkbox"]');if(a.checked&&!a.disabled){const n=parseInt(a.dataset.partId),r=parseInt(e.querySelector(".bulk-part-qty").value)||1;t.push({model_year_engine_id:bulkSelectedMYEId,part_id:n,quantity_required:r})}})),0!==t.length)try{const e=await fetch("/api/admin/import/fitment",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({records:t})}),a=await e.json();if(!e.ok)throw new Error(a.error||"Error al guardar");showAlert(`${a.imported} fitments creados exitosamente`),await loadBulkParts(),loadFitment(),loadDashboard()}catch(e){showAlert(e.message,"error")}else showAlert("Selecciona al menos una parte","error")}const originalShowSection=showSection;showSection=function(e){originalShowSection(e),"fitment"===e&&initBulkEditor()};let currentEditorDiagramId=null,currentEditorHotspots=[],partSearchTimeout=null;async function searchDiagramsAdmin(){const e=document.getElementById("diagramSearchInput").value.trim(),t=document.getElementById("diagramSearchResults");if(e){t.innerHTML='

Buscando...

';try{const a=await fetch(`/api/diagrams/search?q=${encodeURIComponent(e)}`),n=await a.json();if(0===n.length)return void(t.innerHTML='

No se encontraron diagramas

');t.innerHTML=n.map((e=>{const t=e.image_path?"/"+e.image_path:`/static/diagrams/moog/${e.name}.jpg`;return`\n
\n ${e.name}\n
\n
${e.name}
\n
${e.name_es||e.source||""}
\n
\n
`})).join("")}catch(e){t.innerHTML='

Error al buscar diagramas

'}}else t.innerHTML='

Ingresa un código de diagrama para buscar

'}async function openHotspotEditor(e){currentEditorDiagramId=e,document.getElementById("hotspotEditorArea").style.display="block";try{const t=await fetch(`/api/diagrams/${e}`),a=await t.json();document.getElementById("hotspotEditorTitle").textContent=`${a.name} - ${a.name_es||a.group_name||""}`;const n=a.image_url||(a.image_path?"/"+a.image_path:"");document.getElementById("hotspotEditorImg").src=n,currentEditorHotspots=a.hotspots||[],renderEditorHotspots(),clearHotspotForm();const r=currentEditorHotspots.reduce(((e,t)=>Math.max(e,t.callout_number||0)),0);document.getElementById("hsCallout").value=r+1,document.getElementById("hotspotEditorArea").scrollIntoView({behavior:"smooth"})}catch(e){showAlert("Error al cargar diagrama","error")}}function closeHotspotEditor(){document.getElementById("hotspotEditorArea").style.display="none",currentEditorDiagramId=null,currentEditorHotspots=[]}function onHotspotImageClick(e){const t=e.target.getBoundingClientRect(),a=((e.clientX-t.left)/t.width*100).toFixed(2),n=((e.clientY-t.top)/t.height*100).toFixed(2);document.getElementById("hsCoords").value=`${a},${n}`,renderEditorHotspots();const r=document.getElementById("hotspotMarkersContainer"),o=document.createElement("div");o.style.cssText=`position:absolute;left:${a}%;top:${n}%;width:24px;height:24px;border-radius:50%;background:rgba(46,204,113,0.5);border:2px solid #2ecc71;transform:translate(-50%,-50%);pointer-events:none;z-index:10`,r.appendChild(o)}function renderEditorHotspots(){const e=document.getElementById("hotspotMarkersContainer"),t=document.getElementById("hotspotsList");e.innerHTML=currentEditorHotspots.map((e=>{const t=(e.coords||"").split(",");return t.length<2?"":`
${e.callout_number||""}
`})).join(""),0!==currentEditorHotspots.length?t.innerHTML=currentEditorHotspots.map((e=>`\n
\n ${e.callout_number||"?"}\n
\n
${e.part_name||e.label||"Sin parte"}
\n
${e.part_number||""} | ${e.coords}
\n
\n \n \n
\n `)).join(""):t.innerHTML='

No hay hotspots

'}function editHotspot(e){const t=currentEditorHotspots.find((t=>t.id===e));t&&(document.getElementById("hsEditId").value=t.id,document.getElementById("hsCoords").value=t.coords||"",document.getElementById("hsCallout").value=t.callout_number||"",document.getElementById("hsLabel").value=t.label||"",document.getElementById("hsPartId").value=t.part_id||"",document.getElementById("hsPartSearch").value=t.part_name?`${t.part_number} - ${t.part_name}`:"")}function clearHotspotForm(){document.getElementById("hsEditId").value="",document.getElementById("hsCoords").value="",document.getElementById("hsLabel").value="",document.getElementById("hsPartId").value="",document.getElementById("hsPartSearch").value="",document.getElementById("hsPartSelect").style.display="none";const e=currentEditorHotspots.reduce(((e,t)=>Math.max(e,t.callout_number||0)),0);document.getElementById("hsCallout").value=e+1}async function searchPartsForHotspot(e){clearTimeout(partSearchTimeout);const t=document.getElementById("hsPartSelect");!e||e.length<2?t.style.display="none":partSearchTimeout=setTimeout((async()=>{try{const a=await fetch(`/api/parts?search=${encodeURIComponent(e)}&per_page=20`),n=await a.json(),r=n.data||n;0===r.length?t.innerHTML="":t.innerHTML=r.map((e=>``)).join(""),t.style.display="block",t.onchange=function(){const e=t.options[t.selectedIndex];document.getElementById("hsPartId").value=e.value,document.getElementById("hsPartSearch").value=e.textContent,t.style.display="none"}}catch(e){t.innerHTML="",t.style.display="block"}}),300)}async function saveHotspot(){const e=document.getElementById("hsEditId").value,t=document.getElementById("hsCoords").value.trim(),a=parseInt(document.getElementById("hsCallout").value)||null,n=parseInt(document.getElementById("hsPartId").value)||null,r=document.getElementById("hsLabel").value.trim();if(!t)return void showAlert("Haz clic en la imagen para seleccionar posición","error");const o={diagram_id:currentEditorDiagramId,coords:t,callout_number:a,part_id:n,label:r,shape:"circle",color:"#e74c3c"};try{let t;t=e?await fetch(`/api/admin/hotspots/${e}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}):await fetch("/api/admin/hotspots",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});const a=await t.json();if(!t.ok)throw new Error(a.error||"Error al guardar");showAlert(e?"Hotspot actualizado":"Hotspot creado"),await openHotspotEditor(currentEditorDiagramId)}catch(e){showAlert(e.message,"error")}}async function deleteHotspot(e){if(confirm("Eliminar este hotspot?"))try{const t=await fetch(`/api/admin/hotspots/${e}`,{method:"DELETE"}),a=await t.json();if(!t.ok)throw new Error(a.error||"Error al eliminar");showAlert("Hotspot eliminado"),await openHotspotEditor(currentEditorDiagramId)}catch(e){showAlert(e.message,"error")}}const roleBadgeColors={ADMIN:"#3b82f6",OWNER:"#8b5cf6",TALLER:"#22c55e",BODEGA:"#f59e0b"};function formatDate(e){if(!e)return'Nunca';var t=new Date(e);return isNaN(t.getTime())?e:t.toLocaleDateString("es-MX",{year:"numeric",month:"short",day:"numeric"})+" "+t.toLocaleTimeString("es-MX",{hour:"2-digit",minute:"2-digit"})}function getRoleBadge(e){return''+(e||"N/A")+""}function getActiveBadge(e){return e?'Activo':'Inactivo'}async function loadUsers(){var e=localStorage.getItem("access_token"),t=document.getElementById("usersTable");t.innerHTML='
';try{var a=await fetch("/api/admin/users",{headers:{Authorization:"Bearer "+e}});if(!a.ok)throw new Error("Error al cargar usuarios ("+a.status+")");var n=await a.json(),r=Array.isArray(n)?n:n.data||[],o=r.filter((function(e){return!e.is_active})).length,i=document.getElementById("pendingUsersBadge");if(i&&(o>0?(i.textContent=o,i.style.display="inline-block"):i.style.display="none"),0===r.length)return void(t.innerHTML='No hay usuarios registrados');t.innerHTML=r.map((function(e){var t=e.is_active?"Desactivar":"Activar",a=e.is_active?"btn-secondary":"btn-primary";return""+(e.name||e.nombre||"-")+""+(e.email||"-")+""+(e.business_name||e.negocio||"-")+""+getRoleBadge(e.role||e.rol)+""+getActiveBadge(e.is_active)+""+formatDate(e.last_login||e.ultimo_login)+'"})).join("")}catch(e){t.innerHTML=''+e.message+""}}async function toggleUserActive(e,t){var a=localStorage.getItem("access_token");if(confirm("¿Seguro que deseas "+(t?"desactivar":"activar")+" este usuario?"))try{var n=await fetch("/api/admin/users/"+e+"/activate",{method:"PUT",headers:{"Content-Type":"application/json",Authorization:"Bearer "+a},body:JSON.stringify({is_active:!t})});if(!n.ok){var r=await n.json();throw new Error(r.error||"Error al actualizar usuario")}showAlert("Usuario "+(t?"desactivado":"activado")+" correctamente"),loadUsers()}catch(e){showAlert(e.message,"error")}}