<script setup lang="ts">
import dayjs from "dayjs"
import customParseFormat from "dayjs/plugin/customParseFormat"
import {
  formatTaxEvaluationPeriodLabel,
  formatTaxEvaluationPeriodRange,
  getCreatedDocumentTaxBreakdown,
  getIncomingInvoiceTaxBreakdown,
  getTaxEvaluationPeriodBounds,
  normalizeTaxEvaluationPeriod,
  shiftTaxEvaluationPeriodStart
} from "~/composables/useTaxEvaluation"

dayjs.extend(customParseFormat)

const auth = useAuthStore()

const loading = ref(true)
const createdDocuments = ref<any[]>([])
const incomingInvoices = ref<any[]>([])

const periodType = computed(() => normalizeTaxEvaluationPeriod(auth.activeTenantData?.taxEvaluationPeriod))

const formatCurrency = (value: number) => {
  return new Intl.NumberFormat("de-DE", {
    style: "currency",
    currency: "EUR"
  }).format(Number(value || 0))
}

const isRelevantOutputDocument = (doc: any) => {
  return doc?.state === "Gebucht" && ["invoices", "advanceInvoices", "cancellationInvoices"].includes(doc?.type)
}

const isRelevantInputInvoice = (invoice: any) => {
  return invoice?.state === "Gebucht" && !!invoice?.date
}

const loadData = async () => {
  loading.value = true

  try {
    const [docs, incoming] = await Promise.all([
      useEntities("createddocuments").select(),
      useEntities("incominginvoices").select()
    ])

    createdDocuments.value = (docs || []).filter(isRelevantOutputDocument)
    incomingInvoices.value = (incoming || []).filter(isRelevantInputInvoice)
  } finally {
    loading.value = false
  }
}

const periods = computed(() => {
  const currentBounds = getTaxEvaluationPeriodBounds(dayjs(), periodType.value)

  return Array.from({ length: 8 }, (_, index) => {
    const start = shiftTaxEvaluationPeriodStart(currentBounds.start, periodType.value, -index)
    const bounds = getTaxEvaluationPeriodBounds(start, periodType.value)

    const outputDocs = createdDocuments.value.filter((doc) => {
      const date = dayjs(doc.documentDate)
      return date.isValid() && !date.isBefore(bounds.start, "day") && !date.isAfter(bounds.end, "day")
    })

    const inputDocs = incomingInvoices.value.filter((invoice) => {
      const date = dayjs(invoice.date)
      return date.isValid() && !date.isBefore(bounds.start, "day") && !date.isAfter(bounds.end, "day")
    })

    const output = outputDocs.reduce((sum, doc) => {
      const breakdown = getCreatedDocumentTaxBreakdown(doc)
      return {
        net19: sum.net19 + breakdown.net19,
        tax19: sum.tax19 + breakdown.tax19,
        net7: sum.net7 + breakdown.net7,
        tax7: sum.tax7 + breakdown.tax7,
        net0: sum.net0 + breakdown.net0,
      }
    }, { net19: 0, tax19: 0, net7: 0, tax7: 0, net0: 0 })

    const input = inputDocs.reduce((sum, invoice) => {
      const breakdown = getIncomingInvoiceTaxBreakdown(invoice)
      return {
        net19: sum.net19 + breakdown.net19,
        tax19: sum.tax19 + breakdown.tax19,
        net7: sum.net7 + breakdown.net7,
        tax7: sum.tax7 + breakdown.tax7,
        net0: sum.net0 + breakdown.net0,
      }
    }, { net19: 0, tax19: 0, net7: 0, tax7: 0, net0: 0 })

    const outputTax = Number((output.tax19 + output.tax7).toFixed(2))
    const inputTax = Number((input.tax19 + input.tax7).toFixed(2))
    const balance = Number((outputTax - inputTax).toFixed(2))

    return {
      key: bounds.start.format("YYYY-MM-DD"),
      label: formatTaxEvaluationPeriodLabel(bounds.start, periodType.value),
      range: formatTaxEvaluationPeriodRange(bounds.start, periodType.value),
      isCurrent: index === 0,
      outputTax,
      inputTax,
      balance,
      output,
      input,
      outputCount: outputDocs.length,
      inputCount: inputDocs.length,
    }
  })
})

const currentPeriod = computed(() => periods.value[0] || null)

const columns = [
  { key: "label", label: "Zeitraum" },
  { key: "range", label: "Datumsbereich" },
  { key: "outputTax", label: "USt Rechnungen" },
  { key: "inputTax", label: "Vorsteuer" },
  { key: "balance", label: "Ergebnis" },
  { key: "documents", label: "Belege" },
]

onMounted(loadData)
</script>

<template>
  <div>
    <UDashboardNavbar title="USt-Auswertung">
      <template #right>
        <UButton
            icon="i-heroicons-arrow-path"
            variant="outline"
            @click="loadData"
            :loading="loading"
        >
          Aktualisieren
        </UButton>
      </template>
    </UDashboardNavbar>

    <UDashboardPanelContent class="p-4 md:p-6">
      <div class="mb-6 flex flex-col gap-2">
        <h2 class="text-lg font-semibold text-gray-900 dark:text-white">
          Aktueller Zeitraum: {{ currentPeriod?.label }}
        </h2>
        <p class="text-sm text-gray-500 dark:text-gray-400">
          Intervall: {{ periodType === "monthly" ? "monatlich" : periodType === "quarterly" ? "quartalsweise" : "jährlich" }}.
          Berücksichtigt werden gebuchte Ausgangsrechnungen, Abschlags- und Stornorechnungen sowie gebuchte Eingangsbelege mit Datum.
        </p>
        <p v-if="currentPeriod" class="text-sm text-gray-500 dark:text-gray-400">
          {{ currentPeriod.range }}
        </p>
      </div>

      <div v-if="currentPeriod" class="grid gap-4 md:grid-cols-3">
        <UCard>
          <div class="text-sm text-gray-500 dark:text-gray-400">Berechnete USt</div>
          <div class="mt-2 text-2xl font-semibold text-gray-900 dark:text-white">
            {{ formatCurrency(currentPeriod.outputTax) }}
          </div>
          <div class="mt-3 text-sm text-gray-500 dark:text-gray-400">
            19%: {{ formatCurrency(currentPeriod.output.tax19) }} | 7%: {{ formatCurrency(currentPeriod.output.tax7) }}
          </div>
        </UCard>

        <UCard>
          <div class="text-sm text-gray-500 dark:text-gray-400">Vorsteuer</div>
          <div class="mt-2 text-2xl font-semibold text-gray-900 dark:text-white">
            {{ formatCurrency(currentPeriod.inputTax) }}
          </div>
          <div class="mt-3 text-sm text-gray-500 dark:text-gray-400">
            19%: {{ formatCurrency(currentPeriod.input.tax19) }} | 7%: {{ formatCurrency(currentPeriod.input.tax7) }}
          </div>
        </UCard>

        <UCard>
          <div class="text-sm text-gray-500 dark:text-gray-400">Verrechnetes Ergebnis</div>
          <div
              class="mt-2 text-2xl font-semibold"
              :class="currentPeriod.balance >= 0 ? 'text-amber-600 dark:text-amber-400' : 'text-emerald-600 dark:text-emerald-400'"
          >
            {{ formatCurrency(currentPeriod.balance) }}
          </div>
          <div class="mt-3 text-sm text-gray-500 dark:text-gray-400">
            {{ currentPeriod.outputCount }} Ausgangsbelege | {{ currentPeriod.inputCount }} Eingangsbelege
          </div>
        </UCard>
      </div>

      <div v-if="currentPeriod" class="mt-6 grid gap-4 xl:grid-cols-2">
        <UCard>
          <template #header>
            <div class="font-semibold">Ausgangsrechnungen</div>
          </template>
          <div class="space-y-3 text-sm">
            <div class="flex items-center justify-between">
              <span>Netto 19%</span>
              <span>{{ formatCurrency(currentPeriod.output.net19) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>USt 19%</span>
              <span>{{ formatCurrency(currentPeriod.output.tax19) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>Netto 7%</span>
              <span>{{ formatCurrency(currentPeriod.output.net7) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>USt 7%</span>
              <span>{{ formatCurrency(currentPeriod.output.tax7) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>Netto 0%</span>
              <span>{{ formatCurrency(currentPeriod.output.net0) }}</span>
            </div>
          </div>
        </UCard>

        <UCard>
          <template #header>
            <div class="font-semibold">Eingangsbelege</div>
          </template>
          <div class="space-y-3 text-sm">
            <div class="flex items-center justify-between">
              <span>Netto 19%</span>
              <span>{{ formatCurrency(currentPeriod.input.net19) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>Vorsteuer 19%</span>
              <span>{{ formatCurrency(currentPeriod.input.tax19) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>Netto 7%</span>
              <span>{{ formatCurrency(currentPeriod.input.net7) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>Vorsteuer 7%</span>
              <span>{{ formatCurrency(currentPeriod.input.tax7) }}</span>
            </div>
            <div class="flex items-center justify-between">
              <span>Netto 0%</span>
              <span>{{ formatCurrency(currentPeriod.input.net0) }}</span>
            </div>
          </div>
        </UCard>
      </div>

      <UCard class="mt-6">
        <template #header>
          <div class="font-semibold">Aktueller und vorherige Zeiträume</div>
        </template>

        <UTable
            :columns="columns"
            :rows="periods"
            :loading="loading"
            :empty-state="{ icon: 'i-heroicons-calculator', label: 'Keine Daten für die USt-Auswertung vorhanden' }"
        >
          <template #label-data="{ row }">
            <div class="flex items-center gap-2">
              <span>{{ row.label }}</span>
              <UBadge v-if="row.isCurrent" color="primary" variant="soft">Aktuell</UBadge>
            </div>
          </template>

          <template #outputTax-data="{ row }">
            {{ formatCurrency(row.outputTax) }}
          </template>

          <template #inputTax-data="{ row }">
            {{ formatCurrency(row.inputTax) }}
          </template>

          <template #balance-data="{ row }">
            <span :class="row.balance >= 0 ? 'text-amber-600 dark:text-amber-400 font-medium' : 'text-emerald-600 dark:text-emerald-400 font-medium'">
              {{ formatCurrency(row.balance) }}
            </span>
          </template>

          <template #documents-data="{ row }">
            {{ row.outputCount }} / {{ row.inputCount }}
          </template>
        </UTable>
      </UCard>
    </UDashboardPanelContent>
  </div>
</template>
