<template>
  <div>
    <v-card variant="outlined">
      <v-card-text class="pb-3 pt-1">
        <div class="d-md-flex align-center mb-2" style="gap: 20px">
          <div>
            <v-number-input
              v-model="listItem.quantity"
              hide-details
              :label="$t('form.quantity-label-abbreviated')"
              :min="0"
              :precision="null"
              control-variant="stacked"
              inset
              style="width: 100px;"
            />
          </div>
          <InputLabelType
            v-model="listItem.unit"
            v-model:item-id="listItem.unitId!"
            :items="units"
            :label="$t('recipe.unit')"
            :icon="$globals.icons.units"
            create
            @create="createAssignUnit"
          />
          <InputLabelType
            v-model="listItem.food"
            v-model:item-id="listItem.foodId!"
            :items="foods"
            :label="$t('shopping-list.food')"
            :icon="$globals.icons.foods"
            :autofocus="autoFocus === 'food'"
            create
            @create="createAssignFood"
          />
        </div>
        <div class="d-md-flex align-center" style="gap: 20px">
          <v-textarea
            v-model="listItem.note"
            hide-details
            :label="$t('shopping-list.note')"
            rows="1"
            auto-grow
            :autofocus="autoFocus === 'note'"
            @keypress="handleNoteKeyPress"
          />
        </div>
        <div class="d-flex flex-wrap align-end" style="gap: 20px">
          <div class="d-flex align-end">
            <div style="max-width: 300px" class="mt-3 mr-auto">
              <InputLabelType
                v-model="listItem.label"
                v-model:item-id="listItem.labelId!"
                :items="labels"
                :label="$t('shopping-list.label')"
                width="250"
              />
            </div>
          </div>
          <BaseButton
            v-if="listItem.labelId && listItem.food && listItem.labelId !== listItem.food.labelId"
            small
            color="info"
            :icon="$globals.icons.tagArrowRight"
            :text="$t('shopping-list.save-label')"
            class="mt-2 align-items-flex-start"
            @click="assignLabelToFood"
          />
          <v-spacer />
        </div>
      </v-card-text>
      <v-card-actions class="ma-0 pt-0 pb-1 justify-end">
        <BaseButtonGroup
          :buttons="[
            ...(allowDelete
              ? [
                {
                  icon: $globals.icons.delete,
                  text: $t('general.delete'),
                  event: 'delete',
                },
              ]
              : []),
            {
              icon: $globals.icons.close,
              text: $t('general.cancel'),
              event: 'cancel',
            },
            {
              icon: $globals.icons.save,
              text: $t('general.save'),
              event: 'save',
            },
          ]"
          @save="$emit('save')"
          @cancel="$emit('cancel')"
          @delete="$emit('delete')"
        />
      </v-card-actions>
    </v-card>
  </div>
</template>

<script setup lang="ts">
import type { ShoppingListItemCreate, ShoppingListItemOut } from "~/lib/api/types/household";
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
import type { IngredientFood, IngredientUnit } from "~/lib/api/types/recipe";
import { useFoodStore, useFoodData, useUnitStore, useUnitData } from "~/composables/store";

// modelValue as reactive v-model
const listItem = defineModel<ShoppingListItemCreate | ShoppingListItemOut>({ required: true });

defineProps({
  labels: {
    type: Array as () => MultiPurposeLabelOut[],
    required: true,
  },
  units: {
    type: Array as () => IngredientUnit[],
    required: true,
  },
  foods: {
    type: Array as () => IngredientFood[],
    required: true,
  },
  allowDelete: {
    type: Boolean,
    required: false,
    default: true,
  },
});

// const emit = defineEmits<["save", "cancel", "delete"]>();
const emit = defineEmits<{
  (e: "save", item: ShoppingListItemOut): void;
  (e: "cancel" | "delete"): void;
}>();

const foodStore = useFoodStore();
const foodData = useFoodData();

const unitStore = useUnitStore();
const unitData = useUnitData();

watch(
  () => listItem.value.quantity,
  (newQty) => {
    if (!newQty) {
      listItem.value.quantity = 0;
    }
  },
);

watch(
  () => listItem.value.food,
  (newFood) => {
    listItem.value.label = newFood?.label || null;
    listItem.value.labelId = listItem.value.label?.id || null;
  },
);

const autoFocus = computed(() => (!listItem.value.food && listItem.value.note ? "note" : "food"));

async function createAssignFood(val: string) {
  // keep UI reactive
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  listItem.value.food ? (listItem.value.food.name = val) : (listItem.value.food = { name: val } as any);

  foodData.data.name = val;
  const newFood = await foodStore.actions.createOne(foodData.data);
  if (newFood) {
    listItem.value.food = newFood;
    listItem.value.foodId = newFood.id;
  }
  foodData.reset();
}

async function createAssignUnit(val: string) {
  // keep UI reactive
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  listItem.value.unit ? (listItem.value.unit.name = val) : (listItem.value.unit = { name: val } as any);

  unitData.data.name = val;
  const newUnit = await unitStore.actions.createOne(unitData.data);
  if (newUnit) {
    listItem.value.unit = newUnit;
    listItem.value.unitId = newUnit.id;
  }
  unitData.reset();
}

async function assignLabelToFood() {
  if (!(listItem.value.food && listItem.value.foodId && listItem.value.labelId)) {
    return;
  }

  listItem.value.food.labelId = listItem.value.labelId;
  await foodStore.actions.updateOne(listItem.value.food);
}

function handleNoteKeyPress(event: KeyboardEvent) {
  const e = event as KeyboardEvent & { key: string; shiftKey: boolean };
  if (!e.shiftKey && e.key === "Enter") {
    e.preventDefault();
    emit("save");
  }
}
</script>
