<script lang="ts">
import { defineComponent, PropType } from 'vue';

interface Player {
  id: number,
  name: string
}

interface Model {
  yourId: number,
  players: Map<number, Player>,
  board: string[4][4]
}

function getPlayer(model: Model, id: number): Player | undefined {
  return model.players.get(id)
}

/*
Handles all game business. Sends (local) player input to the server for distribution.
Receives player input from the server and manages state accordingly.
*/
export default defineComponent({
  props: {
    ws: { type: WebSocket, required: true },
    model: { type: Object as PropType<Model>, required: true }
  },
  data() {
    return {
      chatMessages: [] as { from: number, message: string }[],

      playerName: '',
      chatMessage: ''
    }
  },
  created() {
    console.log(this.model.board)
    console.log(this.model)
    console.log(this.model.players)
    this.ws.addEventListener('message', (ev) => {
      const message = JSON.parse(ev.data)
      const payload = message.payload
      console.log(`Message from player ${message.from}:`)
      console.log(payload)

      switch (payload.type) {
        case 'join':
          this.model.players.set(message.from, {
            id: message.from,
            name: ''
          })
          break
        case 'leave':
          this.model.players.delete(message.from)
          break
        case 'chat':
          this.chatMessages.push({
            from: message.from,
            message: payload.message
          })
          break
        case 'set-name':
          getPlayer(this.model, message.from)!.name = payload.name
          break
        case 'roll':
          this.model.board = payload.board
          break
      }

      console.log(this.model)
    })
  },
  methods: {
    setName() {
      this.ws.send(JSON.stringify({
        type: 'set-name',
        name: this.playerName
      }))
    },
    sendChat() {
      if (this.chatMessage === '') {
        return
      }

      this.ws.send(JSON.stringify({
        type: 'chat',
        message: this.chatMessage
      }))
      this.chatMessage = ''
    },
    roll() {
      this.ws.send(JSON.stringify({
        type: 'roll'
      }))
    }
  }
})
</script>

<template>
  <div class="glebby-game">
    <div class="topbar">
      <h1>Glebby</h1>
    </div>
    <div class="game">
      <h2>board</h2>
      <button @click="roll">roll</button>
      <div v-if="model.board" class="game-board">
        <div v-for="row in model.board" class="game-row">
          <div v-for="die in row" class="game-die">{{ die.toUpperCase() }}</div>
        </div>
      </div>
    </div>
    <div class="playerlist">
      <h2>players</h2>
      <form @submit.prevent="setName">
        <input v-model="playerName" placeholder="enter your name...">
        <button>set name</button>
      </form>
      <ul v-if="model">
        <li v-for="[id, player] in model.players" :key="id">
          <code>{{ player.name }}#{{ player.id }}</code>
        </li>
      </ul>
    </div>
    <div class="chatbox">
      <h2>chat</h2>
      <div class="chatbox-scroller">
        <div class="chatbox-scroller-content">
          <div v-for="message in chatMessages" class="chatbox-message">
            <code v-if="model.players.get(message.from)">{{ model.players.get(message.from)!.name }}#{{ message.from }}:</code> {{ message.message }}
          </div>
        </div>
      </div>
      <form @submit.prevent="sendChat">
        <input v-model="chatMessage">
        <button>Post</button>
      </form>
    </div>
  </div>
</template>

<style>
  body {
    margin: 0;
  }

  .glebby-game {
    width: 100vw;
    height: 100vh;
    display: grid;
    grid-template-columns: 1fr 20em;
    grid-template-rows: min-content 1fr 12em;
    grid-template-areas:
      "topbar  topbar"
      "game    playerlist"
      "chatbox playerlist";
    gap: .5em;
    padding: .5em;
    box-sizing: border-box;
  }

  .topbar,
  .game,
  .playerlist,
  .chatbox {
    background-color: #f0f0f0;
    padding: .5em;
  }

  .topbar {
    grid-area: topbar;
  }

  .game {
    grid-area: game;
  }

  .playerlist {
    grid-area: playerlist;
  }

  .chatbox {
    grid-area: chatbox;
  }

  h1, h2 {
    margin: 0;
    font-family: monospace;
  }

  .game-board {
    display: flex;
    gap: 1em;
    flex-direction: column;
    align-items: center;
  }

  .game-row {
    display: flex;
    gap: 1em;
  }

  .game-die {
    width: 2em;
    height: 2em;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: white;
    font-family: monospace;
    font-size: 1.5em;
    font-weight: bold;
  }

  .chatbox {
    display: grid;
    grid-template-rows: min-content 1fr min-content;
  }

  .chatbox-scroller {
    overflow-y: scroll;
    display: flex;
    flex-direction: column-reverse;
  }

  .chatbox-scroller {
    border: 1px dashed #888;
    margin: .25em 0;
    padding: .25em;
  }

  .chatbox-message code {
    color: #888;
  }
</style>
