<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]"
  >
    <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">
        <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 anchor="center middle" self="center middle">
            <div class="q-pa-sm">
              <div class="q-table__title q-pa-sm">Neues Getränk</div>
              <div class="row">
                <q-input
                  v-model="newDrink.name"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Getränkname"
                />
                <q-input
                  v-model="newDrink.article_id"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Artikelnummer"
                />
                <q-select
                  v-model="newDrink.type"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Kategorie"
                  :options="drinkTypes"
                  option-label="name"
                />
                <q-input
                  v-model.number="newDrink.volume"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Inhalt in L/Gebinde"
                  type="number"
                />
                <q-input
                  v-model.number="newDrink.package_size"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Gebindegröße"
                  type="number"
                />
                <q-input
                  v-model.number="newDrink.cost_price_package_netto"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Preis Netto/Gebinde"
                  type="number"
                />
                <q-input
                  v-model="cost_price_pro_volume"
                  class="col-sm-4 col-xs-6 q-pa-sm"
                  filled
                  label="Preis mit 19%/Liter"
                  :disable="calc_price_pro_volume"
                />
              </div>
              <div class="row justify-between">
                <q-btn v-close-popup label="Abbrechen" @click="cancelAddDrink" />
                <q-btn v-close-popup label="Speichern" color="primary" @click="addDrink" />
              </div>
            </div>
          </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="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"
              filled
              dense
              autofocus
              @keyup.enter="scope.set"
            />
          </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_price_package_netto" :props="drinks_props">
          {{
            drinks_props.row.cost_price_package_netto
              ? `${drinks_props.row.cost_price_package_netto.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_price_package_netto"
            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_price_pro_volume" :props="drinks_props">
          {{
            drinks_props.row.cost_price_pro_volume
              ? `${drinks_props.row.cost_price_pro_volume.toFixed(3)}€`
              : 'o.A.'
          }}
          <q-popup-edit
            v-if="
              !(
                !!drinks_props.row.cost_price_package_netto &&
                !!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_price_pro_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-tr>
    </template>
  </q-table>
</template>

<script lang="ts">
import { defineComponent, onBeforeMount, ref, ComputedRef, computed } from 'vue';
import DrinkPriceVolumesTable from 'src/plugins/pricelist/components/CalculationTable/DrinkPriceVolumesTable.vue';
import { useMainStore } from 'src/store';
import { Drink, usePricelistStore } from 'src/plugins/pricelist/store';
import MinPriceSetting from 'src/plugins/pricelist/components/MinPriceSetting.vue';

function sort(a: string | number, b: string | number) {
  if (a > b) return 1;
  if (b > a) return -1;
  return 0;
}
export default defineComponent({
  name: 'CalculationTable',
  components: { MinPriceSetting, DrinkPriceVolumesTable },
  setup() {
    const mainStore = useMainStore();
    const store = usePricelistStore();

    onBeforeMount(() => {
      store.getPriceCalcColumn(user);
    });

    const user = mainStore.currentUser.userid;

    const columns = [
      {
        name: 'name',
        label: 'Getränkename',
        field: 'name',
        sortable: true,
        sort,
      },
      {
        name: 'article_id',
        label: 'Artikelnummer',
        field: 'article_id',
        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: '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_price_package_netto',
        label: 'Preis Netto/Gebinde',
        field: 'cost_price_package_netto',
        format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
        sortable: true,
        sort,
      },
      {
        name: 'cost_price_pro_volume',
        label: 'Preis mit 19%/Liter',
        field: 'cost_price_pro_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',
      },
    ];
    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 emptyDrink: FG.Drink = {
      id: -1,
      article_id: undefined,
      package_size: undefined,
      name: '',
      volume: undefined,
      cost_price_pro_volume: undefined,
      cost_price_package_netto: undefined,
      tags: [],
      type: undefined,
      volumes: [],
    };

    const newDrink = ref<FG.Drink>(emptyDrink);
    const calc_price_pro_volume = computed(
      () =>
        !!newDrink.value.cost_price_package_netto &&
        !!newDrink.value.volume &&
        !!newDrink.value.package_size
    );
    const cost_price_pro_volume = computed({
      get: () => {
        if (calc_price_pro_volume.value) {
          const retVal =
            ((newDrink.value.cost_price_package_netto || 0) /
              ((newDrink.value.volume || 0) * (newDrink.value.package_size || 0))) *
            1.19;
          // eslint-disable-next-line vue/no-side-effects-in-computed-properties
          newDrink.value.cost_price_pro_volume = Math.round(retVal * 1000) / 1000;
        }
        return newDrink.value.cost_price_pro_volume;
      },
      set: (val) => {
        newDrink.value.cost_price_pro_volume = val;
      },
    });

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

    function addDrink() {
      void store.setDrink(newDrink.value);
      cancelAddDrink();
    }
    function cancelAddDrink() {
      setTimeout(() => (newDrink.value = emptyDrink), 200);
    }
    function updateDrink(drink: Drink) {
      void store.updateDrink(drink);
    }
    function deleteDrink(drink: Drink) {
      store.deleteDrink(drink);
    }

    return {
      drinks: computed(() => store.drinks),
      pagination,
      columns,
      column_calc,
      column_prices,
      visibleColumn,
      newDrink,
      cost_price_pro_volume,
      calc_price_pro_volume,
      drinkTypes,
      addDrink,
      cancelAddDrink,
      updateDrink,
      deleteDrink,
      console,
    };
  },
});
</script>

<style scoped></style>