<script setup lang="ts">

import {DatePicker, Divider, InputNumber} from "primevue";
import ConfirmDialog from "@/components/ConfirmDialog.vue";
import {useRoute, useRouter} from "vue-router";
import {useToolbarStore} from "@/stores/toolbar-store";
import {useToast} from "primevue/usetoast";
import {useSpaceStore} from "@/stores/spaceStore";
import {computed, onMounted, ref} from "vue";
import {Category} from "@/models/category";
import {TransactionService} from "@/services/transactions-service";
import {CreateTransactionDTO, UpdateTransactionDTO} from "@/models/transaction";
import {CategoryType, TransactionKind, TransactionKindName, TransactionType, TransactionTypeName} from "@/models/enums";
import {useTransactionStore} from "@/stores/transactions-store";
import {categoriesService} from "@/services/categories-service";


const route = useRoute();
const openMode = route.query.mode;

const router = useRouter()
const toolbar = useToolbarStore();
const toast = useToast();
const spaceStore = useSpaceStore();
const transactionService = TransactionService
const transactionStore = useTransactionStore()
const tgApp = window.Telegram.WebApp

const isCategorySelectorOpened = ref(false);
const categorySearchQuery = ref<string>("");
const categories = ref<Category[]>([]);

const normalizedQuery = computed(() =>
    categorySearchQuery.value.trim().toLowerCase()
);

const incomeCategories = computed(() =>
    categories.value.filter(i =>
        i.type === CategoryType.INCOME &&
        (normalizedQuery.value
            ? i.name.toLowerCase().includes(normalizedQuery.value)
            : true)
    )
);

const expenseCategories = computed(() =>
    categories.value.filter(i =>
        i.type === CategoryType.EXPENSE &&
        (normalizedQuery.value
            ? i.name.toLowerCase().includes(normalizedQuery.value)
            : true)
    )
);
const transactionId = ref<number | undefined>(route.params.id)
const mode = computed(() => {
  return transactionId.value ? "edit" : "create"
})

const isDeleteAlertVisible = ref(false)
const deleteAlertMessage = ref('Do you want to delete transaction?')

// Генерим опции: [{ label: "Расходы", value: "EXPENSE" }, ...]
const optionsType = Object.values(TransactionType).map(type => ({
  label: TransactionTypeName[type],
  value: type
}))

// Генерим опции: [{ label: "Расходы", value: "EXPENSE" }, ...]
const optionsKind = Object.values(TransactionKind).map(type => ({
  label: TransactionKindName[type],
  value: type
}))


const transactionType = ref<TransactionType>(TransactionType.EXPENSE)
const isTypeError = ref<boolean>(false);
const transactionKind = ref<TransactionKind>(TransactionKind.INSTANT)
const isKindError = ref<boolean>(false);
const transactionCategory = ref<Category>({} as Category)
const isCategoryError = ref(false)
const transactionComment = ref<string>('')
const isCommentError = ref(false)
const transactionAmount = ref<number>(0)
const isAmountError = ref(false)
const transactionDate = ref<Date>(new Date())
const isDateError = ref(false)
const isDone = ref(false)

const fetchCategories = async () => {

  try {
    if (spaceStore.selectedSpaceId) {
      categories.value = await categoriesService.fetchCategories(spaceStore.selectedSpaceId)
      if (categories.value.length > 0) {
        transactionCategory.value = categories.value[0]
      }
    } else throw Error("No space selected")
  } catch (error) {
    console.error(error)
    toast.add({
      severity: "error",
      summary: "Error while fetching categories.",
      detail: error.message,
      life: 3000
    })
  }
}

const fetchData = async () => {

  try {
    if (spaceStore.selectedSpaceId && transactionId.value) {
      categories.value = await categoriesService.fetchCategories(spaceStore.selectedSpaceId);
      let data = await transactionService.getTransaction(spaceStore.selectedSpaceId, Number(transactionId.value));
      transactionType.value = data.type;
      transactionKind.value = data.kind;
      transactionCategory.value = data.category;
      transactionComment.value = data.comment;
      transactionAmount.value = data.amount;
      transactionDate.value = new Date(data.date);
    } else {
      throw new Error("Could not find any space")
    }
  } catch (error) {
    if (error.status === 404) {
      await moveUser()
    }
    toast.add({
      severity: "error",
      summary: "Failed to load transaction data.",
      detail: error.status,
      life: 3000
    })
  }
}

const validateForm = (): boolean => {
  // if (!transactionType.value) {
  //   isTypeError.value = true;
  //   return false;
  // }
  // if (!transactionKind.value) {
  //   isKindError.value = true;
  //   return false;
  // }
  if (!transactionCategory.value) {
    isCategoryError.value = true
    return false
  }
  if (transactionComment.value.length == 0) {
    isCommentError.value = true
    return false
  }
  if (transactionAmount.value <= 0) {
    isAmountError.value = true
    return false
  }
  if (!transactionDate.value) {
    isDateError.value = true
    return false
  }
  return true
}

const buildUpdate = (): UpdateTransactionDTO => {
  if (validateForm()) {
    return {
      type: transactionType.value,
      kind: transactionDate.value < new Date() ? TransactionKind.INSTANT : TransactionKind.PLANNING,
      categoryId: transactionCategory.value.id,
      comment: transactionComment.value,
      amount: transactionAmount.value,
      fees: 0,
      isDone: isDone.value,
      date: transactionDate.value
    } as UpdateTransactionDTO
  } else {
    throw new Error("Form is not valid")
  }
}

const buildCreate = (): CreateTransactionDTO => {
  if (validateForm()) {
    return {
      type: transactionType.value,
      kind: transactionDate.value < new Date() ? TransactionKind.INSTANT : TransactionKind.PLANNING,
      categoryId: transactionCategory.value.id,
      comment: transactionComment.value,
      amount: transactionAmount.value,
      fees: 0,
      date: transactionDate.value
    } as CreateTransactionDTO
  } else {
    throw new Error("Form is not valid")
  }
}

const moveUser = async () => {
  if (window.history.length > 1) {
    console.log('moved back')
    router.back()
  } else {
    console.log('moved forward')
    await router.push('/transactions')
  }
}

const deleteTransaction = async () => {
  if (spaceStore.selectedSpaceId && transactionId.value) {
    await transactionService.deleteTransaction(spaceStore.selectedSpaceId, Number(transactionId.value))
    // await transactionStore.fetchTransactions(spaceStore.selectedSpaceId)
    if (openMode && openMode === "from_bot") {
      console.log("test from bot")
      tgApp.close()
    } else await moveUser()
  }
}

const insetTop = ref(54)


onMounted(async () => {
  if (route.query.type === "EXPENSE") transactionType.value = TransactionType.EXPENSE
  if (route.query.type === "INCOME") transactionType.value = TransactionType.INCOME

  if (route.query.kind === "INSTANT") transactionKind.value = TransactionKind.INSTANT
  if (route.query.kind === "PLANNING") transactionKind.value = TransactionKind.PLANNING

// Remove query params AFTER reading them
  if (route.query.type || route.query.kind) {
    router.replace({path: route.path}) // instead of window.location
  }
  await fetchCategories()
  if (tgApp && ['ios', 'android'].includes(tgApp.platform)) {
    insetTop.value = tgApp.contentSafeAreaInset.top + tgApp.safeAreaInset.top
  }

  if (mode.value === "edit") {
    await fetchData()
    toolbar.registerHandler('deleteTransaction', () => {
      if (tgApp.initData) {
        tgApp.showConfirm(deleteAlertMessage.value, async (confirmed: boolean) => {
          if (confirmed) {
            await deleteTransaction()
          }
        })
      } else {
        isDeleteAlertVisible.value = true
      }
    })
    toolbar.registerHandler('updateTransaction', async () => {
      if (spaceStore.selectedSpaceId) {
        // await categoriesStore.fetchCategories(spaceStore.selectedSpaceId)
        try {
          let updateDTO = buildUpdate()
          await transactionService.updateTransaction(spaceStore.selectedSpaceId, Number(transactionId.value), updateDTO)
          console.log(updateDTO)
          console.log(openMode)
          if (openMode && openMode === "from_bot") {
            tgApp.close()
          } else await moveUser()
        } catch (e) {
          toast.add({
            severity: "error",
            summary: "Error while updating transaction",
            detail: e,
            life: 3000,
          })
        }
      }
    })
  } else {
    toolbar.registerHandler('createTransaction', async () => {
      if (spaceStore.selectedSpaceId) {
        // await categoriesStore.fetchCategories(spaceStore.selectedSpaceId)
        try {
          let createDTO = buildCreate()
          await transactionService.createTransaction(spaceStore.selectedSpaceId, createDTO)
          console.log(openMode)
          if (openMode && openMode === "from_bot") {
            tgApp.close()
          } else await moveUser()
        } catch (e) {
          toast.add({
            severity: "error",
            summary: "Error while creating transaction",
            detail: e,
            life: 3000
          })
        }
      }

    })
  }
})


</script>

<template>

  <div class="flex ">
     <span v-if="categories.length == 0" class="card">Looks like you have no created categories yet. <router-link
         to="/categories/create" class="!text-blue-400">Try to create some first.</router-link></span>

    <div v-else class="flex flex-col w-full justify-items-start gap-1 pb-4">
      <ConfirmDialog
          v-if="isDeleteAlertVisible"
          :message="deleteAlertMessage"
          :callback="(confirmed) => { if (confirmed) deleteTransaction(); isDeleteAlertVisible = false; }"
      />
      <!-- Fixed modal container -->
      <div v-if="isCategorySelectorOpened"
           class="absolute inset-0 top-0 z-[1000] flex items-start justify-center p-4 overflow-y-auto "
           style="background-color: var(--primary-color); padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom);"

           :style="tgApp ? `padding-top: ${insetTop}px !important` : 'padding-top: 2rem !important'">
        <div class="flex flex-col w-full max-w-md !h-dvh !pb-20">
          <div class="card w-full">
            <input class=" p-2 rounded-xl border border-gray-100  w-full" placeholder="Search categories"
                   v-model="categorySearchQuery">
          </div>
          <div v-if="incomeCategories.length > 0" class="flex flex-col w-full">
            <span>Income categories</span>
            <div class="flex card justify-items-start justify-start h-fit">
              <div v-for="(cat, idx) in incomeCategories" :key="cat.id"
                   @click="transactionCategory = cat; transactionType = cat.type == 'EXPENSE' ? TransactionType.EXPENSE : TransactionType.INCOME; isCategorySelectorOpened = false"
                   class="flex flex-col w-full gap-0 pl-5 items-start justify-items-center font-bold cursor-pointer hover:bg-gray-50 transition-colors">
                <div class="flex flex-row w-full items-center justify-between py-3">
                  <div class="flex flex-row items-center gap-2">
                    <span class="text-3xl">{{ cat.icon }} </span>
                    <div class="flex flex-col justify-between">
                      <div class="flex flex-row"> {{ cat.name }}</div>
                      <div class="flex flex-row text-sm text-gray-600">{{ cat.description }}</div>
                    </div>
                  </div>
                  <i class="pi pi-angle-right !font-extralight"/>
                </div>
                <Divider v-if="idx + 1 !== incomeCategories.length" class="!m-0"/>
              </div>
            </div>
          </div>
          <div v-if="expenseCategories.length>0" class="flex flex-col w-full">
            <span>Expense categories</span>
            <div class="flex card justify-items-start justify-start h-fit">
              <div v-for="(cat, idx) in expenseCategories" :key="cat.id"
                   @click="transactionCategory = cat; transactionType = cat.type == 'EXPENSE' ? TransactionType.EXPENSE : TransactionType.INCOME; isCategorySelectorOpened = false"
                   class="flex flex-col w-full gap-0 pl-5 items-start justify-items-center font-bold cursor-pointer hover:bg-gray-50 transition-colors">
                <div class="flex flex-row w-full items-center justify-between py-3">
                  <div class="flex flex-row items-center gap-2">
                    <span class="text-3xl">{{ cat.icon }} </span>
                    <div class="flex flex-col justify-between">
                      <div class="flex flex-row"> {{ cat.name }}</div>
                      <div class="flex flex-row text-sm text-gray-600">{{ cat.description }}</div>
                    </div>
                  </div>
                  <i class="pi pi-angle-right !font-extralight"/>
                </div>
                <Divider v-if="idx + 1 !== expenseCategories.length" class="!m-0"/>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="flex flex-col w-full  ">
        <div class="flex flex-col w-full">
          <InputNumber
              v-model="transactionAmount"
              @input=" isAmountError = false"

              type="text"
              inputmode="numeric"
              placeholder="Amount"
              suffix="₽"
              class="text-7xl font-bold w-full text-center focus:outline-none !p-0 !m-0"

          />
          <span v-if="isAmountError" class="text-sm !text-red-500 font-extralight">Amount couldn't be less then 1</span>
          <!--          <span class="absolute right-2 top-1/2 -translate-y-1/2 text-7xl font-bold">₽</span>-->

          <label class="!justify-items-center !justify-center !font-extralight text-gray-600 text-center">Amount</label>
        </div>
      </div>
      <div class="flex lg:flex-row flex-col w-full justify-between gap-4 ">
        <!--        <div class="card flex flex-col w-full items-center justify-center">-->
        <!--          <span class="text-lg hidden lg:flex">Тип транзакции</span>-->
        <!--          <SelectButton v-model="transactionType" :options="optionsType" optionLabel="label"-->
        <!--                        optionValue="value"-->
        <!--                        class="!w-full  !items-center !justify-center !border-none "/>-->
        <!--        </div>-->
        <!--        <div class="card flex flex-col w-full items-center justify-center">-->

        <!--          <span class="text-lg hidden lg:flex">Вид транзакции</span>-->
        <!--          <SelectButton v-model="transactionKind" :options="optionsKind" optionLabel="label"-->
        <!--                        optionValue="value"-->
        <!--                        class="!w-full  !items-center !justify-center !border-none "/>-->
        <!--        </div>-->
      </div>
      <div class="flex flex-row w-full justify-between gap-4 ">
        <div class="flex flex-col w-full justify-items-start">
          <label class="!font-semibold  text-gray-600 pl-2">Transaction comment</label>
          <div class="flex card !justify-start !items-start !p-[1.11rem] !pl-5 ">
            <input class="font-extralight  w-full focus:outline-0" placeholder="Comment"
                   @input="transactionComment?.length ==0 ? isCommentError = true : isCommentError=false"
                   v-model="transactionComment"/>
          </div>
          <span v-if="isCommentError" class="text-sm !text-red-500 font-extralight">Comment couldn't be empty.</span>

        </div>
        <div class="flex flex-col w-full justify-items-start">
          <label class="!font-semibold  text-gray-600 pl-2">Transaction category</label>
          <div class="flex card !justify-start !items-start !p-3 !pl-5 cursor-pointer"
               @click="isCategorySelectorOpened = true; isCategoryError=false;">
            <div class="flex flex-row w-full gap-2 items-center justify-between">
              <div v-if="transactionCategory" class="flex flex-row gap-2 items-center">
                <span class="!text-3xl ">{{ transactionCategory.icon }}</span>
                <div class="flex flex-col ">
              <span class=" !">{{ transactionCategory.name }}
              </span>
                </div>
              </div>
              <div v-else class="flex flex-row gap-2 items-center">
                <i class="pi pi-question !text-3xl "></i>
                <div class="flex flex-col ">
              <span class=" !">Категория не определена
              </span>
                </div>
              </div>
              <i class="pi pi-angle-right  !font-extralight"/>
            </div>
          </div>
          <span v-if="isCategoryError" class="text-sm text-red-500 font-extralight">Category should be selected</span>
        </div>
      </div>
      <div class="flex !flex-col w-full justify-items-start">
        <label class="!font-semibold text-gray-600 !pl-2">Transaction date</label>
        <div class="card flex justify-center">
          <DatePicker inline v-model="transactionDate" class="w-auto !border-0"/>
        </div>

        <span v-if="isDateError" class="text-sm text-red-500 font-extralight">
    Date couldn't be empty or less than 1 and greater than 31.
  </span>
      </div>

    </div>
  </div>
</template>

<style scoped>
:deep(.p-datepicker-panel) {
  width: 100% !important;
  border: none;
}
</style>