<template>
  <v-app>
    <v-navigation-drawer :permanent="true">
      <v-list>
        <v-list-item>
          <v-list-item-action class="justify-center">
            <v-row>
              <v-col class="text-center">
                <UploadForm @torrent_added="torrentAdded"/>
              </v-col>
            </v-row>
          </v-list-item-action>
        </v-list-item>
      </v-list>
      <v-divider/>
      <UserStats :stats="user_stats"/>
      <v-divider/>
      {{dm_status}}
      <DM v-if="dm_activated" :dm_files="dm_files" :dm_status="dm_status" :dm_download_location="dm_download_location"/>
    </v-navigation-drawer>
    <v-navigation-drawer v-model="right_drawer" location="right" temporary>
      <Friend v-if="right_drawer" :active_user="display_user.id" @userSelected="userSelectedUpdated"/>
    </v-navigation-drawer>
    <v-app-bar>
      <v-app-bar-title style="max-width: 150px">
            <v-btn variant="plain" href="/">Oxpanel</v-btn>
      </v-app-bar-title>
      <v-row align="center" justify="center" style="max-width: 500px" class="mx-auto">
        <v-col>
          <v-text-field density="comfortable" flat solo-inverted hide-details prepend-inner-icon="mdi-magnify" label="Search" v-model="filters.search" clearable @click:clear="filters.search = ''"/>
        </v-col>
      </v-row>

      <template v-slot:append>
        <v-menu>
          <template v-slot:activator="{ props }">
            <v-btn v-bind="props">Manage</v-btn>
          </template>
          <v-list>
            <v-list-item href="/password_change/" title="Change password"/>
            <v-list-item>
              <v-list-item-action>
                <form action="/logout/" method="post">
                  <input type="hidden" name="csrfmiddlewaretoken" :value="Cookies.get('csrftoken')">
                  <button>Disconnect</button>
                </form>
              </v-list-item-action>
            </v-list-item>
          </v-list>
        </v-menu>
        <v-btn
          @click="right_drawer = !right_drawer"
          prepend-icon="mdi-account-group"
          :color="display_user.id === user.id ? 'green':'orange'"
          :text="display_user.username"
        />
      </template>

    </v-app-bar>
    <v-main>
      <TorrentList :loading="loading_torrents" :torrents="torrents" :delete_disabled="user.id !== display_user.id"/>
    </v-main>
  </v-app>
</template>

<script setup>
import Cookies from "js-cookie";
import TorrentList from "@/components/torrent/TorrentList.vue";
import UploadForm from "@/components/torrent/UploadForm.vue";
import Friend from "@/components/auth/Friend.vue";
import UserStats from "@/components/torrent/UserStats.vue";
import DM from "@/components/torrent/DM.vue";
</script>

<script>
export default {
  data(){
    return {
      right_drawer: false,
      user: current_user,
      display_user: {
        id: current_user.id,
        username: "My torrents"
      },
      loading_torrents: false,
      filters: {},
      torrents: [],
      user_stats: {
        torrents_size: 0,
        torrents_len: 0,
        torrent_len_shared: 0,
        torrents_total_len: 0,
        user_max_size: 0,
        user_usage_percent: 0,
        disk_total: 0,
        disk_used: 0,
        disk_free: 0,
        disk_usage_percent: 0,
      },
      filter_timer: null,
      dm_files: {},
      // dm_stats: {},
      dm_status: {},
      dm_download_location: "",
      dm_activated: false
    }
  },
  watch: {
    filters: {
      handler(){
        // console.log(JSON.stringify(this.filters));
        clearTimeout(this.filter_timer);
        this.filter_timer = setTimeout(() => {
          this.fetchTorrents();
        }, 200)
      },
      deep: true
    }
  },
  async mounted(){
    this.$ws.connect("/ws/torrent_event/");
    this.$ws.on("connect", () => {
      this.$ws.send(JSON.stringify({"context": "change_follow_user", "user_id": this.display_user.id}));
    });
    this.$ws.on("json_message", (message) => {
      switch(message.context){
        case "transmission_data_updated":
          this.updateTransmissionData(message.data);
          break;
        case "add_torrent":
          this.fetchTorrent(message.torrent_id);
          this.fetchUserStats();
          break;
        case "remove_torrent":
          this.removeTorrent(message.torrent_id);
          this.fetchUserStats();
          break;
        case "update_torrent":
          this.updateTorrent(message.torrent_id, message.updated_fields)
          break
      }
    })
    await this.fetchTorrents();
    await this.fetchUserStats();
    if(this.$qt.connect()){
      this.$qt.on("ready", () => {
        this.dm_status = this.$qt.getProperty("dm_status");
        this.dm_files = this.$qt.getProperty("dm_files");
        // this.dm_stats = this.$qt.getProperty("dm_stats");
        this.dm_download_location = this.$qt.getProperty("dm_download_location");
        this.dm_activated = true;
        // console.log(JSON.stringify(this.dm_files))

        this.$qt.on("status_updated", data => {
          this.dm_status = data;
        })
        // this.$qt.on("stats_updated", data => {
        //   this.dm_stats = data;
        // })
        this.$qt.on("files_updated", data => {
          this.dm_files = data;
        })
        this.$qt.on("download_location_updated", data => {
          this.dm_download_location = data;
        })
      })
    }
  },
  methods: {
    async fetchUserStats(){
      let response = await fetch("/api/users/user_stats/");
      this.user_stats = await response.json();
    },
    torrentAdded(torrent){
      if(!(torrent.id in this.torrentsAsObject)){
        this.torrents.unshift(torrent);
      }
    },
    changeDisplayUser(user){
      if(user){
        this.display_user = {
          "username": this.user.id === user.id ? "My torrents": `${user.username} torrents`,
          "id": user.id
        }
      }else{

      }
      this.display_user = {
        "username": this.user.id === user.id ? "My torrents": `${user.username} torrents`,
        "id": user.id
      }
      this.$ws.send(JSON.stringify({"context": "change_follow_user", "user_id": this.display_user.id}));
    },
    updateTransmissionData(data){
      if(data.hashString in this.torrentsAsObject){
        this.torrentsAsObject[data.hashString].transmission_data = data
      }
    },
    async fetchTorrents(){
      this.loading_torrents = true;
      let filters = {...this.filters, user: this.display_user.id},
        url = `/api/torrents/?${new URLSearchParams(filters)}`;

      let response = await fetch(url);
      this.torrents = await response.json();
      this.loading_torrents = false;
    },
    async fetchTorrent(torrent_id){
      if(torrent_id in this.torrentsAsObject) return;
      let url = `/api/torrents/${torrent_id}/`;
      let response = await fetch(url);
      if(response.ok){
        let torrent = await response.json();
        if(!(torrent.id in this.torrentsAsObject)) this.torrents.unshift(torrent);
      }else{
        setTimeout(() => this.fetchTorrent(torrent_id), 1000);
      }
    },
    async updateTorrent(torrent_id, updated_fields){
      if(torrent_id in this.torrentsAsObject){
        for(let key in updated_fields){
          this.torrentsAsObject[torrent_id][key] = updated_fields[key];
        }
      }
    },
    async removeTorrent(torrent_id){
      if(!(torrent_id in this.torrentsAsObject)) return;
      for(let i = 0; i < this.torrents.length; i++){
        if(this.torrents[i].id === torrent_id){
          this.torrents.splice(i, 1);
          break;
        }
      }
    },
    async userSelectedUpdated(user){
      await this.changeDisplayUser(user ? user: this.user);
      await this.fetchTorrents();

      this.right_drawer = false
    },
  },
  computed: {
    torrentsAsObject(){
      let r = {};
      this.torrents.forEach(torrent => {
        r[torrent.id] = torrent;
      });
      return r;
    }
  }
}
</script>

<style scoped>

</style>