<script setup lang="ts">
import { useSpaceStore } from "@/stores/spaceStore";
import { onMounted, ref, watch } from "vue";
import { Checkbox, Divider, IconField, InputIcon, InputText, Drawer, DatePicker, Button } from "primevue";
import { useToast } from "primevue/usetoast";
import { Transaction, UpdateTransactionDTO } from "@/models/transaction";
import { TransactionFilters, TransactionService } from "@/services/transactions-service";
import { formatAmount, formatDate, toDateOnly } from "@/utils/utils";
import { useRouter } from "vue-router";
import { TransactionKind } from "@/models/enums";
import { useToolbarStore } from "@/stores/toolbar-store";
import { Category } from "@/models/category";
import { categoriesService } from "@/services/categories-service";


const toast = useToast();
const router = useRouter();
const spaceStore = useSpaceStore()
const toolbar = useToolbarStore()
const transactionService = TransactionService

const searchQuery = ref<string>("")
let debounceTimer: ReturnType<typeof setTimeout> | null = null

const isFilterSheetVisible = ref(false)
const filterDateFrom = ref<Date | null>(null)
const filterDateTo = ref<Date | null>(null)
const availableCategories = ref<Category[]>([])
const selectedCategoryIds = ref<number[]>([])

const fetchCategories = async () => {
  if (spaceStore.selectedSpaceId) {
    availableCategories.value = await categoriesService.fetchCategories(spaceStore.selectedSpaceId)
  }
}

const toggleCategorySelection = (categoryId: number) => {
  const index = selectedCategoryIds.value.indexOf(categoryId)
  if (index === -1) {
    selectedCategoryIds.value.push(categoryId)
  } else {
    selectedCategoryIds.value.splice(index, 1)
  }
}

const applyFilters = () => {
  plannedOffset.value = 0
  instantOffset.value = 0
  fetchData(true, true, true)
  isFilterSheetVisible.value = false
}

const resetFilters = () => {
  filterDateFrom.value = null
  filterDateTo.value = null
  selectedCategoryIds.value = []
  applyFilters()
}

watch(searchQuery, () => {
  if (debounceTimer) clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    plannedOffset.value = 0
    instantOffset.value = 0
    fetchData(true, true, true)
  }, 500) // 500ms debounce
})

const showIsDone = ref(false)

const setTransactionDone = async (transaction: Transaction): Promise<void> => {
  const updateTransaction = {
    type: transaction.type,
    kind: transaction.kind,
    categoryId: transaction.category.id,
    comment: transaction.comment,
    amount: transaction.amount,
    fees: 0,
    isDone: transaction.isDone,
    date: new Date(transaction.date),
  } as UpdateTransactionDTO
  try {
    await transactionService.updateTransaction(spaceStore.selectedSpaceId as number, transaction.id, updateTransaction)
  } catch (error) {
    toast.add({
      severity: 'error',
      summary: 'Failed to update transactions.',
      detail: String(error),
      life: 3000,
    })
  }
}

const plannedTransactions = ref<Transaction[]>([])
const plannedOffset = ref(0)
const plannedLimit = ref(10)
const plannedLastBatch = ref(false)

const instantTransactions = ref<Transaction[]>([])
const instantOffset = ref(0)
const instantLimit = ref(10)
const instantLastBatch = ref(false)

const fetchMorePlanned = async () => {
  plannedOffset.value += plannedLimit.value
  await fetchData(true, false)
}

const fetchMoreInstant = async () => {
  instantOffset.value += instantLimit.value
  await fetchData(false, true)
}

const fetchData = async (fetchPlanned: boolean = true, fetchInstant: boolean = true, replace: boolean = false) => {
  if (!spaceStore.selectedSpaceId) return

  try {
    // Готовим промисы
    const plannedPromise: Promise<Transaction[]> =
      fetchPlanned
        ? transactionService.getTransactions(spaceStore.selectedSpaceId, {
          kind: TransactionKind.PLANNING,
          isDone: showIsDone.value ? undefined : false,
          offset: plannedOffset.value,
          limit: plannedLimit.value,
          query: searchQuery.value || null,
          categoriesIds: selectedCategoryIds.value.length > 0 ? selectedCategoryIds.value : null,
          dateFrom: filterDateFrom.value ? toDateOnly(filterDateFrom.value) : null,
          dateTo: filterDateTo.value ? toDateOnly(filterDateTo.value) : null,
          sorts: [{ "sortBy": "date", "sortDirection": "ASC" }]
        } as TransactionFilters) // никаких `as TransactionFilters`, если поля опциональные
        : Promise.resolve(plannedTransactions.value)

    const instantPromise: Promise<Transaction[]> =
      fetchInstant
        ? transactionService.getTransactions(spaceStore.selectedSpaceId, {
          kind: TransactionKind.INSTANT,
          offset: instantOffset.value,
          limit: instantLimit.value,
          query: searchQuery.value || null,
          categoriesIds: selectedCategoryIds.value.length > 0 ? selectedCategoryIds.value : null,
          dateFrom: filterDateFrom.value ? toDateOnly(filterDateFrom.value) : null,
          dateTo: filterDateTo.value ? toDateOnly(filterDateTo.value) : null,
        } as TransactionFilters)
        : Promise.resolve(instantTransactions.value)

    const [planned, instant] = await Promise.all([plannedPromise, instantPromise])

    if (replace) {

      // Если хочешь просто перезаписывать
      plannedTransactions.value = planned
      instantTransactions.value = instant
    } else {
      // Если хочешь "подгружать ещё" (пагинация, load more):
      if (fetchPlanned) {
        plannedTransactions.value = [...plannedTransactions.value, ...planned]
        if (planned.length < plannedLimit.value) plannedLastBatch.value = true
      }
      if (fetchInstant) {
        instantTransactions.value = [...instantTransactions.value, ...instant]
        if (instant.length < instantLimit.value) instantLastBatch.value = true
      }
    }
  } catch (e) {
    toast.add({
      severity: 'error',
      summary: 'Failed to load transactions.',
      detail: String(e),
      life: 3000,
    })
  }
}


onMounted(async () => {
  await fetchCategories()
  await fetchData()
  toolbar.registerHandler('openTransactionCreation', () => {
    router.push('/transactions/create')
  })
})
</script>

<template>

  <div v-if="!spaceStore.selectedSpaceId" class="card">
    Try to select a space first.
  </div>
  <div v-else class="flex flex-col gap-6 pb-10">
    <div class="flex flex-col gap-2">
      <div class="card !w-full flex !flex-row gap-2">
        <IconField iconPosition="left" class="!w-full !bg-white">
          <InputIcon class="pi pi-search"> </InputIcon>
          <InputText v-model="searchQuery" placeholder="Search" class="!w-full !bg-white !text-left" />
        </IconField>
        <Button icon="pi pi-filter" @click="isFilterSheetVisible = true" text rounded aria-label="Filter" />
      </div>
      <div class="flex flex-row justify-between">
        <span class="text-xl !font-semibold !pl-2">Planned transactions</span>
        <div class="flex flex-row gap-2 items-center">
          <Checkbox v-model="showIsDone" binary value=" Показывать выполненные"
            @change="plannedOffset = 0; fetchData(true, false, true)" />
          <span class="text-sm">Выполненные</span>
        </div>
      </div>
      <div class="flex card">
        <span v-if="plannedTransactions.length == 0">Looks like you haven't plan any transactions yet. <router-link
            to="/transactions/create" class="!text-blue-400">Try to create some.</router-link></span>
        <div v-else v-for="key in plannedTransactions.keys()" :key="plannedTransactions[key].id"
          class="flex flex-col  w-full gap-0 pl-5  items-start justify-items-center font-bold ">
          <div class="flex flex-row  w-full items-center gap-4">
            <Checkbox v-model="plannedTransactions[key].isDone" binary class="text-3xl"
              @change="setTransactionDone(plannedTransactions[key])">
              {{ plannedTransactions[key].category.icon }}
            </Checkbox>
            <div class="flex !flex-row !justify-between !w-full"
              @click="router.push(`/transactions/${plannedTransactions[key].id}/edit`)">
              <div class="flex flex-row items-center gap-2">
                <div class="flex flex-col !font-bold "> {{ plannedTransactions[key].comment }}
                  <div class="flex flex-row text-sm">{{ plannedTransactions[key].category.icon }}
                    {{ plannedTransactions[key].category.name }}
                  </div>
                </div>
              </div>
              <div class="flex flex-row gap-2 items-center !w-fit">
                <div class="flex flex-col justify-between items-end !w-fit whitespace-nowrap shrink-0">
                  <span class="text-lg !font-bold">{{ formatAmount(plannedTransactions[key].amount) }} ₽</span>
                  <span class="text-sm !font-extralight"> {{ formatDate(plannedTransactions[key].date) }}</span>
                </div>
                <i class="pi pi-angle-right !font-extralight" />
              </div>
            </div>
          </div>
          <Divider v-if="key + 1 !== plannedTransactions.length" class="!m-0 !py-3" />
        </div>
      </div>
      <button v-if="!plannedLastBatch" class="card w-fit " @click="fetchMorePlanned">Load more...</button>
    </div>

    <!-- Filter Sheet -->
    <Drawer v-model:visible="isFilterSheetVisible" position="bottom" style="height: auto" :modal="true"
      :dismissable="true" :showCloseIcon="false">
      <div class="flex flex-col gap-4 pb-6">
        <div class="flex justify-between items-center px-4 pt-2">
          <span class="text-xl font-bold">Filter Transactions</span>
          <Button icon="pi pi-times" text rounded @click="isFilterSheetVisible = false" />
        </div>

        <div class="flex flex-col px-4 gap-2">
          <span class="font-semibold text-gray-600">Period</span>
          <div class="flex flex-row gap-2 w-full">
            <div class="flex flex-col w-1/2">
              <label class="text-sm text-gray-500 mb-1">From</label>
              <DatePicker v-model="filterDateFrom" showIcon fluid :maxDate="filterDateTo || undefined" />
            </div>
            <div class="flex flex-col w-1/2">
              <label class="text-sm text-gray-500 mb-1">To</label>
              <DatePicker v-model="filterDateTo" showIcon fluid :minDate="filterDateFrom || undefined" />
            </div>
          </div>
        </div>

        <div class="flex flex-col px-4 gap-2">
          <span class="font-semibold text-gray-600">Categories</span>
          <div class="flex flex-wrap gap-2">
            <div v-for="cat in availableCategories" :key="cat.id" @click="toggleCategorySelection(cat.id)"
              :class="['px-3 py-2 rounded-full border cursor-pointer transition-colors flex items-center gap-2',
                selectedCategoryIds.includes(cat.id) ? 'bg-blue-100 border-blue-500 text-blue-700' : 'bg-white border-gray-200 hover:bg-gray-50']">
              <span>{{ cat.icon }}</span>
              <span class="text-sm">{{ cat.name }}</span>
            </div>
          </div>
        </div>

        <div class="flex flex-row gap-3 px-4 pt-4">
          <Button label="Reset" severity="secondary" @click="resetFilters" class="w-1/3" outlined />
          <Button label="Apply Filters" @click="applyFilters" class="w-2/3" />
        </div>
      </div>
    </Drawer>
    <div class="flex flex-col gap-2">
      <span class="text-xl !font-semibold !pl-2">Instant transactions</span>
      <div class="flex card">
        <span v-if="instantTransactions.length == 0">Looks like you haven't record any transaction yet.<router-link
            to="/transactions/create" class="!text-blue-400">Try to create some.</router-link></span>
        <div v-else v-for="key in instantTransactions.keys()" :key="instantTransactions[key].id"
          @click="router.push(`/transactions/${instantTransactions[key].id}/edit`)"
          class="flex flex-col  w-full gap-0 pl-5  items-start justify-items-center font-bold ">
          <div class="flex flex-row  w-full items-center justify-between">
            <div class="flex flex-row items-center gap-2 ">
              <span v-if="instantTransactions[key].category" class="text-3xl"> {{
                instantTransactions[key].category.icon
              }}</span>
              <i v-else class="pi pi-question !text-3xl" />
              <div class="flex flex-col !font-bold "> {{ instantTransactions[key].comment }}
                <div v-if="instantTransactions[key].category" class="flex flex-row text-sm">
                  {{ instantTransactions[key].category.name }}
                </div>
              </div>
            </div>
            <div class="flex flex-row gap-2 items-center">
              <div class="flex flex-col justify-between items-end !w-fit whitespace-nowrap shrink-0">
                <span class="text-lg !font-bold ">{{ formatAmount(instantTransactions[key].amount) }} ₽</span>
                <span class="text-sm !font-extralight"> {{ formatDate(instantTransactions[key].date) }}</span>
              </div>
              <i class="pi pi-angle-right !font-extralight" />
            </div>
          </div>
          <Divider v-if="key + 1 !== instantTransactions.length" class="!m-0 !py-3" />
        </div>
      </div>
      <button v-if="!instantLastBatch" class="card w-fit " @click="fetchMoreInstant">Load more...</button>

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


<style scoped></style>