<script>
import draggable from 'vuedraggable'
import axios from 'axios'
import userService from '@/utils/user-utils'
import {
  showToastAtCursorWarningGroupLimit,
  showToastGroup,
  showToastGroupAdmin
} from '@/utils/event-utils'

export default {
  components: {
    // eslint-disable-next-line vue/no-unused-components
    draggable
  },
  data() {
    return {
      groups: [
        { id: '0', name: 'Nezařazení' },
        { id: '1', name: 'Skupina 1' },
        { id: '2', name: 'Skupina 2' },
        { id: '3', name: 'Skupina 3' }
      ],
      users: [], // Zde načte uživatele z backendu
      draggedUser: null,
      content: '',
      isLoggedIn: false,
      isAdmin: false,
      currentUserId: localStorage.getItem('userId')
    }
  },
  methods: {
    getUsersByGroup(group) {
      return this.users.filter((user) => user.group === group)
    },
    handleDragStart(user) {
      if (this.isAdmin) {
        this.draggedUser = user
      }
    },
    // Přesouvání uživatelů mezi skupinami
    async handleDrop(newGroup) {
      if (this.draggedUser && this.isAdmin) {
        try {
          const groupId = newGroup.id || newGroup
          const usersInGroup = this.getUsersByGroup(groupId)

          // Do jedné skupiny nelze přesunout víc jak 2 uživatele, neplatí pro skupinu 0 -> "Nezařazení"
          if (usersInGroup.length >= 2 && groupId != 0) {
            showToastAtCursorWarningGroupLimit()
            return
          }

          // Získá eventy přesouvaného uživatele
          const response = await axios.get(
            `http://localhost:3001/api/events/?userId=${this.draggedUser._id}`
          )

          const userEvents = response.data.events || []

          const groupUserIds = usersInGroup.map((user) => user.id || user._id)
          const groupResponse = await axios.get(`http://localhost:3001/api/events/all`)
          const allEvents = groupResponse.data.events || []

          const groupEvents = allEvents.filter((event) => groupUserIds.includes(event.userId))

          // Získá eventy přesouvaného uživatele a uživatele uvnitř skupiny a porovná jestli se overlappují eventy
          const hasConflict = userEvents.some((userEvent) =>
            groupEvents.some(
              (groupEvent) =>
                new Date(userEvent.start).toISOString().slice(0, 10) ===
                new Date(groupEvent.start).toISOString().slice(0, 10)
            )
          )

          if (hasConflict) {
            if (
              confirm(
                'Při přesunu uživatele do této skupiny dojde ke kolizi vypsaných služeb\nOpravdu chcete pokračovat?'
              )
            ) {
              this.draggedUser.group = groupId
              await this.updateUserGroup(this.draggedUser.id || this.draggedUser._id, groupId) // pošle aktualizaci do backendu
              this.draggedUser = null
            }
          } else {
            this.draggedUser.group = groupId
            await this.updateUserGroup(this.draggedUser.id || this.draggedUser._id, groupId) // pošle aktualizaci do backendu
            this.draggedUser = null
          }
        } catch (error) {
          console.error('Nepodařilo se aktualizovat uživatelovu skupinu', error)
        }
      }
    },
    async updateUserGroup(userId, newGroup) {
      try {
        const response = await axios.put(`http://localhost:3001/api/users/${userId}`, {
          group: newGroup
        })
        if (response.data && response.data.username && response.data.group) {
          console.log(
            `Uživatel ${response.data.username} byl přesunut do skupiny ${response.data.group}`
          )
        } else {
          console.warn('Odpověď z backendu neobsahuje očekávaná uživatelská data:', response.data)
        }
      } catch (error) {
        console.error('Nepodařilo se aktualizovat uživatelovu skupinu', error)
      }
    },
    // Metoda, která získá všechny uživatele, kteří jsou uloženi v databázi
    async fetchUsers() {
      try {
        const response = await axios.get('http://localhost:3001/api/users/')
        this.users = response.data
      } catch (error) {
        console.error('Nepodařilo se získat uživatele pro skupiny', error)
      }
    },
    createGroup() {
      // Vypíše aktuální ID skupin mimo skupinu 0, která slouží pro "Nezařazené"
      const existingIds = this.groups
        .filter((group) => group.id !== '0')
        .map((group) => parseInt(group.id))

      // Najde nejnižší chybějící číslo v posloupnosti
      let newGroupId = 1
      while (existingIds.includes(newGroupId)) {
        newGroupId++
      }

      // Převede nové ID na string a vytvoří novou skupinu
      const newGroup = { id: newGroupId.toString(), name: `Skupina ${newGroupId}` }
      this.groups.push(newGroup)

      // Seřadí skupiny vzestupně a uloží je do localStorage
      this.groups.sort((a, b) => parseInt(a.id) - parseInt(b.id))
      localStorage.setItem('groups', JSON.stringify(this.groups))
      window.toastr.success('Nová skupina byla úspěšně vytvořena!')
    },
    async deleteGroup(groupId) {
      try {
        // Najde uživatele, kteří patří do smazané skupiny
        const usersToMove = this.users.filter((user) => user.group === groupId)

        // Projde a nastaví každého uživatele skupinu na '0' (Nezařazení) a pošle změnu do backendu
        for (const user of usersToMove) {
          user.group = '0' // aktualizuje lokálně
          await this.updateUserGroup(user._id, '0')
        }
        // Odstraní skupinu ze seznamu skupin a nastaví změnu do localStorage
        this.groups = this.groups.filter((group) => group.id !== groupId)
        localStorage.setItem('groups', JSON.stringify(this.groups))
        window.toastr.success(`Úspěšně jste smazali skupinu ${groupId}!`)
      } catch (error) {
        window.toastr.error('Naskytla se chyba během mazání skupin a aktualizace jejich uživatelů')
        console.error('Naskytla se chyba během mazání skupin a aktualizace jejich uživatelů', error)
      }
    },
    // Metoda, která kontroluje, zdali je daný uživatel součástí skupiny "Nezařazení", pokud ano zobrazí upozornění
    checkGroup() {
      if (this.isLoggedIn && !this.isAdmin) {
        const userGroup = this.users.find(
          (user) => user._id === this.currentUserId && user.group === '0'
        )
        if (userGroup) {
          showToastGroup()
        }
      }
      // Pokud jsou někteří uživatelé součástí skupiny "Nezařazení" zobrazí upozornění -> admin only
      if (this.isAdmin) {
        const userGroup = this.users.find((user) => user.group === '0')
        if (userGroup) {
          showToastGroupAdmin()
        }
      }
    }
  },
  created() {
    window.toastr.remove()
    this.fetchUsers()
    const savedGroups = localStorage.getItem('groups')
    if (savedGroups) {
      this.groups = JSON.parse(savedGroups)
    } else {
      ;(this.groups = [
        { id: '0', name: 'Nezařazení' },
        { id: '1', name: 'Skupina 1' },
        { id: '2', name: 'Skupina 2' },
        { id: '3', name: 'Skupina 3' }
      ]),
        localStorage.setItem('groups', JSON.stringify(this.groups))
    }
  },
  mounted() {
    const token = localStorage.getItem('x-access-token')
    const currentUsername = localStorage.getItem('username')

    if (token) {
      userService.getAdminBoard().then((response) => {
        const admins = response.data

        this.isAdmin = admins.some((admin) => admin.username === currentUsername)
        this.isLoggedIn = true

        this.checkGroup()

        if (!this.isAdmin) {
          return userService
            .getUserBoard()
            .then((response) => {
              if (response) {
                this.content = response.data
              }
            })
            .catch((error) => {
              this.isAdmin = false
              this.isLoggedIn = false
              console.error('Error:', error.response?.data || error.message)
              this.content = error.response?.data || error.message || 'An error occurred.'
            })
        }
      })
    } else {
      userService.getPublicContent().then(
        (response) => {
          this.content = response.data
        },
        (error) => {
          this.content =
            (error.response && error.response.data) || error.messsage || error.toString()
        }
      )
    }
  }
}
</script>

<template>
  <article v-if="!isLoggedIn">
    <h3>{{ content }}</h3>
  </article>
  <article v-if="isLoggedIn">
    <h1>Skupiny</h1>
    <div>
      <!-- Projde přiřazené skupiny -->
      <div
        v-for="group in groups"
        :key="group.id"
        class="group"
        @drop="isAdmin ? handleDrop(group) : null"
        @dragover.prevent
      >
        <div class="group-actions">
          <button
            v-if="isAdmin && group.id !== '0'"
            @click="deleteGroup(group.id)"
            class="action-button"
          >
            🗑️ Smaž
          </button>
        </div>

        <!-- Skupina s číslem 0 se zobrazuje jako 'Nezařazení', zbytek normálně -->
        <h3>{{ group.id === '0' ? 'Nezařazení' : group.name }}</h3>
        <!-- Projde uživatele v každé skupině a vypíše je -->
        <div
          class="user"
          v-for="user in getUsersByGroup(group.id)"
          :key="user._id"
          :class="{ currentUserInGroup: user._id === currentUserId }"
          :draggable="isAdmin"
          @dragstart="isAdmin ? handleDragStart(user) : null"
        >
          {{ user.username }}
        </div>
      </div>
    </div>

    <div v-if="isAdmin">
      <button class="groups-button" @click="createGroup">Vytvoř novou skupinu</button>
    </div>
  </article>
</template>
