<template>
  <q-table
    title="Preisliste"
    :columns="columns"
    :rows="drinks"
    :visible-columns="visibleColumns"
    :filter="search"
    :filter-method="filter"
    dense
    :pagination="pagination"
    :fullscreen="fullscreen"
  >
    <template #top-right>
      <div class="row justify-end q-gutter-sm">
        <search-input v-model="search" :keys="options" />
        <q-select
          v-model="visibleColumns"
          multiple
          filled
          dense
          options-dense
          display-value="Sichtbarkeit"
          emit-value
          map-options
          :options="options"
          option-value="name"
          options-cover
        />
        <q-btn round icon="mdi-backburger">
          <q-tooltip anchor="top middle" self="bottom middle"> Reihenfolge ändern </q-tooltip>
          <q-menu anchor="bottom middle" self="top middle">
            <drag v-model="order" class="q-list" ghost-class="ghost" group="people" item-key="id">
              <template #item="{ element }">
                <q-item>
                  <q-item-section>
                    {{ element.label }}
                  </q-item-section>
                </q-item>
              </template>
            </drag>
          </q-menu>
        </q-btn>
        <slot></slot>
        <q-btn
          round
          :icon="fullscreen ? 'mdi-fullscreen-exit' : 'mdi-fullscreen'"
          @click="fullscreen = !fullscreen"
        />
      </div>
    </template>
    <template #body-cell-tags="props">
      <q-td :props="props">
        <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-td>
    </template>
    <template #body-cell-public="props">
      <q-td :props="props">
        <q-toggle
          v-model="props.row.public"
          disable
          checked-icon="mdi-earth"
          unchecked-icon="mdi-earth-off"
        />
      </q-td>
    </template>
  </q-table>
</template>

<script lang="ts">
import { computed, defineComponent, onBeforeMount, ref, ComponentPublicInstance } from 'vue';
import SearchInput from '../components/SearchInput.vue';
import { usePricelistStore, Order } from '../store';
import { useMainStore } from '@flaschengeist/api';
import { Search, filter } from '../utils/filter';
import drag from 'vuedraggable';

interface Row {
  name: string;
  label: string;
  field: string;
  sortable?: boolean;
  filterable?: boolean;
  format?: (val: never) => string;
  align?: string;
}

export default defineComponent({
  name: 'Pricelist',
  components: { SearchInput, drag: <ComponentPublicInstance>drag },
  props: {
    public: {
      type: Boolean,
      default: false,
    },
  },
  setup(props) {
    const store = usePricelistStore();
    const user = ref('');

    onBeforeMount(() => {
      if (!props.public) {
        user.value = useMainStore().currentUser.userid;
        void store.getPriceListColumnOrder(user.value);
        void store.getDrinks();
        void store.getPriceCalcColumn(user.value);
      } else {
        user.value = '';
      }
    });

    const _order = ref<Array<Order>>([
      {
        name: 'name',
        label: 'Name',
      },
      {
        name: 'type',
        label: 'Kategorie',
      },
      {
        name: 'tags',
        label: 'Tags',
      },
      {
        name: 'volume',
        label: 'Inhalt',
      },
      {
        name: 'price',
        label: 'Preis',
      },
      {
        name: 'public',
        label: 'Öffentlich',
      },
      {
        name: 'description',
        label: 'Beschreibung',
      },
    ]);

    const order = computed<Array<Order>>({
      get: () => {
        if (props.public) {
          return _order.value;
        }
        if (store.pricelist_columns_order.length === 0) {
          return _order.value;
        }
        return store.pricelist_columns_order;
      },
      set: (val: Array<Order>) => {
        if (!props.public) {
          void store.updatePriceListColumnOrder(user.value, val);
        } else {
          _order.value = val;
        }
      },
    });

    const _columns: Array<Row> = [
      {
        name: 'name',
        label: 'Name',
        field: 'name',
        sortable: true,
        filterable: true,
        align: 'left',
      },
      {
        name: 'type',
        label: 'Kategorie',
        field: 'type',
        sortable: true,
        filterable: true,
        format: (val: FG.DrinkType) => val.name,
      },
      {
        name: 'tags',
        label: 'Tags',
        field: 'tags',
        filterable: true,

        format: (val: Array<FG.Tag>) => {
          let retVal = '';
          val.forEach((tag, index) => {
            if (index >= val.length - 1 && index > 0) {
              retVal += ', ';
            }
            retVal += tag.name;
          });
          return retVal;
        },
      },
      {
        name: 'volume',
        label: 'Inhalt',
        field: 'volume',
        filterable: true,
        sortable: true,
        format: (val: number) => `${val.toFixed(3)}L`,
      },
      {
        name: 'price',
        label: 'Preis',
        field: 'price',
        sortable: true,
        filterable: true,
        format: (val: number) => `${val.toFixed(2)}€`,
      },
      {
        name: 'public',
        label: 'Öffentlich',
        field: 'public',
        format: (val: boolean) => (val ? 'Öffentlich' : 'nicht Öffentlich'),
      },
      {
        name: 'description',
        label: 'Beschreibung',
        field: 'description',
        filterable: true,
      },
    ];

    const columns = computed(() => {
      const retVal: Array<Row> = [];
      if (order.value) {
        order.value.forEach((col) => {
          const _col = _columns.find((a) => a.name === col.name);
          if (_col) {
            retVal.push(_col);
          }
        });
        retVal.forEach((element, index) => {
          element.align = 'right';
          if (index === 0) {
            element.align = 'left';
          }
        });
        return retVal;
      }
      return _columns;
    });

    const _options = computed(() => {
      const retVal: Array<{ name: string; label: string; field: string }> = [];
      columns.value.forEach((col) => {
        if (props.public) {
          if (col.name !== 'public') {
            retVal.push(col);
          }
        } else {
          retVal.push(col);
        }
      });
      return retVal;
    });

    const _colums = computed<Array<string>>(() => {
      const retVal: Array<string> = [];
      columns.value.forEach((col) => {
        if (props.public) {
          if (col.name !== 'public') {
            retVal.push(col.name);
          }
        } else {
          retVal.push(col.name);
        }
      });
      return retVal;
    });

    const _visibleColumns = ref(_colums.value);

    const visibleColumns = computed({
      get: () => (props.public ? _visibleColumns.value : store.pricecalc_columns),
      set: (val) => {
        if (!props.public) {
          void store.updatePriceCalcColumn(user.value, val);
        } else {
          _visibleColumns.value = val;
        }
      },
    });

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

    const pagination = ref({
      sortBy: 'name',
      rowsPerPage: 10,
    });

    const fullscreen = ref(false);

    return {
      drinks: computed(() => store.pricelist),
      columns,
      order,
      visibleColumns,
      options: _options,
      search,
      filter,
      pagination,
      fullscreen,
    };
  },
});
</script>

<style scoped lang="sass">
.ghost
  opacity: 0.5
  background: $accent
</style>
