(function($){
'use strict';
if(!$||typeof base_url==='undefined')return;
var panel=$('#chatPanel'),usersEl=$('#chatUsers'),messagesEl=$('#chatMessages'),input=$('#chatInput'),attachmentInput=$('#chatAttachment'),attachmentFile=null,previewUrl=null,chatSound=String(panel.data('notification-sound')||'classic');
var state={open:false,user:null,users:[],lastId:0,knownUnread:0,initialized:false,typing:false,typingTimer:null,busy:false,sending:false,disabled:false};
var audioCtx=null;
function esc(v){return $('<div>').text(v==null?'':String(v)).html();}
function dateValue(v){return v?new Date(String(v).replace(' ','T')):null;}
function time(v){var d=dateValue(v);return d&&!isNaN(d)?d.toLocaleTimeString('id-ID',{hour:'2-digit',minute:'2-digit'}):'';}
function lastActive(v){var d=dateValue(v);if(!d||isNaN(d))return 'Belum pernah aktif';var s=Math.max(0,Math.floor((Date.now()-d.getTime())/1000));if(s<90)return 'Online';if(s<3600)return 'Aktif '+Math.floor(s/60)+' menit lalu';if(s<86400)return 'Aktif '+Math.floor(s/3600)+' jam lalu';return 'Terakhir aktif '+d.toLocaleDateString('id-ID',{day:'numeric',month:'short'})+' '+time(v);}
function unlockAudio(){if(!audioCtx)try{audioCtx=new(window.AudioContext||window.webkitAudioContext)();}catch(e){}if(audioCtx&&audioCtx.state==='suspended')audioCtx.resume();}
function beep(){if(chatSound==='silent'||!audioCtx||audioCtx.state!=='running')return;function tone(frequency,start,duration,volume){var o=audioCtx.createOscillator(),g=audioCtx.createGain();o.type='sine';o.frequency.value=frequency;g.gain.setValueAtTime(.0001,audioCtx.currentTime+start);g.gain.exponentialRampToValueAtTime(volume,audioCtx.currentTime+start+.012);g.gain.exponentialRampToValueAtTime(.0001,audioCtx.currentTime+start+duration);o.connect(g);g.connect(audioCtx.destination);o.start(audioCtx.currentTime+start);o.stop(audioCtx.currentTime+start+duration+.02);}if(chatSound==='soft')tone(520,0,.28,.075);else if(chatSound==='double'){tone(660,0,.16,.1);tone(880,.18,.2,.1);}else tone(720,0,.23,.12);}
$(document).one('click keydown touchstart',unlockAudio);
function badge(n){n=parseInt(n||0,10);$('#chatNavBadge').text(n>99?'99+':n).toggle(n>0);}
function userInitials(u){return String(u.nama_lengkap||'?').trim().split(/\s+/).slice(0,2).map(function(x){return x.charAt(0)}).join('').toUpperCase()||'?';}
function avatarContent(u){return u.photo_url?'<img class="chat-avatar-image" src="'+esc(u.photo_url)+'" alt="Foto profil '+esc(u.nama_lengkap)+'">':esc(userInitials(u));}
function setHeaderAvatar(u){$('#chatHeaderAvatar').html(u.photo_url?'<img class="chat-avatar-image" src="'+esc(u.photo_url)+'" alt="Foto profil '+esc(u.nama_lengkap)+'">':esc(userInitials(u)));}
function renderUsers(filter){filter=(filter||'').toLowerCase().trim();var html='',online=state.users.filter(function(u){return u.online;}).length;$('#chatOnlineSummary').text(online+' online · '+state.users.length+' pengguna');state.users.forEach(function(u){if(String(u.nama_lengkap).toLowerCase().indexOf(filter)<0)return;var role=String(u.level||'pengguna').replace(/_/g,' '),status=u.online?'Sedang online':lastActive(u.last_activity);html+='<button type="button" class="chat-user" data-id="'+u.id+'" aria-label="Buka percakapan"><span class="chat-avatar">'+avatarContent(u)+'<i class="chat-presence '+(u.online?'online':'')+'"></i></span><span class="chat-user-info"><span class="chat-user-primary"><span class="chat-user-name">'+esc(u.nama_lengkap)+'</span><span class="chat-user-role">'+esc(role)+'</span></span><span class="chat-user-status '+(u.online?'is-online':'')+'">'+esc(status)+'</span></span><span class="chat-user-trailing">'+(u.unread>0?'<span class="chat-user-unread">'+(u.unread>99?'99+':u.unread)+'</span>':'<i class="fa fa-angle-right chat-user-chevron"></i>')+'</span></button>';});usersEl.html(html||'<div class="chat-empty"><span class="chat-empty-icon"><i class="fa fa-user-o"></i></span><strong>'+(filter?'Pengguna tidak ditemukan':'Belum ada pengguna lain')+'</strong><small>'+(filter?'Coba gunakan kata pencarian lain':'Pengguna aktif akan tampil di sini')+'</small></div>');}
function disableChatClient(){state.disabled=true;state.open=false;$('#chatNavButton').closest('li').remove();$('#chatPanel,#chatBackdrop').remove();}
function chatRequestFailed(xhr){if(xhr&&xhr.status===403&&xhr.responseJSON&&xhr.responseJSON.chat_enabled===false)disableChatClient();}
function loadUsers(){if(state.disabled||document.hidden)return;$.post(base_url+'chat/users',{},null,'json').done(function(res){var old=state.knownUnread||0;state.users=res.users||[];state.knownUnread=parseInt(res.unread_total||0,10);badge(state.knownUnread);renderUsers($('#chatSearch').val());if(state.initialized&&state.knownUnread>old)beep();state.initialized=true;if(state.user){var current=state.users.find(function(u){return u.id===state.user.id});if(current){state.user=current;setHeaderAvatar(current);$('#chatSubtitle').text(current.online?'Sedang online':lastActive(current.last_activity));}}}).fail(chatRequestFailed);}
function receipt(m){if(m.read_at)return '<i class="fa fa-check-circle" title="Sudah dibaca"></i>';if(m.delivered_at)return '<i class="fa fa-check" title="Terkirim"></i>';return '<i class="fa fa-clock-o" title="Mengirim"></i>';}
function fileSize(bytes){bytes=parseInt(bytes||0,10);if(bytes<1024)return bytes+' B';if(bytes<1048576)return(bytes/1024).toFixed(1)+' KB';return(bytes/1048576).toFixed(1)+' MB';}
function attachmentHtml(m){if(!m.attachment_path)return '';var url=base_url+String(m.attachment_path).replace(/^\/+/,''),name=esc(m.attachment_name||'Lampiran');if(m.attachment_type==='image')return '<a class="chat-image-lightbox" href="'+esc(url)+'" data-title="'+name+'"><img class="chat-attachment-image" src="'+esc(url)+'" alt="'+name+'" loading="lazy"></a>';return '<a class="chat-file-card" href="'+esc(url)+'" target="_blank" rel="noopener" download><i class="fa fa-file-o"></i><span class="chat-file-details"><span class="chat-file-name">'+name+'</span><span class="chat-file-size">'+fileSize(m.attachment_size)+'</span></span></a>';}
function openChatLightbox(link){if(typeof GLightbox!=='function'||!link||typeof link.getAttribute!=='function')return false;var lightbox=GLightbox({selector:'.chat-image-lightbox',loop:true,touchNavigation:true,keyboardNavigation:true,closeOnOutsideClick:true,onClose:function(){lightbox.destroy();}});lightbox.open(link);return true;}
function appendMessages(rows,replace){if(replace)messagesEl.empty();var nearBottom=messagesEl[0].scrollHeight-messagesEl.scrollTop()-messagesEl.outerHeight()<80;(rows||[]).forEach(function(m){if($('#chat-msg-'+m.id).length){$('#chat-msg-'+m.id+' .chat-receipt').html(receipt(m));return;}var mine=m.sender_id===parseInt(''+window.chatCurrentUserId,10),content=attachmentHtml(m)+(m.message?'<div>'+esc(m.message)+'</div>':'');messagesEl.append('<div class="chat-message '+(mine?'mine':'')+'" id="chat-msg-'+m.id+'"><div class="chat-bubble">'+content+'<div class="chat-meta">'+time(m.created_at)+(mine?' <span class="chat-receipt">'+receipt(m)+'</span>':'')+'</div></div></div>');state.lastId=Math.max(state.lastId,m.id);});if(replace||nearBottom)messagesEl.scrollTop(messagesEl[0].scrollHeight);}
function loadMessages(initial){if(state.disabled||!state.open||!state.user||document.hidden||state.busy)return;state.busy=true;$.post(base_url+'chat/messages',{user_id:state.user.id,after_id:initial?0:state.lastId,mark_read:1},null,'json').done(function(res){appendMessages(res.messages||[],initial);(res.receipts||[]).forEach(function(m){$('#chat-msg-'+m.id+' .chat-receipt').html(receipt(m));});$('#chatTyping').text(res.typing?state.user.nama_lengkap+' sedang mengetik...':'');if(!initial&&res.messages&&res.messages.some(function(m){return m.sender_id===state.user.id}))beep();loadUsers();}).fail(chatRequestFailed).always(function(){state.busy=false;});}
function openPanel(){unlockAudio();state.open=true;panel.addClass('open').attr('aria-hidden','false');$('#chatBackdrop').addClass('show').attr('aria-hidden','false');loadUsers();}
function closePanel(){state.open=false;panel.removeClass('open').attr('aria-hidden','true');$('#chatBackdrop').removeClass('show').attr('aria-hidden','true');stopTyping();}
function chooseUser(id){var u=state.users.find(function(x){return x.id===id});if(!u)return;state.user=u;state.lastId=0;panel.addClass('in-conversation');setHeaderAvatar(u);$('#chatTitle').text(u.nama_lengkap);$('#chatSubtitle').text(u.online?'Sedang online':lastActive(u.last_activity));messagesEl.empty();loadMessages(true);input.focus();}
function stopTyping(){if(!state.typing||!state.user)return;state.typing=false;clearTimeout(state.typingTimer);$.post(base_url+'chat/typing',{user_id:state.user.id,active:0});}
function signalTyping(){if(!state.user)return;if(!state.typing){state.typing=true;$.post(base_url+'chat/typing',{user_id:state.user.id,active:1});}clearTimeout(state.typingTimer);state.typingTimer=setTimeout(stopTyping,2500);}
function clearAttachment(){attachmentFile=null;attachmentInput.val('');if(previewUrl){URL.revokeObjectURL(previewUrl);previewUrl=null;}$('#chatAttachmentPreview').removeClass('show').empty();}
function showAttachment(file){if(!file)return;if(file.size>10485760){if(typeof notif==='function')notif('Ukuran lampiran maksimal 10 MB','danger');return;}var image=/^image\/(jpeg|png|gif|webp)$/.test(file.type);if(!image&&(!file.name||! /\.(pdf|docx?|xlsx?|txt|csv|zip|rar)$/i.test(file.name))){if(typeof notif==='function')notif('Tipe lampiran tidak didukung','danger');return;}clearAttachment();attachmentFile=file;if(!attachmentFile.name&&image)attachmentFile=new File([file],'gambar-clipboard.png',{type:file.type||'image/png'});var visual='';if(image){previewUrl=URL.createObjectURL(attachmentFile);visual='<img class="chat-preview-thumb" src="'+previewUrl+'" alt="Preview">';}else visual='<span class="chat-preview-icon"><i class="fa fa-file-o"></i></span>';$('#chatAttachmentPreview').html(visual+'<span class="chat-preview-info"><span class="chat-preview-name">'+esc(attachmentFile.name||'gambar-clipboard.png')+'</span><span class="chat-preview-size">'+fileSize(attachmentFile.size)+(image?' · akan dikonversi ke WebP':'')+'</span></span><button type="button" class="chat-preview-remove" aria-label="Hapus lampiran"><i class="fa fa-times"></i></button>').addClass('show');}
function errorMessage(xhr){if(xhr&&xhr.responseJSON&&xhr.responseJSON.message)return xhr.responseJSON.message;var raw=xhr&&xhr.responseText?String(xhr.responseText):'';if(raw){try{var parsed=JSON.parse(raw);if(parsed.message)return parsed.message;}catch(e){}var match=raw.match(/"message"\s*:\s*"([^"]+)"/);if(match)return match[1];}if(xhr&&xhr.status===0)return 'Koneksi terputus. Periksa jaringan lalu kirim ulang';if(xhr&&xhr.status===413)return 'Ukuran lampiran terlalu besar';return 'Pesan gagal dikirim';}
function send(){if(state.disabled||!state.user||state.sending)return;var value=input.val().trim();if(!value&&!attachmentFile)return;state.sending=true;var data=new FormData();data.append('user_id',state.user.id);data.append('message',value);if(attachmentFile)data.append('attachment',attachmentFile,attachmentFile.name||'gambar-clipboard.png');$('#chatSend').prop('disabled',true).html('<i class="fa fa-spinner fa-spin"></i>');$.ajax({url:base_url+'chat/send',method:'POST',data:data,dataType:'json',processData:false,contentType:false,timeout:60000}).done(function(res){if(!res||!res.message){if(typeof notif==='function')notif('Respons pengiriman tidak valid','danger');return;}input.val('').css('height','auto');clearAttachment();stopTyping();appendMessages([res.message],false);}).fail(function(xhr){chatRequestFailed(xhr);if(!state.disabled&&typeof notif==='function')notif(errorMessage(xhr),'danger');}).always(function(){state.sending=false;$('#chatSend').prop('disabled',false).html('<i class="fa fa-paper-plane"></i>');if(!state.disabled)input.focus();});}
var emojis='😀 😃 😄 😁 😆 😅 😂 😊 🙂 🙃 😉 😍 🥰 😘 😋 😎 🤩 🥳 😢 😭 😤 😡 🤔 🤭 🤗 😴 🙏 👍 👎 👌 ✌️ 🤝 👏 💪 ❤️ 🧡 💛 💚 💙 💜 💯 🔥 ✨ 🎉 ✅ ❌ ⚠️ 📌 📎 📷 💬 🚀 ☕ 🎂'.split(' ');$('#chatEmojiPicker').html(emojis.map(function(e){return '<button type="button" class="chat-emoji" data-emoji="'+e+'">'+e+'</button>';}).join(''));
$('#chatNavButton').on('click',function(e){e.preventDefault();state.open?closePanel():openPanel();});$('#chatClose,#chatBackdrop').on('click',closePanel);$('#chatSearch').on('input',function(){renderUsers(this.value);$('#chatSearchClear').toggle(!!this.value);});$('#chatSearchClear').on('click',function(){$('#chatSearch').val('').trigger('input').focus();});usersEl.on('click','.chat-user',function(){chooseUser(parseInt($(this).data('id'),10))});$('#chatBackButton').on('click',function(){stopTyping();clearAttachment();state.user=null;panel.removeClass('in-conversation');$('#chatHeaderAvatar').html('<i class="fa fa-comments"></i>');$('#chatTitle').text('Chat Pengguna');$('#chatSubtitle').text('Pilih rekan kerja untuk memulai percakapan');loadUsers();});$('#chatSend').on('click',send);$('#chatEmojiButton').on('click',function(){$('#chatEmojiPicker').toggleClass('show')});$('#chatEmojiPicker').on('click','.chat-emoji',function(){var el=input[0],emoji=$(this).data('emoji'),start=el.selectionStart||0,end=el.selectionEnd||0,value=input.val();input.val(value.slice(0,start)+emoji+value.slice(end));el.selectionStart=el.selectionEnd=start+emoji.length;$('#chatEmojiPicker').removeClass('show');input.focus();signalTyping();});$('#chatAttachButton').on('click',function(){attachmentInput.trigger('click')});attachmentInput.on('change',function(){showAttachment(this.files&&this.files[0])});$('#chatAttachmentPreview').on('click','.chat-preview-remove',clearAttachment);input.on('paste',function(e){var clipboard=e.originalEvent&&e.originalEvent.clipboardData;if(!clipboard||!clipboard.items)return;for(var i=0;i<clipboard.items.length;i++){var item=clipboard.items[i];if(item.kind==='file'&&/^image\//.test(item.type)){e.preventDefault();var pasted=item.getAsFile();if(pasted)showAttachment(new File([pasted],'gambar-clipboard-'+Date.now()+'.png',{type:pasted.type||'image/png'}));return;}}}).on('keydown',function(e){if(e.isComposing||e.keyCode===229)return;if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();if(!e.repeat)send();}else signalTyping();}).on('input',function(){this.style.height='auto';this.style.height=Math.min(this.scrollHeight,110)+'px';signalTyping();});
messagesEl.on('click','.chat-image-lightbox',function(e){e.preventDefault();if(!openChatLightbox(this)&&typeof notif==='function')notif('Preview gambar tidak dapat dibuka','danger');});
window.chatCurrentUserId=parseInt(panel.data('current-user'),10);loadUsers();setInterval(loadUsers,5000);setInterval(function(){loadMessages(false)},2500);document.addEventListener('visibilitychange',function(){if(!document.hidden){loadUsers();loadMessages(false);}});
})(window.jQuery);
