// build stats for settings page

'use strict';

/* globals apiRequest */

function primaryStats() {
  let apiEndpoint = '/api/stats/primary/';
  let responseData = apiRequest(apiEndpoint, 'GET');
  let primaryBox = document.getElementById('primaryBox');
  clearLoading(primaryBox);
  let videoTile = buildVideoTile(responseData);
  primaryBox.appendChild(videoTile);
  let channelTile = buildChannelTile(responseData);
  primaryBox.appendChild(channelTile);
  let playlistTile = buildPlaylistTile(responseData);
  primaryBox.appendChild(playlistTile);
  let downloadTile = buildDownloadTile(responseData);
  primaryBox.appendChild(downloadTile);
}

function clearLoading(dashBox) {
  dashBox.querySelector('#loading').remove();
}

function buildTile(titleText) {
  let tile = document.createElement('div');
  tile.classList.add('info-box-item');
  let title = document.createElement('h3');
  title.innerText = titleText;
  tile.appendChild(title);
  return tile;
}

function buildVideoTile(responseData) {
  let tile = buildTile(`Total Videos: ${responseData.videos.total || 0}`);
  let message = document.createElement('p');
  message.innerHTML = `
        videos: ${responseData.videos.videos || 0}<br>
        shorts: ${responseData.videos.shorts || 0}<br>
        streams: ${responseData.videos.streams || 0}<br>
    `;
  tile.appendChild(message);

  return tile;
}

function buildChannelTile(responseData) {
  let tile = buildTile(`Total Channels: ${responseData.channels.total || 0}`);
  let message = document.createElement('p');
  message.innerHTML = `subscribed: ${responseData.channels.sub_true || 0}`;
  tile.appendChild(message);

  return tile;
}

function buildPlaylistTile(responseData) {
  let tile = buildTile(`Total Playlists: ${responseData.playlists.total || 0}`);
  let message = document.createElement('p');
  message.innerHTML = `subscribed: ${responseData.playlists.sub_true || 0}`;
  tile.appendChild(message);

  return tile;
}

function buildDownloadTile(responseData) {
  let tile = buildTile('Downloads');
  let message = document.createElement('p');
  message.innerHTML = `
        pending: ${responseData.downloads.pending || 0}<br>
        ignored: ${responseData.downloads.ignore || 0}<br>
    `;
  tile.appendChild(message);

  return tile;
}

function watchStats() {
  let apiEndpoint = '/api/stats/watch/';
  let responseData = apiRequest(apiEndpoint, 'GET');
  let watchBox = document.getElementById('watchBox');
  clearLoading(watchBox);

  for (const property in responseData) {
    let tile = buildWatchTile(property, responseData[property]);
    watchBox.appendChild(tile);
  }
}

function buildWatchTile(title, watchDetail) {
  let tile = buildTile(`Total ${title}`);
  let message = document.createElement('p');
  message.innerHTML = `
    ${watchDetail.items} Videos<br>
    ${watchDetail.duration} Seconds<br>
    ${watchDetail.duration_str} Playback
  `;
  if (watchDetail.progress) {
    message.innerHTML += `<br>${Number(watchDetail.progress * 100).toFixed(2)}%`;
  }
  tile.appendChild(message);
  return tile;
}

function downloadHist() {
  let apiEndpoint = '/api/stats/downloadhist/';
  let responseData = apiRequest(apiEndpoint, 'GET');
  let histBox = document.getElementById('downHistBox');
  clearLoading(histBox);
  if (responseData.length === 0) {
    let tile = buildTile('No recent downloads');
    histBox.appendChild(tile);
    return;
  }

  for (let i = 0; i < responseData.length; i++) {
    const dailyStat = responseData[i];
    let tile = buildDailyStat(dailyStat);
    histBox.appendChild(tile);
  }
}

function buildDailyStat(dailyStat) {
  let tile = buildTile(dailyStat.date);
  let message = document.createElement('p');
  message.innerText = `new videos: ${dailyStat.count}`;
  tile.appendChild(message);
  return tile;
}

function humanFileSize(size) {
  let i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
  return (size / Math.pow(1024, i)).toFixed(1) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}

function buildChannelRow(id, name, value) {
  let tableRow = document.createElement('tr');

  tableRow.innerHTML = `
    <td class="agg-channel-name"><a href="/channel/${id}/">${name}</a></td>
    <td class="agg-channel-right-align">${value}</td>
  `;

  return tableRow;
}

function addBiggestChannelByDocCount() {
  let tBody = document.getElementById('biggestChannelTableVideos');

  let apiEndpoint = '/api/stats/biggestchannels/?order=doc_count';
  const responseData = apiRequest(apiEndpoint, 'GET');

  for (let i = 0; i < responseData.length; i++) {
    const { id, name, doc_count } = responseData[i];

    let tableRow = buildChannelRow(id, name, doc_count);

    tBody.appendChild(tableRow);
  }
}

function addBiggestChannelByDuration() {
  const tBody = document.getElementById('biggestChannelTableDuration');

  let apiEndpoint = '/api/stats/biggestchannels/?order=duration';
  const responseData = apiRequest(apiEndpoint, 'GET');

  for (let i = 0; i < responseData.length; i++) {
    const { id, name, duration_str } = responseData[i];

    let tableRow = buildChannelRow(id, name, duration_str);

    tBody.appendChild(tableRow);
  }
}

function addBiggestChannelByMediaSize() {
  let tBody = document.getElementById('biggestChannelTableMediaSize');

  let apiEndpoint = '/api/stats/biggestchannels/?order=media_size';
  const responseData = apiRequest(apiEndpoint, 'GET');

  for (let i = 0; i < responseData.length; i++) {
    const { id, name, media_size } = responseData[i];

    let tableRow = buildChannelRow(id, name, humanFileSize(media_size));

    tBody.appendChild(tableRow);
  }
}

function biggestChannel() {
  addBiggestChannelByDocCount();
  addBiggestChannelByDuration();
  addBiggestChannelByMediaSize();
}

async function buildStats() {
  primaryStats();
  watchStats();
  downloadHist();
  biggestChannel();
}

document.addEventListener('DOMContentLoaded', () => {
  window.requestAnimationFrame(() => {
    buildStats();
  });
});
