jQuery(function($){
function setMain($wrap, url){
const $img=$wrap.find('.cosmod-main-img img');
if($img.length&&url) $img.attr('src', url);
}
$(document).on('click', '.cosmod-sp .cosmod-thumbs .thumb', function(){
const $btn=$(this);
const $wrap=$btn.closest('.cosmod-sp');
const url=$btn.find('img').data('full')||$btn.find('img').attr('src');
if(url) setMain($wrap, url);
$btn.addClass('active').siblings().removeClass('active');
});
$(document).on('click', '.cosmod-sp .cosmod-nav .next, .cosmod-sp .cosmod-nav .prev', function(){
const $wrap=$(this).closest('.cosmod-sp');
const $thumbs=$wrap.find('.cosmod-thumbs .thumb');
if(!$thumbs.length) return;
const $active=$thumbs.filter('.active');
let idx=$active.length ? $thumbs.index($active):0;
idx=$(this).hasClass('next') ? idx + 1:idx - 1;
if(idx < 0) idx=$thumbs.length - 1;
if(idx >=$thumbs.length) idx=0;
$thumbs.eq(idx).trigger('click');
});
(function(){
let startX=0, tracking=false;
$(document).on('touchstart', '.cosmod-main-img', function(e){
if(!e.originalEvent.touches) return;
tracking=true; startX=e.originalEvent.touches[0].clientX;
});
$(document).on('touchmove', '.cosmod-main-img', function(e){
if(!tracking||!e.originalEvent.touches) return;
const dx=e.originalEvent.touches[0].clientX - startX;
if(Math.abs(dx) > 40){
$(this).find(dx < 0 ? '.next':'.prev').trigger('click');
tracking=false;
}});
$(document).on('touchend', '.cosmod-main-img', function(){ tracking=false; });
})();
const Zoom={
$z: null, $img: null, images: [], idx: 0, $wrap: null,
open($wrap, startSrc){
this.$z=$('.cosmod-zoom');
this.$img=this.$z.find('img');
this.$wrap=$wrap;
try { this.images=JSON.parse($wrap.attr('data-images')||'[]'); } catch(e){ this.images=[]; }
if(!this.images.length){
const cur=startSrc||$wrap.find('.cosmod-main-img img').attr('src');
if(cur) this.images=[cur];
}
const $active=$wrap.find('.cosmod-thumbs .thumb.active');
if($active.length){
this.idx=$wrap.find('.cosmod-thumbs .thumb').index($active);
}else{
const cur=startSrc||$wrap.find('.cosmod-main-img img').attr('src');
const found=this.images.findIndex(u=> u===cur);
this.idx=found >=0 ? found:0;
}
this.show(this.idx);
$('html,body').css('overflow','hidden');
this.$z.attr('aria-hidden','false').addClass('show');
this.$z.find('.zprev,.znext').toggle(this.images.length > 1);
},
close(){
if(!this.$z) return;
this.$z.attr('aria-hidden','true').removeClass('show');
$('html,body').css('overflow','');
},
show(i){
if(!this.images.length) return;
if(i < 0) i=this.images.length - 1;
if(i >=this.images.length) i=0;
this.idx=i;
this.$img.attr('src', this.images[this.idx]);
},
next(){ this.show(this.idx + 1); },
prev(){ this.show(this.idx - 1); }};
$(document).on('click', '.cosmod-main-img img', function(){
Zoom.open($(this).closest('.cosmod-sp'), $(this).attr('src'));
});
$(document).on('click', '.cosmod-zoom .znext', function(e){ e.stopPropagation(); Zoom.next(); });
$(document).on('click', '.cosmod-zoom .zprev', function(e){ e.stopPropagation(); Zoom.prev(); });
$(document).on('click', '.cosmod-zoom .close, .cosmod-zoom', function(e){
if($(e.target).is('.cosmod-zoom .close')||$(e.target).is('.cosmod-zoom')){
Zoom.close();
}});
$(document).on('keyup', function(e){
if(!$('.cosmod-zoom').hasClass('show')) return;
if(e.key==='Escape') Zoom.close();
if(e.key==='ArrowRight') Zoom.next();
if(e.key==='ArrowLeft')  Zoom.prev();
});
(function(){
let startX=0, tracking=false;
$(document).on('touchstart', '.cosmod-zoom', function(ev){
if(!ev.originalEvent.touches) return;
tracking=true; startX=ev.originalEvent.touches[0].clientX;
});
$(document).on('touchmove', '.cosmod-zoom', function(ev){
if(!tracking||!ev.originalEvent.touches) return;
const dx=ev.originalEvent.touches[0].clientX - startX;
if(Math.abs(dx) > 40){
if(dx < 0) Zoom.next(); else Zoom.prev();
tracking=false;
}});
$(document).on('touchend', '.cosmod-zoom', function(){ tracking=false; });
})();
function clampQty($input){
const min=parseInt($input.attr('min')||1, 10);
const maxA=$input.attr('max');
const dMax=parseInt($input.data('max')||0, 10);
const max=maxA ? parseInt(maxA, 10):(dMax > 0 ? dMax:Infinity);
let val=parseInt(String($input.val()).replace(/\D/g,''), 10);
if(isNaN(val)) val=min;
if(val < min) val=min;
if(val > max) val=max;
$input.val(val);
const atMax=(max!==Infinity)&&(val >=max);
$input.closest('.cosmod-qty').find('.plus').prop('disabled', atMax).attr('aria-disabled', atMax ? 'true':'false');
return val;
}
$(document).on('click', '.cosmod-qty .plus, .cosmod-qty .minus', function(){
const $input=$(this).closest('.cosmod-qty').find('input.qty');
const min=parseInt($input.attr('min')||1, 10);
const maxA=$input.attr('max');
const dMax=parseInt($input.data('max')||0, 10);
const max=maxA ? parseInt(maxA, 10):(dMax > 0 ? dMax:Infinity);
let val=clampQty($input);
if($(this).hasClass('plus')){ if(val < max) val++; }else{ if(val > min) val--; }
$input.val(val); clampQty($input);
});
$(document).on('input change', '.cosmod-qty .qty', function(){ clampQty($(this)); });
$('.cosmod-qty .qty').each(function(){ clampQty($(this)); });
$(document).on('click', '.cosmod-sp .add-to-cart', function(e){
e.preventDefault();
const $btn=$(this);
const $box=$btn.closest('.cosmod-sp');
const productId=parseInt($btn.attr('data-product-id'), 10);
const qty=clampQty($box.find('.cosmod-qty .qty'));
if(!productId||qty < 1){
console.log('Product ID error', productId);
return;
}
$.ajax({
url: '/wp-admin/admin-ajax.php',
type: 'POST',
dataType: 'json',
data: {
action: 'cosmod_add_to_cart',
product_id: productId,
quantity: qty
},
success: function(resp){
console.log('AJAX OK', resp);
if(resp.fragments){
$.each(resp.fragments, function(k, v){
$(k).replaceWith(v);
});
$(document.body).trigger('added_to_cart', [resp.fragments, resp.cart_hash, $btn]);
}},
error: function(err){
console.log('AJAX error', err);
}});
});
const LS_KEY='cosmod_wishlist';
function getWL(){ try{ return JSON.parse(localStorage.getItem(LS_KEY)||'[]'); }catch(e){ return []; }}
function setWL(arr){ localStorage.setItem(LS_KEY, JSON.stringify(arr)); }
function toggleWL(id){ let wl=getWL(); const i=wl.indexOf(id); if(i===-1) wl.push(id); else wl.splice(i,1); setWL(wl); return wl.indexOf(id)!==-1; }
function renderWLState($btn, id){
const inWL=getWL().indexOf(id)!==-1;
$btn.toggleClass('in', inWL).toggleClass('active', inWL)
.attr('aria-pressed', inWL ? 'true':'false')
.attr('title', (window.CosmodI18N&&(inWL ? CosmodI18N.wl_in:CosmodI18N.wl_add))||'');
}
$(document).on('click', '.cosmod-like', function(){
const $b=$(this); const id=parseInt($b.data('id'), 10);
toggleWL(id); renderWLState($b, id);
});
$('.cosmod-like').each(function(){ renderWLState($(this), parseInt($(this).data('id'),10)); });
$(document).on('click', '.cosmod-tabs .tab', function(){
const $t=$(this), $wrap=$t.closest('.cosmod-tabs');
$wrap.find('.tab').removeClass('active').attr('aria-selected','false');
$t.addClass('active').attr('aria-selected','true');
const target=$t.data('tab');
$wrap.find('.panel').removeClass('show');
$wrap.find('#tab-'+target).addClass('show');
});
(function(){
let down=false, sx=0, sl=0, moved=false;
$(document).on('mousedown touchstart', '.cosmod-thumbs', function(e){
down=true; moved=false;
const ev=e.originalEvent.touches?e.originalEvent.touches[0]:e;
sx=ev.clientX; sl=this.scrollLeft;
$(this).addClass('dragging');
});
$(document).on('mousemove touchmove', '.cosmod-thumbs', function(e){
if(!down) return;
const ev=e.originalEvent.touches?e.originalEvent.touches[0]:e;
const dx=ev.clientX-sx; if(Math.abs(dx)>3) moved=true;
this.scrollLeft=sl - dx;
});
$(document).on('mouseleave mouseup touchend', '.cosmod-thumbs', function(){
down=false; $(this).removeClass('dragging');
});
$(document).on('click', '.cosmod-thumbs .thumb', function(e){
if(moved){ e.preventDefault(); e.stopImmediatePropagation(); }
moved=false;
});
})();
});