<!--
Part of the EditTransactionPage which controls the list of line items for the
transaction. This editor shows a table of current line items, and includes a
modal for adding a new one.
-->
<script setup lang="ts">
import { type TransactionCategoryTree, type TransactionLineItemResponse } from '@/api/transaction'
import AppButton from '@/components/common/AppButton.vue'
import FormGroup from '@/components/common/form/FormGroup.vue'
import { floatMoneyToInteger, formatMoney, type Currency } from '@/api/data'
import ModalWrapper from '@/components/common/ModalWrapper.vue'
import FormControl from '@/components/common/form/FormControl.vue'
import { computed, ref, type Ref, useTemplateRef } from 'vue'
import CategorySelect from './CategorySelect.vue'
import LineItemCard from './LineItemCard.vue'
import AppBadge from './common/AppBadge.vue'

const model = defineModel<TransactionLineItemResponse[]>({ required: true })
const props = defineProps<{
  transactionAmount: number
  currency: Currency
}>()

const computedTotal = computed(() => {
  let sum = 0
  for (const item of model.value) {
    sum += item.quantity * item.valuePerItem
  }
  return sum
})

const addLineItemDescription = ref('')
const addLineItemValuePerItem = ref(0)
const addLineItemQuantity = ref(0)
const addLineItemCategoryId: Ref<number | null> = ref(null)
const selectedCategory: Ref<TransactionCategoryTree | null> = ref(null)
const addLineItemModal = useTemplateRef('addLineItemModal')

function canAddLineItem() {
  return addLineItemDescription.value.length > 0 && addLineItemQuantity.value > 0
}

function showAddLineItemModal() {
  addLineItemDescription.value = ''
  addLineItemValuePerItem.value = 1.0
  addLineItemQuantity.value = 1
  addLineItemCategoryId.value = null
  addLineItemModal.value?.show()
}

async function addLineItem() {
  const newIdx = model.value.length === 0 ? 0 : Math.max(...model.value.map((i) => i.idx)) + 1
  model.value.push({
    idx: newIdx,
    description: addLineItemDescription.value,
    quantity: addLineItemQuantity.value,
    valuePerItem: floatMoneyToInteger(addLineItemValuePerItem.value, props.currency),
    category: selectedCategory.value,
  })
  addLineItemModal.value?.close()
}

function removeLineItem(idx: number) {
  model.value = model.value.filter((i) => i.idx !== idx)
  for (let i = 0; i < model.value.length; i++) {
    model.value[i].idx = i
  }
}

function moveItemUp(idx: number) {
  if (idx <= 0) return
  const item = model.value[idx]
  model.value[idx] = model.value[idx - 1]
  model.value[idx - 1] = item
  for (let i = 0; i < model.value.length; i++) {
    model.value[i].idx = i
  }
}

function moveItemDown(idx: number) {
  if (idx >= model.value.length - 1) return
  const item = model.value[idx]
  model.value[idx] = model.value[idx + 1]
  model.value[idx + 1] = item
  for (let i = 0; i < model.value.length; i++) {
    model.value[i].idx = i
  }
}
</script>
<template>
  <div>
    <LineItemCard
      v-for="item in model"
      :key="item.idx"
      :line-item="item"
      :currency="currency"
      :total-count="model.length"
      editable
      @deleted="removeLineItem(item.idx)"
      @moved-up="moveItemUp(item.idx)"
      @moved-down="moveItemDown(item.idx)"
    />
    <div>
      <AppButton
        icon="plus"
        @click="showAddLineItemModal()"
        >Add Line Item</AppButton
      >
      <AppBadge
        v-if="model.length > 0"
        :class="{
          'text-positive': computedTotal === transactionAmount,
          'text-negative': computedTotal !== transactionAmount,
        }"
      >
        Items Total: {{ formatMoney(computedTotal, currency) }}
      </AppBadge>
    </div>

    <!-- Modal for adding a new line item. -->
    <ModalWrapper ref="addLineItemModal">
      <template v-slot:default>
        <h3>Add Line Item</h3>
        <FormGroup>
          <FormControl label="Description">
            <textarea v-model="addLineItemDescription"></textarea>
          </FormControl>
          <FormControl label="Value Per Item">
            <input
              type="number"
              step="0.01"
              v-model="addLineItemValuePerItem"
            />
          </FormControl>
          <FormControl label="Quantity">
            <input
              type="number"
              step="1"
              min="1"
              v-model="addLineItemQuantity"
            />
          </FormControl>
          <FormControl label="Category">
            <CategorySelect
              v-model="addLineItemCategoryId"
              @category-selected="(c) => (selectedCategory = c)"
            />
          </FormControl>
        </FormGroup>
      </template>
      <template v-slot:buttons>
        <AppButton
          @click="addLineItem()"
          :disabled="!canAddLineItem()"
          >Add</AppButton
        >
        <AppButton
          button-style="secondary"
          @click="addLineItemModal?.close()"
          >Cancel</AppButton
        >
      </template>
    </ModalWrapper>
  </div>
</template>
