<script setup lang="ts">
import Drawer from "primevue/drawer";
import InputText from "primevue/inputtext";
import DatePicker from "primevue/datepicker";
import FloatLabel from "primevue/floatlabel";
import InputNumber from "primevue/inputnumber";
import Button from "primevue/button";
import {ref, onMounted, computed} from 'vue';
import {Transaction, TransactionType} from "@/models/Transaction";
import {CategoryType} from "@/models/Category";
import SelectButton from "primevue/selectbutton";
import Select from "primevue/select";
import {
  createTransactionRequest,
  getTransactionTypes,
  updateTransactionRequest,
  deleteTransactionRequest
} from "@/services/transactionService";
import {getCategories, getCategoryTypes} from "@/services/categoryService";
import {useToast} from "primevue/usetoast";
import LoadingView from "@/components/LoadingView.vue";

const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
  },
  transaction: {
    type: Object as () => Transaction,
    required: false
  },
  transactionType: {
    type: String,
    required: false
  },
  categoryType: {
    type: String,
    required: false
  }
});

const emit = defineEmits(['create-transaction', 'update-transaction', 'delete-transaction', 'close-drawer']);
const toast = useToast();
const categoryTypeChanged = () => {
  console.log(selectedCategoryType.value)
  editedTransaction.value.category = selectedCategoryType.value.code == "EXPENSE" ? expenseCategories.value[0] : incomeCategories.value[0];

}
const selectCategory = (category) => {
  isCategorySelectorOpened.value = false;
  editedTransaction.value.category = category;
};


// Состояние
const loading = ref(false);
const isEditing = ref(!!props.transaction);
const isCategorySelectorOpened = ref(false);
const editedTransaction = ref<Transaction | null>(null);

const selectedCategoryType = ref<CategoryType | null>(null);
const selectedTransactionType = ref<TransactionType | null>(null);

const entireCategories = ref<Category[]>([]);
const expenseCategories = ref<Category[]>([]);
const incomeCategories = ref<Category[]>([]);
const categoryTypes = ref<CategoryType[]>([]);
const transactionTypes = ref<TransactionType[]>([]);

// Получение категорий и типов транзакций
const fetchCategoriesAndTypes = async () => {
  try {
    const [categoriesResponse, categoryTypesResponse, transactionTypesResponse] = await Promise.all([
      getCategories(),
      getCategoryTypes(),
      getTransactionTypes()
    ]);
    entireCategories.value = categoriesResponse.data;
    expenseCategories.value = categoriesResponse.data.filter((category: Category) => category.type.code === 'EXPENSE');
    incomeCategories.value = categoriesResponse.data.filter((category: Category) => category.type.code === 'INCOME');

    categoryTypes.value = categoryTypesResponse.data;
    transactionTypes.value = transactionTypesResponse.data;
  } catch (error) {
    console.error('Error fetching categories and types:', error);
  }
};

// Инициализация данных
const prepareData = () => {
  if (!props.transaction) {
    editedTransaction.value = new Transaction();
    editedTransaction.value.transactionType = transactionTypes.value.find(type => type.code === props.transactionType) || transactionTypes.value[0];
    selectedCategoryType.value = categoryTypes.value.find(type => type.code === props.categoryType) || categoryTypes.value[0];
    editedTransaction.value.category = props.categoryType === 'EXPENSE' ? expenseCategories.value[0] : incomeCategories.value[0];
    editedTransaction.value.date = new Date();
  } else {
    editedTransaction.value = {...props.transaction};
    selectedCategoryType.value = editedTransaction.value.category.type;
    selectedTransactionType.value = editedTransaction.value.transactionType;
  }

};

// Создание транзакции
const createTransaction = async () => {
  try {
    loading.value = true;
    if (editedTransaction.value.transactionType.code === 'INSTANT') {
      editedTransaction.value.isDone = true;
    }
    await createTransactionRequest(editedTransaction.value);
    toast.add({severity: 'success', summary: 'Transaction created!', detail: 'Транзакция создана!', life: 3000});
    emit('create-transaction', editedTransaction.value);
    resetForm();
  } catch (error) {
    console.error('Error creating transaction:', error);
  } finally {
    loading.value = false;
    console.log(editedTransaction.value)
  }
};

// Обновление транзакции
const updateTransaction = async () => {
  try {
    loading.value = true;
    const response = await updateTransactionRequest(editedTransaction.value);
    editedTransaction.value = response.data;
    toast.add({severity: 'success', summary: 'Transaction updated!', detail: 'Транзакция обновлена!', life: 3000});
    emit('update-transaction', editedTransaction.value);
  } catch (error) {
    console.error('Error updating transaction:', error);
  } finally {
    loading.value = false;
  }
};

// Удаление транзакции
const deleteTransaction = async () => {
  try {
    loading.value = true;
    await deleteTransactionRequest(editedTransaction.value.id);
    toast.add({severity: 'success', summary: 'Transaction deleted!', detail: 'Транзакция удалена!', life: 3000});
    emit('delete-transaction', editedTransaction.value);
    closeDrawer()
  } catch (error) {
    console.error('Error deleting transaction:', error);
  } finally {
    loading.value = false;
  }
};

// Сброс формы
const resetForm = () => {

  editedTransaction.value.date = new Date();
  editedTransaction.value.amount = null;
  editedTransaction.value.comment = '';

};

const dateErrorMessage = computed(() => {
  console.log('tut')
  if (editedTransaction.value.transactionType.code != 'PLANNED' && editedTransaction.value.date > new Date()) {
    console.log('tut2')
    return 'При мгновенных тратах дата должна быть меньше текущей!'
  } else if (editedTransaction.value.transactionType.code == 'PLANNED' && editedTransaction.value.date < new Date()) {
    console.log('tu3')
    return 'При плановых тратах дата должна быть больше текущей!'
  } else {
    console.log('tu4')
    return ''
  }
})

// Закрытие окна
const closeDrawer = () => emit('close-drawer');

// Мониторинг при монтировании
onMounted(async () => {
  loading.value = true;
  await fetchCategoriesAndTypes();
  prepareData();
  loading.value = false;
});
</script>

<template>

  <div class="card flex justify-center h-dvh">

    <Drawer :visible="visible" :header="isEditing ? 'Edit Transaction' : 'Create Transaction'" :showCloseIcon="false"
            position="right" @hide="closeDrawer"
            class="!w-128  ">
      <LoadingView v-if="loading"/>
      <div v-else class=" grid gap-4 w-full ">

        <div class="relative w-full justify-center justify-items-center ">
          <div class="flex flex-col justify-items-center gap-2">
            <div class="flex flex-row gap-2">
              <!--            {{editedTransaction.value.transactionType}}-->
              <Select v-if="!isEditing" v-model="editedTransaction.transactionType" :allow-empty="false"
                            :options="transactionTypes"
                            optionLabel="name"
                            aria-labelledby="basic"
                            class="justify-center"/>
              <SelectButton v-model="selectedCategoryType" :options="categoryTypes" :allow-empty="false"
                            optionLabel="name"
                            aria-labelledby="basic"
                            @change="categoryTypeChanged" class="justify-center"/>
            </div>
            <button class="border border-gray-300 rounded-lg w-full z-50"
                    @click="isCategorySelectorOpened = !isCategorySelectorOpened">
              <div class="flex flex-row  items-center pe-4 py-2 ">
                <div class="flex flex-row justify-between w-full gap-4 px-4 items-center">
                  <p class="text-3xl font-bold text-gray-700 dark:text-gray-400">{{
                      editedTransaction.category.icon
                    }}</p>
                  <div class="flex flex-col items-start justify-items-start justify-around w-full">
                    <p class="font-bold text-start">{{ editedTransaction.category.name }}</p>
                    <p class="font-light line-clamp-1 items-start text-start">{{
                        editedTransaction.category.description
                      }}</p>
                  </div>
                </div>
                <div>
              <span :class="{'rotate-90': isCategorySelectorOpened}"
                    class="pi pi-angle-right transition-transform duration-300 text-5xl"/>
                </div>
              </div>
            </button>
          </div>

          <!-- Анимированное открытие списка категорий -->
          <div v-show="isCategorySelectorOpened"
               class="absolute left-0 right-0 top-full overflow-hidden z-50 border-b-4 border-x  rounded-b-lg bg-white shadow-lg transition-all duration-500"
               :class="{ 'max-h-0': !isCategorySelectorOpened, 'max-h-[500px]': isCategorySelectorOpened }">
            <div class="grid grid-cols-2  mt-2">
              <button
                  v-for="category in editedTransaction.category.type.code == 'EXPENSE' ? expenseCategories : incomeCategories"
                  :key="category.id" class="border rounded-lg mx-2 mb-2"
                  @click="selectCategory(category)">
                <div class="flex flex-row justify-between w-full px-2">
                  <p class="text-4xl font-bold text-gray-700 dark:text-gray-400">{{ category.icon }}</p>
                  <div class="flex flex-col items-start justify-items-start justify-around w-full">
                    <p class="font-bold text-start">{{ category.name }}</p>
                    <p class="font-light line-clamp-1 text-start">{{ category.description }}</p>
                  </div>
                </div>
              </button>
            </div>
          </div>
        </div>
        <div class="flex flex-row gap-4">


            <FloatLabel variant="on" class="">
              <InputNumber class=""
                           :invalid="!editedTransaction.amount"
                           :minFractionDigits="0"
                           id="amount"
                           v-model="editedTransaction.amount"
                           mode="currency"
                           currency="RUB"
                           locale="ru-RU"

              />
              <label for="amount" class="">Amount</label>
            </FloatLabel>

          <!-- Comment Input -->

            <FloatLabel variant="on" class="w-full">
              <label for="comment">Comment</label>
              <InputText class="w-full"
                         :invalid="!editedTransaction.comment"
                         id="comment"
                         v-model="editedTransaction.comment"

              />
            </FloatLabel>

        </div>

        <!-- Date Picker -->
        <div class="field col-12 gap-0">
          <FloatLabel variant="on">
            <label for="date">Date </label>

            <DatePicker class="w-full"
                        inline
                        :invalid="editedTransaction.transactionType.code != 'PLANNED' ? editedTransaction.date > new Date() : true"
                        id="date"
                        v-model="editedTransaction.date"
                        dateFormat="yy-mm-dd"
                        showIcon

            />
            <p :class="dateErrorMessage != '' ? 'visible' : 'invisible'"
               class="text-red-400">{{ dateErrorMessage }}</p>


          </FloatLabel>
        </div>

        <!-- Amount Input -->


        <!-- Buttons -->
        <div class="fixed  col-12 bottom-6 flex justify-content-end gap-4">

          <Button label="Save" icon="pi pi-check" class="p-button-success"
                  @click="isEditing ? updateTransaction() : createTransaction()"/>
          <Button label="Cancel" icon="pi pi-times" class="p-button-secondary " @click="closeDrawer"/>
          <Button v-if="isEditing" label="Delete" icon="pi pi-times" class="p-button-success" severity="danger"
                  @click="deleteTransaction"/>
        </div>

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

<style scoped>

</style>
