<template>
  <q-table
    v-model:pagination="pagination"
    title="Preistabelle"
    :columns="columns"
    :rows="drinks"
    dense
    :filter="search"
    :filter-method="filter"
    grid
    :rows-per-page-options="[0]"
  >
    <template #top-right>
      <div class="row justify-end q-gutter-sm">
        <search-input v-model="search" :keys="search_keys" />
        <slot></slot>
        <q-btn v-if="!public && !nodetails" label="Aufpreise">
          <q-menu anchor="center middle" self="center middle">
            <min-price-setting />
          </q-menu>
        </q-btn>
        <q-btn
          v-if="!public && !nodetails && editable && hasPermission(PERMISSIONS.CREATE)"
          color="primary"
          round
          icon="mdi-plus"
          @click="newDrink"
        >
          <q-tooltip> Neues Getränk </q-tooltip>
        </q-btn>
      </div>
    </template>
    <template #item="props">
      <div class="q-pa-xs col-xs-12 col-sm-6 col-md-4">
        <q-card>
          <q-img
            style="max-height: 256px"
            :src="
              props.row.uuid ? `/api/pricelist/picture/${props.row.uuid}?size=400` : 'no-image.svg'
            "
          >
            <div
              v-if="!public && !nodetails && editable"
              class="absolute-top-right justify-end"
              style="background-color: transparent"
            >
              <q-btn
                round
                icon="mdi-pencil"
                style="background-color: rgba(0, 0, 0, 0.5)"
                @click="editDrink = props.row"
              />
            </div>
            <div class="absolute-bottom-right justify-end">
              <div class="text-subtitle1 text-right">
                {{ props.row.name }}
              </div>
              <div class="text-caption text-right">
                {{ props.row.type.name }}
              </div>
            </div>
          </q-img>
          <q-card-section>
            <q-badge
              v-for="tag in props.row.tags"
              :key="`${props.row.id}-${tag.id}`"
              class="text-caption"
              rounded
              :style="`background-color: ${tag.color}`"
            >
              {{ tag.name }}
            </q-badge>
          </q-card-section>
          <q-card-section v-if="!public && !nodetails">
            <div class="fit row">
              <q-input
                v-if="props.row.article_id"
                class="col-xs-12 col-sm-6 q-pa-sm"
                :model-value="props.row.article_id"
                outlined
                readonly
                label="Artikelnummer"
                dense
              />
              <q-input
                v-if="props.row.volume"
                class="col-xs-12 col-sm-6 q-pa-sm"
                :model-value="props.row.volume"
                outlined
                readonly
                label="Inhalt"
                dense
                suffix="L"
              />
              <q-input
                v-if="props.row.package_size"
                class="col-xs-12 col-sm-6 q-pa-sm"
                :model-value="props.row.package_size"
                outlined
                readonly
                label="Gebindegröße"
                dense
              />
              <q-input
                v-if="props.row.cost_per_package"
                class="col-xs-12 col-sm-6 q-pa-sm"
                :model-value="props.row.cost_per_package"
                outlined
                readonly
                label="Preis Gebinde"
                suffix="€"
                dense
              />
              <q-input
                v-if="props.row.cost_per_volume"
                class="col-xs-12 col-sm-6 q-pa-sm q-pb-lg"
                :model-value="props.row.cost_per_volume"
                outlined
                readonly
                label="Preis pro L"
                hint="Inkl. 19% Mehrwertsteuer"
                suffix="€"
                dense
              />
            </div>
          </q-card-section>
          <q-card-section v-if="props.row.volumes.length > 0 && notLoading">
            <drink-price-volumes
              :model-value="props.row.volumes"
              :public="public"
              :nodetails="nodetails"
            />
          </q-card-section>
        </q-card>
      </div>
    </template>
  </q-table>
  <q-dialog :model-value="editDrink !== undefined" persistent>
    <drink-modify
      :drink="editDrink"
      @save="editing_drink"
      @cancel="editDrink = undefined"
      @delete="deleteDrink"
    />
  </q-dialog>
</template>

<script lang="ts">
import { defineComponent, onBeforeMount, ComputedRef, computed, ref } from 'vue';
import { Drink, usePricelistStore, DrinkPriceVolume } from 'src/plugins/pricelist/store';
import MinPriceSetting from 'src/plugins/pricelist/components/MinPriceSetting.vue';
import SearchInput from './SearchInput.vue';
import DrinkPriceVolumes from 'src/plugins/pricelist/components/CalculationTable/DrinkPriceVolumes.vue';
import DrinkModify from './DrinkModify.vue';
import { filter, Search } from '../utils/filter';
import { Notify } from 'quasar';
import { sort } from '../utils/sort';
import { DeleteObjects } from 'src/plugins/pricelist/utils/utils';
import { hasPermission } from 'src/utils/permission';
import { PERMISSIONS } from 'src/plugins/pricelist/permissions';

export default defineComponent({
  name: 'CalculationTable',
  components: {
    SearchInput,
    MinPriceSetting,
    DrinkPriceVolumes,
    DrinkModify,
  },
  props: {
    public: {
      type: Boolean,
      default: false,
    },
    editable: {
      type: Boolean,
      default: false,
    },
    nodetails: {
      type: Boolean,
      default: false,
    },
  },
  setup(props) {
    const store = usePricelistStore();

    onBeforeMount(() => {
      void store.getDrinks();
    });

    const columns = [
      {
        name: 'picture',
        label: 'Bild',
      },
      {
        name: 'name',
        label: 'Name',
        field: 'name',
        sortable: true,
        sort,
        filterable: true,
        public: true,
      },

      {
        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),
        filterable: true,
        public: true,
      },
      {
        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;
        },
        filterable: true,
        public: true,
      },
      {
        name: 'article_id',
        label: 'Artikelnummer',
        field: 'article_id',
        sortable: true,
        sort,
        filterable: true,
        public: false,
      },
      {
        name: 'volume_package',
        label: 'Inhalt in l des Gebinde',
        field: 'volume',
        sortable: true,
        sort,
        public: false,
      },
      {
        name: 'package_size',
        label: 'Gebindegröße',
        field: 'package_size',
        sortable: true,
        sort,
        public: false,
      },
      {
        name: 'cost_per_package',
        label: 'Preis Netto/Gebinde',
        field: 'cost_per_package',
        format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
        sortable: true,
        sort,
        public: false,
      },
      {
        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',
        format: (val: Array<DrinkPriceVolume>) => {
          let retVal = '';
          val.forEach((val, index) => {
            if (index > 0) {
              retVal += ', ';
            }
            retVal += val.id;
          });
          return retVal;
        },
        sortable: false,
      },
      {
        name: 'receipt',
        label: 'Bauanleitung',
        field: 'receipt',
        format: (val: Array<string>) => {
          let retVal = '';
          val.forEach((value, index) => {
            if (index > 0) {
              retVal += ', ';
            }
            retVal += value;
          });
          return retVal;
        },
        filterable: true,
        sortable: false,
        public: false,
      },
    ];
    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 search_keys = computed(() =>
      columns.filter(
        (column) => column.filterable && (props.public || props.nodetails ? column.public : true)
      )
    );

    const pagination = ref({
      sortBy: 'name',
      descending: false,
      rowsPerPage: store.drinks.length,
    });

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

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

    function deleteDrink() {
      if (editDrink.value) {
        store.deleteDrink(editDrink.value);
      }
      editDrink.value = undefined;
    }

    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;
    }

    async function savePicture(drinkPic: File) {
      if (editDrink.value) {
        await store.upload_drink_picture(editDrink.value, drinkPic).catch((response: Response) => {
          if (response && response.status == 400) {
            onPictureRejected();
          }
        });
      }
    }

    async function deletePicture() {
      if (editDrink.value) {
        await store.delete_drink_picture(editDrink.value);
      }
    }

    const search = ref<Search>({
      value: '',
      key: '',
      label: '',
    });

    const emptyDrink: Drink = {
      id: -1,
      article_id: undefined,
      package_size: undefined,
      name: '',
      volume: undefined,
      cost_per_volume: undefined,
      cost_per_package: undefined,
      tags: [],
      type: undefined,
      volumes: [],
      uuid: '',
    };

    function newDrink() {
      editDrink.value = Object.assign({}, emptyDrink);
    }

    const editDrink = ref<Drink>();

    async function editing_drink(
      drink: Drink,
      toDeleteObjects: DeleteObjects,
      drinkPic: File | undefined,
      deletePic: boolean
    ) {
      notLoading.value = false;
      for (const ingredient of toDeleteObjects.ingredients) {
        await store.deleteIngredient(ingredient);
      }
      for (const price of toDeleteObjects.prices) {
        await store.deletePrice(price);
      }
      for (const volume of toDeleteObjects.volumes) {
        await store.deleteVolume(volume, drink);
      }
      console.log(drink);
      if (drink.id > 0) {
        await store.updateDrink(drink);
      } else {
        const _drink = await store.setDrink(drink);
        if (editDrink.value) {
          editDrink.value.id = _drink.id;
        }
      }
      if (deletePic) {
        await deletePicture();
      }
      if (drinkPic instanceof File) {
        await savePicture(drinkPic);
      }
      editDrink.value = undefined;
      notLoading.value = true;
    }

    function get_volumes(drink_id: number) {
      return store.drinks.find((a) => a.id === drink_id)?.volumes;
    }

    const notLoading = ref(true);

    const imageloading = ref<Array<{ id: number; loading: boolean }>>([]);
    function getImageLoading(id: number) {
      const loading = imageloading.value.find((a) => a.id === id);
      if (loading) {
        return loading.loading;
      }
      return false;
    }

    return {
      drinks: computed(() => store.drinks),
      pagination,
      columns,
      column_calc,
      column_prices,
      drinkTypes,
      updateDrink,
      deleteDrink,
      showNewDrink,
      drinkPic,
      savePicture,
      deletePicture,
      console,
      search,
      filter,
      search_keys,
      tags: computed(() => store.tags),
      editDrink,
      editing_drink,
      get_volumes,
      notLoading,
      getImageLoading,
      newDrink,
      hasPermission,
      PERMISSIONS,
    };
  },
});
</script>

<style scoped></style>