<template>
  <div class="character-sheet-printed fill-height">
    <v-fade-transition mode="out-in">
      <div
        v-if="!$subReady.singleCharacter"
        key="character-loading"
        class="fill-height layout justify-center align-center"
      >
        <v-progress-circular
          indeterminate
          color="primary"
          size="64"
        />
      </div>
      <div v-else-if="!creature">
        <v-layout
          column
          align-center
          justify-center
        >
          <h2 style="margin: 48px 28px 16px">
            Character not found
          </h2>
          <h3>
            Either this character does not exist, or you don't have permission
            to view it.
          </h3>
        </v-layout>
      </div>
      <v-theme-provider
        v-else
        light
      >
        <div class="page pa-3">
          <div class="title-block px-3 d-flex align-center">
            <div class="logo-background" />
            <div class="creature-name mr-3">
              {{ creature.name }}
            </div>
            <div class="text-right flex mr-4">
              <div v-if="creature.alignment || background">
                {{ creature.alignment }} {{ background }}
              </div>
              <dir v-if="race || creature.gender">
                {{ creature.gender }} {{ race }}
              </dir>
              <div v-if="level && classes && classes.length === 1">
                Level {{ level }} {{ classes[0].name }}
              </div>
              <div v-else-if="level">
                Level {{ level }} ({{ classes.map(c => `${c.name} ${c.level}`).join(', ') }})
              </div>
            </div>
            <qrcode-vue
              style="height: 100px"
              render-as="svg"
              :value="creatureUrl"
            />
          </div>
          <div
            class="text-right mt-3 mr-4"
            style="font-size: 8pt; margin-bottom: -4px;"
          >
            {{ creatureUrl }}
          </div>
          <printed-stats :creature-id="creatureId" />
          <printed-inventory :creature-id="creatureId" />
          <printed-spells
            v-if="!creature.settings.hideSpellsTab"
            :creature-id="creatureId"
          />
        </div>
      </v-theme-provider>
    </v-fade-transition>
  </div>
</template>

<script lang="js">
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import PrintedStats from '/imports/client/ui/creature/character/printedCharacterSheet/PrintedStats.vue';
import PrintedInventory from '/imports/client/ui/creature/character/printedCharacterSheet/PrintedInventory.vue';
import PrintedSpells from '/imports/client/ui/creature/character/printedCharacterSheet/PrintedSpells.vue';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables.js';
import QrcodeVue from 'qrcode.vue'

export default {
  components: {
    PrintedStats,
    PrintedInventory,
    PrintedSpells,
    QrcodeVue,
  },
  computed: {
    creatureId() {
      return this.$route.params.id
    },
    creatureUrl() {
      let props = this.$router.resolve({ 
        name: 'characterSheet',
        params: { id: this.creatureId},
      });
      return new URL(props?.href, document.baseURI).href
    },
    level() {
      return this.variables?.level?.value;
    },
    highestLevels(){
      let highestLevels = {};
      let highestLevelsList = [];
      this.classLevels.forEach(classLevel => {
        let name = classLevel.variableName;
        if (
          !highestLevels[name] ||
          highestLevels[name].level < classLevel.level
        ){
          highestLevels[name] = classLevel;
        }
      });
      for (let name in highestLevels){
        highestLevelsList.push(highestLevels[name]);
      }
      highestLevelsList.sort((a, b) => a.level - b.level);
      return highestLevelsList;
    },
    classes() {
      return [
        ...this.highestLevels,
        ...this.classProperties
      ].sort((a, b) => a.order - b.order);
    },
  },
  reactiveProvide: {
    name: 'context',
    include: ['creatureId', 'editPermission'],
  },
  watch: {
    'creature.name'(value) {
      this.$store.commit('setPageTitle', value ? ('Print ' + value) : 'Print Character Sheet');
    },
  },
  mounted() {
    this.$store.commit('setPageTitle',
      (this.creature && this.creature.name) ?
        ('Print ' + this.creature.name) :
        'Print Character Sheet'
    );
    this.nameObserver = Creatures.find({
      creatureId: this.creatureId,
    }, {
      fields: { name: 1 },
    }).observe({
      added: ({ name }) =>
        this.$store.commit('setPageTitle', name ? ('Print ' + name) : 'Print Character Sheet'),
      changed: ({ name }) =>
        this.$store.commit('setPageTitle', name ? ('Print ' + name) : 'Print Character Sheet'),
    });
  },
  beforeDestroy() {
    this.nameObserver.stop();
  },
  meteor: {
    $subscribe: {
      'singleCharacter'() {
        return [this.creatureId];
      },
    },
    creature() {
      return Creatures.findOne(this.creatureId);
    },
    variables() {
      return CreatureVariables.findOne({ _creatureId: this.creatureId }) || {};
    },
    race() {
      if (this.variables?.race?.value?.valueType === 'string') return this.variables.race.value.value;
      const prop = CreatureProperties.findOne({
        'ancestors.id': this.creatureId,
        tags: 'race',
        removed: { $ne: true },
        inactive: { $ne: true },
        overridden: { $ne: true },
      });
      if (prop?.name) return prop.name;
      return '';
    },
    background() {
      if (this.variables?.background?.value?.valueType === 'string') return this.variables.background.value.value;
      const prop = CreatureProperties.findOne({
        'ancestors.id': this.creatureId,
        tags: 'background',
        removed: { $ne: true },
        inactive: { $ne: true },
        overridden: { $ne: true },
      });
      if (prop?.name) return prop.name;
      return '';
    },
    classProperties(){
      return CreatureProperties.find({
        'ancestors.id': this.creatureId,
        type: 'class',
        removed: {$ne: true},
        inactive: {$ne: true},
      }, {
        sort: {order: 1}
      }).fetch();
    },
    classLevels() {
      const classVariableNames = this.classProperties.map(c => c.variableName)
      return CreatureProperties.find({
        'ancestors.id': this.creatureId,
        type: 'classLevel',
        variableName: {$nin: classVariableNames},
        removed: {$ne: true},
        inactive: {$ne: true},
      }, {
        sort: {order: 1}
      });
    },
    editPermission() {
      try {
        assertEditPermission(this.creature, Meteor.userId());
        return true;
      } catch (e) {
        return false;
      }
    },
  },
}
</script>

<style>
.character-sheet-printed {
  background: white;
  color: black;
  font-size: 11pt;
}

.character-sheet-printed * {
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
  cursor: unset !important;
}

.page {
  padding: 4px;
}

.character-sheet-printed .column-layout, .character-sheet-printed .column-layout.wide-columns {
  position:relative;
  width: 100%;
  widows: 0;
  orphans: 0;
  -webkit-column-fill: balance-all;
  column-fill: balance-all;
}

.character-sheet-printed .column-layout>div {
  position:relative;
}
.character-sheet-printed .column-layout > div > * {
  page-break-inside: avoid;
}

.character-sheet-printed .inactive {
  opacity: 1 !important;
}
.character-sheet-printed .creature-name {
  font-size: 24pt;
  background-color: white;
}
.character-sheet-printed .logo-background {
  width: 60px;
  height: 60px;
  margin-right: 8px;
  background-image: url(/crown-dice-logo-cropped-transparent.png);
  background-size: contain;
  background-position: 0 center;
}

.character-sheet-printed .v-divider {
  border-color: rgba(0,0,0,0.3);
  max-width: unset;
}

.character-sheet-printed .double-border {
  position: relative;
  padding: 11px 10px;
  border-image-source: url(/images/print/doubleLineImageBorder.png);
  border-image-slice: 110 126 fill;
  border-image-width: 16px;
  border-image-repeat: stretch;
}

.character-sheet-printed .octagon-border {
  position: relative;
  padding: 4px 20px;
  border-image: url(/images/print/octagonBorder.png) 124 118 fill;
  border-image-width: 22px;
}

.character-sheet-printed .span-all {
  page-break-after: avoid;
  break-after: avoid;
}
.span-all + div {
  page-break-before: avoid;
  break-before: avoid;
}

.character-sheet-printed .stats .label {
  font-size: 10pt;
  font-variant: small-caps;
}

.character-sheet-printed .label {
  font-size: 14pt;
  font-variant: all-small-caps;
  font-weight: 600;
}

.character-sheet-printed .span-all {
  column-span: all;
}

@media screen {
  .character-sheet-printed {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .character-sheet-printed .page {
    width: 210mm;
  }
}
@media print {
  @page { 
      size: auto;
      margin: 8mm 8mm 8mm 8mm;  
  }
  body {  
      margin: 0;  
  }
  .character-sheet-printed .page {
    width: 100%;
    padding: 0 !important;
  }
  .character-sheet-printed .column-layout {
    padding: 4px 0 !important;
  }
  .character-sheet-printed .title-block {
    padding-left: 0 !important;
    padding-right: 4px !important;
  }
  .v-main, .v-application, .v-application--wrap, .character-sheet-printed {
    display: block !important;
    background-color: white !important;
  }
  html {
    background-color: white !important;
  }
  header, nav, .v-snack, .dialog-stack {
    display: none !important;
  }
  .v-main {
    padding: 0 !important;
  }
}
</style>
