<template>
  <q-table
    v-model:pagination="pagination"
    title="Kalkulationstabelle"
    :columns="columns"
    :rows="drinks"
    :visible-columns="visibleColumn"
    :dense="$q.screen.lt.md"
    row-key="id"
    virtual-scroll
    :rows-per-page-options="[0]"
    :filter="search"
    :filter-method="filter"
  >
    <template #header="props">
      <q-tr :props="props">
        <q-th auto-width />
        <q-th v-for="col in props.cols" :key="col.name" :props="props">
          {{ col.label }}
        </q-th>
      </q-tr>
    </template>
    <template #top-right>
      <div class="row justify-end q-gutter-sm">
        <search-input v-model="search" :keys="[...columns, ...column_calc, ...column_prices]" />
        <q-btn label="Aufpreise">
          <q-menu anchor="center middle" self="center middle">
            <min-price-setting />
          </q-menu>
        </q-btn>
        <q-btn label="neues Getränk" color="positive" icon-right="add">
          <q-menu v-model="showNewDrink" anchor="center middle" self="center middle" persistent>
            <new-drink @close="showNewDrink = false" />
          </q-menu>
        </q-btn>
        <q-select
          v-model="visibleColumn"
          multiple
          filled
          dense
          options-dense
          display-value="Sichtbarkeit"
          emit-value
          map-options
          :options="[...columns, ...column_calc, ...column_prices]"
          option-value="name"
          options-cover
        />
      </div>
    </template>
    <template #body="drinks_props">
      <q-tr :props="drinks_props">
        <q-td auto-width>
          <q-btn
            v-if="drinks_props.row.volumes.length === 0"
            size="xs"
            color="negative"
            round
            dense
            icon="mdi-delete"
            class="q-mx-sm"
            @click="deleteDrink(drinks_props.row)"
          />
        </q-td>
        <q-td key="picture" :props="drinks_props" style="min-width: 256px">
          <q-img
            loading="lazy"
            :src="
              drinks_props.row.uuid
                ? `/api/pricelist/picture/${drinks_props.row.uuid}?size=256`
                : 'no-image.svg'
            "
            placeholder-src="no-image.svg"
          >
            <template #error>
              <div class="absolute-full flex flex-center bg-negative text-white">
                Cannot load image
              </div>
            </template>
          </q-img>
          <q-popup-edit v-model="drinkPic" @update:modelValue="savePicture(drinks_props.row)">
            <template #default="scope">
              <div class="full-width row">
                <q-file v-model="scope.value" filled>
                  <template #prepend>
                    <q-icon name="attach_file" />
                  </template>
                </q-file>
                <div class="full-width row justify-between">
                  <q-btn label="Abbrechen" flat color="primary" @click="scope.cancel" />
                  <q-btn
                    label="Löschen"
                    flat
                    color="primary"
                    @click="
                      scope.cancel();
                      deletePicture(drinks_props.row);
                    "
                  />
                  <q-btn label="Speichern" flat color="primary" @click="scope.set" />
                </div>
              </div>
            </template>
          </q-popup-edit>
        </q-td>
        <q-td key="name" :props="drinks_props">
          {{ drinks_props.row.name }}
          <q-popup-edit
            v-slot="scope"
            v-model="drinks_props.row.name"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model="scope.value"
              filled
              dense
              autofocus
              clearable
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="drink_type" :props="drinks_props">
          {{ drinks_props.row.type.name }}
          <q-popup-edit
            v-slot="scope"
            v-model="drinks_props.row.type"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-select
              v-model="scope.value"
              :options="drinkTypes"
              option-label="name"
              option-value="id"
              filled
              dense
              autofocus
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="tags" :props="drinks_props">
          <q-badge
            v-for="tag in drinks_props.row.tags"
            :key="`${drinks_props.row.id}-${tag.id}`"
            class="q-ma-xs"
            rounded
            :style="`background-color: ${tag.color}`"
          >
            {{ tag.name }}
          </q-badge>
          <q-popup-edit
            v-model="drinks_props.row.tags"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <template #default="scope">
              <q-select
                v-model="scope.value"
                multiple
                :options="tags"
                label="Tags"
                option-label="name"
                filled
              >
                <template #selected-item="item">
                  <q-chip
                    removable
                    :tabindex="item.tabindex"
                    :style="`background-color: ${item.opt.color}`"
                    @remove="item.removeAtIndex(item.index)"
                  >
                    {{ item.opt.name }}
                  </q-chip>
                </template>
                <template #option="item">
                  <q-item v-bind="item.itemProps" v-on="item.itemEvents">
                    <q-chip :style="`background-color: ${item.opt.color}`">
                      <q-avatar
                        v-if="item.selected"
                        icon="mdi-check"
                        color="positive"
                        text-color="white"
                      />
                      {{ item.opt.name }}
                    </q-chip>
                  </q-item>
                </template>
              </q-select>
            </template>
          </q-popup-edit>
        </q-td>
        <q-td key="article_id" :props="drinks_props">
          {{ drinks_props.row.article_id || 'o.A.' }}
          <q-popup-edit
            v-slot="scope"
            v-model="drinks_props.row.article_id"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model="scope.value"
              filled
              dense
              autofocus
              clearable
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="volume_package" :props="drinks_props">
          {{ drinks_props.row.volume ? `${drinks_props.row.volume} L` : 'o.A.' }}
          <q-popup-edit
            v-if="
              !drinks_props.row.volumes.some((volume) =>
                volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
              )
            "
            v-slot="scope"
            v-model.number="drinks_props.row.volume"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model.number="scope.value"
              filled
              dense
              autofocus
              type="number"
              clearable
              step="0.01"
              min="0"
              suffix="L"
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="package_size" :props="drinks_props">
          {{ drinks_props.row.package_size || 'o.A.' }}
          <q-popup-edit
            v-if="
              !drinks_props.row.volumes.some((volume) =>
                volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
              )
            "
            v-slot="scope"
            v-model="drinks_props.row.package_size"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model.number="scope.value"
              filled
              dense
              autofocus
              type="number"
              min="0"
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="cost_per_package" :props="drinks_props">
          {{
            drinks_props.row.cost_per_package
              ? `${drinks_props.row.cost_per_package.toFixed(2)}€`
              : 'o.A.'
          }}
          <q-popup-edit
            v-if="
              !drinks_props.row.volumes.some((volume) =>
                volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
              )
            "
            v-slot="scope"
            v-model="drinks_props.row.cost_per_package"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model.number="scope.value"
              filled
              dense
              autofocus
              type="number"
              step="0.01"
              min="0"
              suffix="€"
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="cost_per_volume" :props="drinks_props">
          {{
            drinks_props.row.cost_per_volume
              ? `${drinks_props.row.cost_per_volume.toFixed(3)}€`
              : 'o.A.'
          }}
          <q-popup-edit
            v-if="
              !(
                !!drinks_props.row.cost_per_package &&
                !!drinks_props.row.volume &&
                !!drinks_props.row.package_size
              ) &&
              !drinks_props.row.volumes.some((volume) =>
                volume.ingredients.some((ingredient) => ingredient.drink_ingredient)
              )
            "
            v-slot="scope"
            v-model="drinks_props.row.cost_per_volume"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model.number="scope.value"
              filled
              dense
              autofocus
              type="number"
              min="0"
              step="0.1"
              suffix="€"
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-td>
        <q-td key="volumes" :props="drinks_props">
          <drink-price-volumes-table
            :rows="drinks_props.row.volumes"
            :visible-columns="visibleColumn"
            :columns="column_calc"
            :drink="drinks_props.row"
            @updateDrink="updateDrink(drinks_props.row)"
          />
        </q-td>
        <q-td key="receipt" :props="drinks_props">
          <build-manual
            :steps="drinks_props.row.receipt"
            @deleteStep="deleteStep($event, drinks_props.row)"
            @addStep="addStep($event, drinks_props.row)"
          />
          <!--<q-popup-edit
            v-slot="scope"
            v-model="drinks_props.row.receipt"
            buttons
            label-cancel="Abbrechen"
            label-set="Speichern"
            @update:modelValue="updateDrink(drinks_props.row)"
          >
            <q-input
              v-model="scope.value"
              type="textarea"
              autofocus
              counter
              @keyup.enter.stop
            />
          </q-popup-edit>-->
        </q-td>
      </q-tr>
    </template>
  </q-table>
</template>

<script lang="ts">
import { defineComponent, onBeforeMount, ComputedRef, computed, ref } from 'vue';
import DrinkPriceVolumesTable from 'src/plugins/pricelist/components/CalculationTable/DrinkPriceVolumesTable.vue';
import { useMainStore } from 'src/stores';
import { Drink, usePricelistStore } from 'src/plugins/pricelist/store';
import MinPriceSetting from 'src/plugins/pricelist/components/MinPriceSetting.vue';
import NewDrink from 'src/plugins/pricelist/components/CalculationTable/NewDrink.vue';
import BuildManual from 'src/plugins/pricelist/components/CalculationTable/BuildManual.vue';
import SearchInput from './SearchInput.vue';
import { filter, Search } from '../utils/filter';
import { Notify } from 'quasar';
import { sort } from '../utils/sort';

export default defineComponent({
  name: 'CalculationTable',
  components: { SearchInput, BuildManual, MinPriceSetting, DrinkPriceVolumesTable, NewDrink },
  setup() {
    const mainStore = useMainStore();
    const store = usePricelistStore();

    onBeforeMount(() => {
      void store.getDrinkTypes(true);
      void store.getTags();
      void store.getExtraIngredients();
      void store.get_min_prices();
      store.getPriceCalcColumn(user);
    });

    const user = mainStore.currentUser.userid;

    const columns = [
      {
        name: 'picture',
        label: 'Bild',
      },
      {
        name: 'name',
        label: 'Getränkename',
        field: 'name',
        sortable: true,
        sort,
      },

      {
        name: 'drink_type',
        label: 'Kategorie',
        field: 'type',
        format: (val: FG.DrinkType) => `${val.name}`,
        sortable: true,
        sort: (a: FG.DrinkType, b: FG.DrinkType) => sort(a.name, b.name),
      },
      {
        name: 'tags',
        label: 'Tags',
        field: 'tags',
        format: (val: Array<FG.Tag>) => {
          let retVal = '';
          val.forEach((tag, index) => {
            if (index > 0) {
              retVal += ', ';
            }
            retVal += tag.name;
          });
          return retVal;
        },
      },
      {
        name: 'article_id',
        label: 'Artikelnummer',
        field: 'article_id',
        sortable: true,
        sort,
      },
      {
        name: 'volume_package',
        label: 'Inhalt in l des Gebinde',
        field: 'volume',
        sortable: true,
        sort,
      },
      {
        name: 'package_size',
        label: 'Gebindegröße',
        field: 'package_size',
        sortable: true,
        sort,
      },
      {
        name: 'cost_per_package',
        label: 'Preis Netto/Gebinde',
        field: 'cost_per_package',
        format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
        sortable: true,
        sort,
      },
      {
        name: 'cost_per_volume',
        label: 'Preis mit 19%/Liter',
        field: 'cost_per_volume',
        format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
        sortable: true,
        sort: (a: ComputedRef, b: ComputedRef) => sort(a.value, b.value),
      },
      {
        name: 'volumes',
        label: 'Preiskalkulation',
        field: 'volumes',
      },
      {
        name: 'receipt',
        label: 'Bauanleitung',
        field: 'receipt',
      },
    ];
    const column_calc = [
      {
        name: 'volume',
        label: 'Abgabe in l',
        field: 'volume',
      },
      {
        name: 'min_prices',
        label: 'Minimal Preise',
        field: 'min_prices',
      },
      {
        name: 'prices',
        label: 'Preise',
        field: 'prices',
      },
    ];
    const column_prices = [
      {
        name: 'price',
        label: 'Preis',
        field: 'price',
        format: (val: number) => `${val.toFixed(2)}€`,
      },
      {
        name: 'description',
        label: 'Beschreibung',
        field: 'description',
      },
      {
        name: 'public',
        label: 'Öffentlich',
        field: 'public',
      },
    ];
    const visibleColumn = computed({
      get: () => store.pricecalc_columns,
      set: (val) => {
        store.updatePriceCalcColumn(user, val);
      },
    });

    // eslint-disable-next-line vue/return-in-computed-property
    const pagination = computed(() => {
      rowsPerPage: store.drinks.length;
    });

    const drinkTypes = computed(() => store.drinkTypes);

    function updateDrink(drink: Drink) {
      void store.updateDrink(drink);
    }

    function deleteDrink(drink: Drink) {
      store.deleteDrink(drink);
    }

    const showNewDrink = ref(false);

    const drinkPic = ref<File>();

    function onPictureRejected() {
      Notify.create({
        group: false,
        type: 'negative',
        message: 'Datei zu groß oder keine gültige Bilddatei.',
        timeout: 10000,
        progress: true,
        actions: [{ icon: 'mdi-close', color: 'white' }],
      });
      drinkPic.value = undefined;
    }

    function savePicture(drink: Drink) {
      console.log('hier bin ich!!!', drinkPic.value);
      if (drinkPic.value && drinkPic.value instanceof File) {
        store.upload_drink_picture(drink, drinkPic.value).catch((response: Response) => {
          if (response && response.status == 400) {
            onPictureRejected();
          }
        });
      }
    }

    function deletePicture(drink: Drink) {
      void store.delete_drink_picture(drink);
    }

    function addStep(event: string, drink: Drink) {
      console.log(event, drink.receipt);
      drink.receipt?.push(event);
      updateDrink(drink);
    }

    function deleteStep(event: number, drink: Drink) {
      console.log(event, drink.receipt);
      drink.receipt?.splice(event, 1);
      updateDrink(drink);
    }

    const search = ref<Search>({
      value: '',
      key: '',
      label: '',
    });
    return {
      drinks: computed(() => store.drinks),
      pagination,
      columns,
      column_calc,
      column_prices,
      visibleColumn,
      drinkTypes,
      updateDrink,
      deleteDrink,
      showNewDrink,
      drinkPic,
      savePicture,
      deletePicture,
      addStep,
      deleteStep,
      console,
      search,
      filter,
      tags: computed(() => store.tags),
    };
  },
});
</script>

<style scoped></style>