const fs = require('fs');
const ytdl = require('ytdl-core-enhanced');
const { resolve } = require('path');
const { createCanvas, loadImage, registerFont } = require('canvas');
const axios = require('axios');
const path = require('path');

function extractVideoId(url) {
  const patterns = [
    /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/v\/)([^&\n?#]+)/,
    /^([a-zA-Z0-9_-]{11})$/ 
  ];
  
  for (const pattern of patterns) {
    const match = url.match(pattern);
    if (match) return match[1];
  }
  return null;
}

function isYouTubeUrlOrId(input) {
  return extractVideoId(input) !== null;
}

function durationToSeconds(duration) {
  if (!duration || duration === "N/A") return 0;
  
  const parts = duration.split(':').reverse();
  let seconds = 0;
  
  for (let i = 0; i < parts.length; i++) {
    seconds += parseInt(parts[i]) * Math.pow(60, i);
  }
  
  return seconds;
}
function filterVideosByDuration(videos, maxDurationMinutes = 23) {
  const maxSeconds = maxDurationMinutes * 60;
  
  return videos.filter(video => {
    let duration = "N/A";
    
    if (video.length && video.length.simpleText) {
      duration = video.length.simpleText;
    } else if (video.length) {
      duration = video.length.toString();
    } else if (video.lengthText) {
      duration = video.lengthText;
    } else if (video.lengthSeconds) {
      const minutes = Math.floor(video.lengthSeconds / 60);
      const seconds = video.lengthSeconds % 60;
      duration = `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
    }
    
    const durationInSeconds = durationToSeconds(duration);
    return durationInSeconds > 0 && durationInSeconds <= maxSeconds;
  });
}

async function getCachedBackground() {
  const backgrounds = [
    "http://vanthuankk.io.vn/1752417707835_x4lztg.jpg",
    "http://vanthuankk.io.vn/1752417779463_scpurq.jpg", 
    "http://vanthuankk.io.vn/1752417802639_vovq0e.jpg",
    "http://vanthuankk.io.vn/1752417842408_1i3ups.jpg",
    "http://vanthuankk.io.vn/1752417862731_8nxtc6.jpg"
  ];
  
  const randomBg = backgrounds[Math.floor(Math.random() * backgrounds.length)];
  const bgFileName = randomBg.split('/').pop();
  const bgCachePath = `${__dirname}/cache/backgrounds`;
  
  if (!fs.existsSync(bgCachePath)) {
    fs.mkdirSync(bgCachePath, { recursive: true });
  }
  
  const cachedBgPath = path.join(bgCachePath, bgFileName);
  
  if (fs.existsSync(cachedBgPath)) {
    return cachedBgPath;
  }
  
  try {
    const response = await axios.get(randomBg, { 
      responseType: 'arraybuffer',
      timeout: 15000 
    });
    fs.writeFileSync(cachedBgPath, Buffer.from(response.data));
    return cachedBgPath;
  } catch (error) {
    console.error("Error downloading background:", error);
    const existingBgs = fs.readdirSync(bgCachePath);
    if (existingBgs.length > 0) {
      return path.join(bgCachePath, existingBgs[0]);
    }
    throw error;
  }
}

function formatNumber(num) {
  if (num >= 1000000000) {
    return (num / 1000000000).toFixed(1) + 'B';
  }
  if (num >= 1000000) {
    return (num / 1000000).toFixed(1) + 'M';
  }
  if (num >= 1000) {
    return (num / 1000).toFixed(1) + 'K';
  }
  return num.toString();
}

function truncateText(text, maxLength) {
  if (text.length <= maxLength) return text;
  return text.substring(0, maxLength - 3) + '...';
}

async function downloadThumbnail(videoId, savePath) {
  try {
    const thumbnailUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
    const response = await axios({
      method: 'GET',
      url: thumbnailUrl,
      responseType: 'arraybuffer'
    });
    
    fs.writeFileSync(savePath, response.data);
    return true;
  } catch (error) {
    console.log('Error downloading thumbnail:', error);
    return false;
  }
}

async function createMusicPlayerCanvas(data, userName, videoId) {
  const width = 800;
  const height = 400;
  const canvas = createCanvas(width, height);
  const ctx = canvas.getContext('2d');

  try {
    const backgroundPath = await getCachedBackground();
    const background = await loadImage(backgroundPath);
    
    ctx.drawImage(background, 0, 0, width, height);
    
    ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
    ctx.fillRect(0, 0, width, height);
  } catch (error) {
    console.log('Error loading background:', error);
    const gradient = ctx.createLinearGradient(0, 0, width, height);
    gradient.addColorStop(0, '#667eea');
    gradient.addColorStop(1, '#764ba2');
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
  }

  const containerX = 30;
  const containerY = 30;
  const containerWidth = width - 60;
  const containerHeight = height - 60;
  const containerRadius = 25;
  
  ctx.fillStyle = 'rgba(255, 255, 255, 0.15)';
  ctx.beginPath();
  ctx.moveTo(containerX + containerRadius, containerY);
  ctx.lineTo(containerX + containerWidth - containerRadius, containerY);
  ctx.quadraticCurveTo(containerX + containerWidth, containerY, containerX + containerWidth, containerY + containerRadius);
  ctx.lineTo(containerX + containerWidth, containerY + containerHeight - containerRadius);
  ctx.quadraticCurveTo(containerX + containerWidth, containerY + containerHeight, containerX + containerWidth - containerRadius, containerY + containerHeight);
  ctx.lineTo(containerX + containerRadius, containerY + containerHeight);
  ctx.quadraticCurveTo(containerX, containerY + containerHeight, containerX, containerY + containerHeight - containerRadius);
  ctx.lineTo(containerX, containerY + containerRadius);
  ctx.quadraticCurveTo(containerX, containerY, containerX + containerRadius, containerY);
  ctx.closePath();
  ctx.fill();
  
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
  ctx.lineWidth = 2;
  ctx.stroke();
  
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
  ctx.lineWidth = 1;
  ctx.stroke();

  const albumSize = 280;
  const albumX = containerX + 40;
  const albumY = containerY + (containerHeight - albumSize) / 2;
  
  const thumbnailPath = `${__dirname}/cache/thumb-${videoId}.jpg`;
  const thumbnailExists = await downloadThumbnail(videoId, thumbnailPath);
  
  if (thumbnailExists && fs.existsSync(thumbnailPath)) {
    try {
      const thumbnail = await loadImage(thumbnailPath);
      
      const radius = 20;
      ctx.save();
      ctx.beginPath();
      ctx.moveTo(albumX + radius, albumY);
      ctx.lineTo(albumX + albumSize - radius, albumY);
      ctx.quadraticCurveTo(albumX + albumSize, albumY, albumX + albumSize, albumY + radius);
      ctx.lineTo(albumX + albumSize, albumY + albumSize - radius);
      ctx.quadraticCurveTo(albumX + albumSize, albumY + albumSize, albumX + albumSize - radius, albumY + albumSize);
      ctx.lineTo(albumX + radius, albumY + albumSize);
      ctx.quadraticCurveTo(albumX, albumY + albumSize, albumX, albumY + albumSize - radius);
      ctx.lineTo(albumX, albumY + radius);
      ctx.quadraticCurveTo(albumX, albumY, albumX + radius, albumY);
      ctx.closePath();
      ctx.clip();
      
      ctx.drawImage(thumbnail, albumX, albumY, albumSize, albumSize);
      ctx.restore();
      
      ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(albumX + radius, albumY);
      ctx.lineTo(albumX + albumSize - radius, albumY);
      ctx.quadraticCurveTo(albumX + albumSize, albumY, albumX + albumSize, albumY + radius);
      ctx.lineTo(albumX + albumSize, albumY + albumSize - radius);
      ctx.quadraticCurveTo(albumX + albumSize, albumY + albumSize, albumX + albumSize - radius, albumY + albumSize);
      ctx.lineTo(albumX + radius, albumY + albumSize);
      ctx.quadraticCurveTo(albumX, albumY + albumSize, albumX, albumY + albumSize - radius);
      ctx.lineTo(albumX, albumY + radius);
      ctx.quadraticCurveTo(albumX, albumY, albumX + radius, albumY);
      ctx.closePath();
      ctx.stroke();
      
      fs.unlinkSync(thumbnailPath);
    } catch (error) {
      console.log('Error loading thumbnail:', error);
      const radius = 20;
      ctx.fillStyle = '#e9ecef';
      ctx.beginPath();
      ctx.moveTo(albumX + radius, albumY);
      ctx.lineTo(albumX + albumSize - radius, albumY);
      ctx.quadraticCurveTo(albumX + albumSize, albumY, albumX + albumSize, albumY + radius);
      ctx.lineTo(albumX + albumSize, albumY + albumSize - radius);
      ctx.quadraticCurveTo(albumX + albumSize, albumY + albumSize, albumX + albumSize - radius, albumY + albumSize);
      ctx.lineTo(albumX + radius, albumY + albumSize);
      ctx.quadraticCurveTo(albumX, albumY + albumSize, albumX, albumY + albumSize - radius);
      ctx.lineTo(albumX, albumY + radius);
      ctx.quadraticCurveTo(albumX, albumY, albumX + radius, albumY);
      ctx.closePath();
      ctx.fill();
      
      ctx.fillStyle = '#6c757d';
      ctx.font = '48px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('🎵', albumX + albumSize/2, albumY + albumSize/2 + 15);
    }
  } else {
    const radius = 20;
    ctx.fillStyle = '#e9ecef';
    ctx.beginPath();
    ctx.moveTo(albumX + radius, albumY);
    ctx.lineTo(albumX + albumSize - radius, albumY);
    ctx.quadraticCurveTo(albumX + albumSize, albumY, albumX + albumSize, albumY + radius);
    ctx.lineTo(albumX + albumSize, albumY + albumSize - radius);
    ctx.quadraticCurveTo(albumX + albumSize, albumY + albumSize, albumX + albumSize - radius, albumY + albumSize);
    ctx.lineTo(albumX + radius, albumY + albumSize);
    ctx.quadraticCurveTo(albumX, albumY + albumSize, albumX, albumY + albumSize - radius);
    ctx.lineTo(albumX, albumY + radius);
    ctx.quadraticCurveTo(albumX, albumY, albumX + radius, albumY);
    ctx.closePath();
    ctx.fill();
    
    ctx.fillStyle = '#6c757d';
    ctx.font = '48px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('🎵', albumX + albumSize/2, albumY + albumSize/2 + 15);
  }

  const infoX = albumX + albumSize + 50;
  const infoWidth = containerWidth - (albumSize + 90);
  let currentY = containerY + 60;

  ctx.fillStyle = '#ffffff';
  ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
  ctx.shadowBlur = 4;
  ctx.font = 'bold 32px Arial';
  ctx.textAlign = 'left';
  
  const titleMaxWidth = infoWidth - 80;
  const words = data.title.split(' ');
  const lines = [];
  let currentLine = '';
  
  for (let i = 0; i < words.length; i++) {
    const testLine = currentLine + (currentLine ? ' ' : '') + words[i];
    const metrics = ctx.measureText(testLine);
    
    if (metrics.width > titleMaxWidth && currentLine) {
      lines.push(currentLine);
      currentLine = words[i];
    } else {
      currentLine = testLine;
    }
  }
  if (currentLine) lines.push(currentLine);
  
  if (lines.length > 2) {
    lines[1] = lines[1] + '...';
    lines.splice(2);
  }
  
  for (let i = 0; i < lines.length; i++) {
    ctx.fillText(lines[i], infoX, currentY + (i * 40));
  }
  ctx.shadowBlur = 0;
  
  currentY += lines.length * 40 + 10;

  ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
  ctx.font = '20px Arial';
  const truncatedAuthor = truncateText(data.author, 35);
  ctx.fillText(truncatedAuthor, infoX, currentY);
  currentY += 40;

  ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.arc(infoX + infoWidth - 30, containerY + 70, 20, 0, Math.PI * 2);
  ctx.fill();
  ctx.stroke();
  
  ctx.fillStyle = '#dc3545';
  ctx.font = '20px Arial';
  ctx.textAlign = 'center';
  ctx.fillText('♥', infoX + infoWidth - 30, containerY + 76);

  const progressY = currentY + 20;
  const progressWidth = infoWidth - 40;
  
  ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
  ctx.fillRect(infoX, progressY - 3, progressWidth, 6);
  
  const progress = Math.random() * 0.7 + 0.1;
  ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
  ctx.fillRect(infoX, progressY - 3, progressWidth * progress, 6);
  
  ctx.fillStyle = '#ffffff';
  ctx.beginPath();
  ctx.arc(infoX + (progressWidth * progress), progressY, 8, 0, Math.PI * 2);
  ctx.fill();
  
  currentY += 60;

  const buttonY = currentY;
  const buttonSize = 40;
  const buttonSpacing = 70;
  
  function drawButtonBg(x, y, size, color = '#ffffff') {
    ctx.fillStyle = color;
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)';
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.arc(x, y, size/2, 0, Math.PI * 2);
    ctx.fill();
    ctx.stroke();
  }
  
  drawButtonBg(infoX + 25, buttonY, buttonSize);
  ctx.fillStyle = '#28a745';
  ctx.lineWidth = 2;
  ctx.strokeStyle = '#28a745';
  ctx.beginPath();
  ctx.moveTo(infoX + 15, buttonY - 5);
  ctx.lineTo(infoX + 25, buttonY - 5);
  ctx.lineTo(infoX + 22, buttonY - 8);
  ctx.moveTo(infoX + 25, buttonY - 5);
  ctx.lineTo(infoX + 22, buttonY - 2);
  ctx.moveTo(infoX + 35, buttonY + 5);
  ctx.lineTo(infoX + 25, buttonY + 5);
  ctx.lineTo(infoX + 28, buttonY + 8);
  ctx.moveTo(infoX + 25, buttonY + 5);
  ctx.lineTo(infoX + 28, buttonY + 2);
  ctx.stroke();
  
  drawButtonBg(infoX + 25 + buttonSpacing, buttonY, buttonSize);
  ctx.fillStyle = '#6f42c1';
  ctx.beginPath();
  ctx.moveTo(infoX + 25 + buttonSpacing - 8, buttonY);
  ctx.lineTo(infoX + 25 + buttonSpacing - 2, buttonY - 6);
  ctx.lineTo(infoX + 25 + buttonSpacing - 2, buttonY + 6);
  ctx.closePath();
  ctx.fill();
  ctx.beginPath();
  ctx.moveTo(infoX + 25 + buttonSpacing + 2, buttonY);
  ctx.lineTo(infoX + 25 + buttonSpacing + 8, buttonY - 6);
  ctx.lineTo(infoX + 25 + buttonSpacing + 8, buttonY + 6);
  ctx.closePath();
  ctx.fill();
  
  ctx.fillStyle = '#007bff';
  ctx.beginPath();
  ctx.arc(infoX + 25 + buttonSpacing * 2, buttonY, 28, 0, Math.PI * 2);
  ctx.fill();
  
  ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)';
  ctx.lineWidth = 1;
  ctx.stroke();
  
  ctx.fillStyle = '#ffffff';
  ctx.beginPath();
  ctx.moveTo(infoX + 25 + buttonSpacing * 2 - 6, buttonY - 10);
  ctx.lineTo(infoX + 25 + buttonSpacing * 2 - 6, buttonY + 10);
  ctx.lineTo(infoX + 25 + buttonSpacing * 2 + 10, buttonY);
  ctx.closePath();
  ctx.fill();
  
  drawButtonBg(infoX + 25 + buttonSpacing * 3, buttonY, buttonSize);
  ctx.fillStyle = '#6f42c1';
  ctx.beginPath();
  ctx.moveTo(infoX + 25 + buttonSpacing * 3 - 8, buttonY - 6);
  ctx.lineTo(infoX + 25 + buttonSpacing * 3 - 8, buttonY + 6);
  ctx.lineTo(infoX + 25 + buttonSpacing * 3 - 2, buttonY);
  ctx.closePath();
  ctx.fill();
  ctx.beginPath();
  ctx.moveTo(infoX + 25 + buttonSpacing * 3 + 2, buttonY - 6);
  ctx.lineTo(infoX + 25 + buttonSpacing * 3 + 2, buttonY + 6);
  ctx.lineTo(infoX + 25 + buttonSpacing * 3 + 8, buttonY);
  ctx.closePath();
  ctx.fill();
  
  drawButtonBg(infoX + 25 + buttonSpacing * 4, buttonY, buttonSize);
  ctx.fillStyle = '#fd7e14';
  ctx.strokeStyle = '#fd7e14';
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.arc(infoX + 25 + buttonSpacing * 4, buttonY, 8, 0, Math.PI * 1.5);
  ctx.stroke();
  ctx.fillStyle = '#fd7e14';
  ctx.beginPath();
  ctx.moveTo(infoX + 25 + buttonSpacing * 4 + 8, buttonY - 8);
  ctx.lineTo(infoX + 25 + buttonSpacing * 4 + 5, buttonY - 5);
  ctx.lineTo(infoX + 25 + buttonSpacing * 4 + 8, buttonY - 2);
  ctx.closePath();
  ctx.fill();
  
  currentY += 80;

  return canvas.toBuffer('image/png');
}

  async function downloadMusicFromYoutube(link, filePath, options = {}) {
    const timeStart = Date.now();

    if (!link) throw new Error('Thiếu link');
    if (!filePath) throw new Error('Thiếu đường dẫn file');

    try {
      await fs.promises.mkdir(path.dirname(filePath), { recursive: true }).catch(() => {});
      const videoInfo = await ytdl.getInfo(link);
      const audioFormats = ytdl.filterFormats(videoInfo.formats, 'audioonly');

      let selectedFormat =
        audioFormats.find(format =>
          format.quality === 'tiny' &&
          format.audioBitrate === 128 &&
          format.hasAudio === true
        ) ||
        audioFormats.find(format =>
          format.audioBitrate === 128 &&
          format.hasAudio === true
        ) ||
        ytdl.chooseFormat(audioFormats, { quality: 'highestaudio' });

      if (!selectedFormat) {
        throw new Error('Không tìm thấy format audio phù hợp');
      }
      const downloadOptions = {
        format: selectedFormat,
        multiThread: options.multiThread !== false,
        maxThreads: options.maxThreads || 4,
        minSizeForMultiThread: options.minSizeForMultiThread || 2 * 1024 * 1024,
        requestOptions: {
          timeout: options.timeout || 120000,
          maxRetries: 3
        }
      };
      const downloadResult = await new Promise((resolve, reject) => {
        const stream = ytdl(link, downloadOptions);
        const writeStream = fs.createWriteStream(filePath);

        let downloadedBytes = 0;
        let hasError = false;

        stream.on('progress', (chunkLength, downloaded, total) => {
          downloadedBytes = downloaded;
        });

        const handleSuccess = () => {
          if (hasError) return;
          const duration = (Date.now() - timeStart) / 1000;
          const avgSpeed = Math.round(downloadedBytes / 1024 / duration);
          resolve({ downloadedBytes, duration, avgSpeed });
        };

        const handleError = (error) => {
          if (hasError) return;
          hasError = true;
          stream.destroy();
          writeStream.destroy();
          reject(error);
        };

        stream.on('end', () => writeStream.end());
        writeStream.on('finish', handleSuccess);
        stream.on('error', handleError);
        writeStream.on('error', handleError);
        setTimeout(() => {
          if (!hasError) handleError(new Error('Download timeout'));
        }, downloadOptions.requestOptions.timeout);

        stream.pipe(writeStream);
      });
      const fileStats = fs.statSync(filePath);
      if (fileStats.size === 0) {
        throw new Error('Downloaded file is empty');
      }
      return {
        title: videoInfo.videoDetails.title,
        dur: Number(videoInfo.videoDetails.lengthSeconds),
        sub: Number(videoInfo.videoDetails.author.subscriber_count) || 0,
        viewCount: Number(videoInfo.videoDetails.viewCount) || 0,
        author: videoInfo.videoDetails.author.name,
        timestart: timeStart,
        filePath: filePath,
        fileSize: fileStats.size,
        fileSizeMB: Number((fileStats.size / 1024 / 1024).toFixed(2)),
        downloadTime: downloadResult.duration,
        downloadSpeed: downloadResult.avgSpeed,
        totalTime: (Date.now() - timeStart) / 1000,
        multiThreadUsed: selectedFormat.contentLength > downloadOptions.minSizeForMultiThread,
        success: true
      };

    } catch (error) {
      if (fs.existsSync(filePath)) {
        try { fs.unlinkSync(filePath); } catch (e) {}
      }
      throw error;
    }
  }

module.exports.config = {
  name: "sing1",
  version: "2.2.0",
  hasPermssion: 0,
  credits: "D-Jukie, Satoru ",
  description: "Phát nhạc thông qua link YouTube, Video ID hoặc từ khoá tìm kiếm",
  commandCategory: "Nhạc",
  usages: "[searchMusic/YouTubeURL/VideoID]",
  cooldowns: 0
}

const moment = require("moment-timezone");
var gio = moment.tz("Asia/Ho_Chi_Minh").format("HH:mm:ss || D/MM/YYYY");

module.exports.run = async function ({ api, event, args, Users}) {
  var thu = moment.tz('Asia/Ho_Chi_Minh').format('dddd');
  if (thu == 'Sunday') thu = 'Chủ Nhật'
  if (thu == 'Monday') thu = 'Thứ Hai'
  if (thu == 'Tuesday') thu = 'Thứ Ba'
  if (thu == 'Wednesday') thu = 'Thứ Tư'
  if (thu == "Thursday") thu = 'Thứ Năm'
  if (thu == 'Friday') thu = 'Thứ Sáu'
  if (thu == 'Saturday') thu = 'Thứ Bảy'
  let name = await Users.getNameUser(event.senderID);
  
  if (args.length == 0 || !args) {
    api.setMessageReaction("❎", event.messageID, () => { }, true);
    api.sendMessage('➣ 𝗛𝗮̃𝘆 𝗻𝗵𝗮̣̂𝗽:\n• 𝗧𝘂̀ 𝗸𝗵𝗼́𝗮 𝘁𝗶̀𝗺 𝗸𝗶𝗲̂́𝗺\n• 𝗟𝗶𝗻𝗸 𝗬𝗼𝘂𝗧𝘂𝗯𝗲\n• 𝗜𝗗 𝘃𝗶𝗱𝗲𝗼 𝗬𝗼𝘂𝗧𝘂𝗯𝗲', event.threadID, event.messageID);
    return;
  };

  const input = args.join(" ");
  var path = `${__dirname}/cache/sing-${event.senderID}.mp3`
  if (fs.existsSync(path)) { 
    fs.unlinkSync(path)
  }
  
  if (isYouTubeUrlOrId(input)) {
    try {
      api.setMessageReaction("⌛", event.messageID, () => { }, true);
      
      const videoId = extractVideoId(input);
      const youtubeUrl = `https://www.youtube.com/watch?v=${videoId}`;
      var data = await downloadMusicFromYoutube(youtubeUrl, path);
      
      if (fs.statSync(path).size > 26214400) {
        return api.sendMessage('𝐁𝐚̀𝐢 𝐠𝐢̀ 𝐦𝐚̀ 𝐝𝐚̀𝐢 𝐝𝐮̛̃ 𝐯𝐚̣̂𝐲, đ𝐨̂̉𝐢 𝐛𝐚̀𝐢 đ𝐢 😠', event.threadID, () => fs.unlinkSync(path), event.messageID);
      }
      
      var imagePath = `${__dirname}/cache/player-${event.senderID}.png`
      const canvasBuffer = await createMusicPlayerCanvas(data, name, videoId);
      fs.writeFileSync(imagePath, canvasBuffer);
      
      api.setMessageReaction("✅", event.messageID, () => { }, true);
      
      api.sendMessage({ 
        attachment: fs.createReadStream(imagePath)
      }, event.threadID, () => {
        fs.unlinkSync(imagePath);
        setTimeout(() => {
          api.sendMessage({ 
            attachment: fs.createReadStream(path)
          }, event.threadID, () => {
            fs.unlinkSync(path);
          });
        }, 100);
      }, event.messageID);
      
    } catch (e) {
      console.log(e);
      api.setMessageReaction("❎", event.messageID, () => { }, true);
      return api.sendMessage('➣ 𝗟𝗼̂̃𝗶 𝗸𝗵𝗶 𝘁𝗮̉𝗶 𝗻𝗵𝗮̣𝗰! 𝗞𝗶𝗲̂̉𝗺 𝘁𝗿𝗮 𝗹𝗮̣𝗶 𝗹𝗶𝗻𝗸/𝗜𝗗', event.threadID, event.messageID);
    }
  } else {
    try {
      var link = [],
        msg = "",
        num = 0
      const Youtube = require('youtube-search-api');
      api.setMessageReaction("⌛", event.messageID, () => { }, true);
      var allData = (await Youtube.GetListByKeyword(input, false, 50)).items;
      var filteredData = filterVideosByDuration(allData, 23);
      var data = filteredData.slice(0, 8);
      
      if (data.length === 0) {
        api.setMessageReaction("❎", event.messageID, () => { }, true);
        return api.sendMessage('➣ 𝗞𝗵𝗼̂𝗻𝗴 𝘁𝗶̀𝗺 𝘁𝗵𝗮̂́𝘆 𝘃𝗶𝗱𝗲𝗼 𝗻𝗮̀𝗼 𝗰𝗼́ 𝘁𝗵𝗼̛̀𝗶 𝗹𝘂̛𝗼̛̣𝗻𝗴 ≤ 𝟮𝟯 𝗽𝗵𝘂́𝘁!', event.threadID, event.messageID);
      }
      
      for (let value of data) {
        link.push(value.id);
        num = num+=1
        api.setMessageReaction("✅", event.messageID, () => { }, true);

        let duration = "N/A";
        if (value.length && value.length.simpleText) {
          duration = value.length.simpleText;
        } else if (value.length) {
          duration = value.length.toString();
        } else if (value.lengthText) {
          duration = value.lengthText;
        } else if (value.lengthSeconds) {
          const minutes = Math.floor(value.lengthSeconds / 60);
          const seconds = value.lengthSeconds % 60;
          duration = `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
        }
        
        msg += (`➣ Kết quả: ${num} - ${value.title}\n➣ 𝐓𝐞̂𝐧 𝐤𝐞̂𝐧𝐡: ${value.channelTitle || "N/A"}\n➣ 𝐓𝐡𝐨̛̀𝐢 𝐥𝐮̛𝐨̛̣𝐧𝐠: ${duration}\n====================\n`);
      }
      var body = `==『 𝙼𝚘̛̀𝚒 𝚋𝚊̣𝚗 𝚘𝚛𝚍𝚎𝚛 𝚖𝚎𝚗𝚞 』==\n====================\n${msg}➝ 𝙼𝚘̛̀𝚒 ${name} 𝚝𝚛𝚊̉ 𝚕𝚘̛̀𝚒 𝚝𝚒𝚗 𝚗𝚑𝚊̆́𝚗 𝚗𝚊̀𝚢 𝚔𝚎̀𝚖 𝚜𝚘̂́ 𝚝𝚑𝚞̛́ 𝚝𝚞̛̣ 𝚖𝚊̀ 𝚋𝚊̣𝚗 𝚖𝚞𝚘̂́𝚗 𝚗𝚐𝚑𝚎 𝚋𝚘𝚝 𝚜𝚎̃ 𝚘𝚛𝚍𝚎𝚛 𝚌𝚑𝚘 𝚋𝚊̣𝚗`
      
      return api.sendMessage({
        body: body
      }, event.threadID, (error, info) => global.client.handleReply.push({
        type: 'reply',
        name: this.config.name,
        messageID: info.messageID,
        author: event.senderID,
        link
      }), event.messageID);
      
    } catch(e) {
      console.log(e)
      api.setMessageReaction("❎", event.messageID, () => { }, true);
      return api.sendMessage('➣ 𝗟𝗼̂̃𝗶 𝗸𝗵𝗶 𝘁𝗶̀𝗺 𝗸𝗶𝗲̂́𝗺!', event.threadID, event.messageID);
    } 
  }
}

module.exports.handleReply = async function ({ api, event, handleReply, Users }) {
  api.setMessageReaction("⌛", event.messageID, () => { }, true);
  const moment = require("moment-timezone");
  var gio = moment.tz("Asia/Ho_Chi_Minh").format("HH:mm:ss || D/MM/YYYY");
  var thu = moment.tz('Asia/Ho_Chi_Minh').format('dddd');
  if (thu == 'Sunday') thu = 'Chủ Nhật'
  if (thu == 'Monday') thu = 'Thứ Hai'
  if (thu == 'Tuesday') thu = 'Thứ Ba'
  if (thu == 'Wednesday') thu = 'Thứ Tư'
  if (thu == "Thursday") thu = 'Thứ Năm'
  if (thu == 'Friday') thu = 'Thứ Sáu'
  if (thu == 'Saturday') thu = 'Thứ Bảy'
  let name = await Users.getNameUser(event.senderID);
  
  const { createReadStream, unlinkSync, statSync } = require("fs-extra")
  try {
    var path = `${__dirname}/cache/sing-${event.senderID}.mp3`
    var imagePath = `${__dirname}/cache/player-${event.senderID}.png`
    
    const videoId = handleReply.link[event.body - 1];
    var data = await downloadMusicFromYoutube('https://www.youtube.com/watch?v=' + videoId, path);
    
    if (fs.statSync(path).size > 26214400) {
      return api.sendMessage('𝐁𝐚̀𝐢 𝐠𝐢̀ 𝐦𝐚̀ 𝐝𝐚̀𝐢 𝐝𝐮̛̃ 𝐯𝐚̣̂𝐲, đ𝐨̂̉𝐢 𝐛𝐚̀𝐢 đ𝐢 😠', event.threadID, () => fs.unlinkSync(path), event.messageID);
    }
    
    const canvasBuffer = await createMusicPlayerCanvas(data, name, videoId);
    fs.writeFileSync(imagePath, canvasBuffer);
    
    api.unsendMessage(handleReply.messageID);
    api.setMessageReaction("✅", event.messageID, () => { }, true);
    api.sendMessage({ 
      attachment: fs.createReadStream(imagePath)
    }, event.threadID, () => {
      fs.unlinkSync(imagePath);
      setTimeout(() => {
        api.sendMessage({ 
          attachment: fs.createReadStream(path)
        }, event.threadID, () => {
          fs.unlinkSync(path);
        });
      }, 100);
    }, event.messageID);
  }
  catch (e) { 
    console.log(e);
    return api.sendMessage('Có lỗi xảy ra khi tạo player', event.threadID, event.messageID);
  }
}

module.exports.convertHMS = function(value) {
  const sec = parseInt(value, 10); 
  let hours = Math.floor(sec / 3600);
  let minutes = Math.floor((sec - (hours * 3600)) / 60);
  let seconds = sec - (hours * 3600) - (minutes * 60); 
  if (hours   < 10) {hours   = "0"+hours;}
  if (minutes < 10) {minutes = "0"+minutes;}
  if (seconds < 10) {seconds = "0"+seconds;}
  return (hours != '00' ? hours +':': '') + minutes+':'+seconds;
}