﻿﻿<template>
  <q-page v-if="canReadFinance" class="q-px-md q-pb-md q-pt-xs page-col statement-page">
    <q-slide-transition>
      <div v-show="!filtersCollapsed" class="local-filter-bar compact-filter q-pa-sm q-mb-xs">
        <div class="row q-col-gutter-sm items-end">
        <div class="col-12 col-md-5">
          <q-select
            v-model="selectedCari"
            :options="filteredOptions"
            label="Cari kod / isim"
            filled
            dense
            clearable
            use-input
            input-debounce="300"
            @filter="filterCari"
            emit-value
            map-options
            :loading="accountStore.loading"
            option-value="value"
            option-label="label"
            behavior="menu"
            :keep-selected="true"
          />
        </div>
        <div class="col-12 col-sm-6 col-md-2">
          <q-input v-model="dateTo" label="Son tarih" filled dense clearable readonly>
            <template #append>
              <q-icon name="event" class="cursor-pointer">
                <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                  <q-date v-model="dateTo" mask="YYYY-MM-DD" locale="tr-TR" />
                </q-popup-proxy>
              </q-icon>
            </template>
          </q-input>
        </div>
        <div class="col-12 col-sm-6 col-md-3">
          <q-select
            v-model="selectedMonType"
            :options="monetaryTypeOptions"
            label="Parasal İşlem Tipi"
            emit-value
            map-options
            filled
            dense
          />
        </div>
        <div class="col-auto">
          <q-btn color="primary" icon="filter_alt" label="Filtrele" @click="onFilterClick" />
        </div>
        <div class="col-auto">
          <q-btn flat color="grey-8" icon="restart_alt" label="Sıfırla" @click="resetFilters" />
        </div>
        </div>
      </div>
    </q-slide-transition>

    <div class="table-scroll">
      <div class="sticky-bar row justify-end items-center q-pa-sm bg-grey-1 q-gutter-sm">
        <q-btn
          flat
          color="primary"
          :icon="filtersCollapsed ? 'unfold_more' : 'unfold_less'"
          :label="filtersCollapsed ? 'Filtreleri Genişlet' : 'Filtreleri Daralt'"
          @click="toggleFiltersCollapsed"
        />
        <q-btn
          v-if="canExportFinance"
          flat
          color="red"
          icon="picture_as_pdf"
          label="PDF Yazdır"
          @click="downloadAgingScreenPDF"
        />
        <q-btn
          flat
          color="secondary"
          icon="list"
          :label="allDetailsOpen ? 'Tüm Detayları Kapat' : 'Tüm Detayları Aç'"
          @click="toggleAllDetails"
        />
      </div>

      <q-table
        class="sticky-table statement-table"
        title="Cari Yaşlandırmalı Ekstre"
        :rows="agingStore.masterRows"
        :columns="masterColumns"
        v-model:pagination="masterPagination"
        row-key="group_key"
        flat
        bordered
        dense
        hide-bottom
        wrap-cells
        :rows-per-page-options="[0]"
        :loading="agingStore.loading"
        :table-style="{ tableLayout: 'fixed', width: '100%' }"
      >
        <template #header="props">
          <q-tr :props="props" class="header-row">
            <q-th v-for="col in props.cols" :key="col.name" :props="props">{{ col.label }}</q-th>
          </q-tr>
        </template>

        <template #body="props">
          <q-tr :props="props" class="master-row">
            <q-td v-for="col in props.cols" :key="col.name" :props="props">
              <q-btn
                v-if="col.name === 'expand'"
                dense
                flat
                round
                size="sm"
                :icon="masterExpanded[props.row.group_key] ? 'expand_less' : 'expand_more'"
                @click="toggleMaster(props.row.group_key)"
              />
              <span
                v-else-if="masterNumericCols.includes(col.name)"
                :class="['block', masterCenteredCols.includes(col.name) ? 'text-center' : 'text-right']"
              >
                {{ formatAmount(props.row[col.field]) }}
              </span>
              <span v-else>{{ props.row[col.field] ?? '-' }}</span>
            </q-td>
          </q-tr>

          <q-tr v-if="masterExpanded[props.row.group_key]" class="master-sub-row">
            <q-td colspan="100%" class="q-pa-none">
              <div class="currency-groups">
                <div class="currency-level-head">
                  <div class="cgh-cell cgh-expand"></div>
                  <div class="cgh-cell cgh-code">Döviz</div>
                  <div class="cgh-cell cgh-num">Satır</div>
                  <div class="cgh-cell cgh-num">Toplam Tutar</div>
                  <div class="cgh-cell cgh-num">Toplam USD</div>
                  <div class="cgh-cell cgh-num">Normal</div>
                  <div class="cgh-cell cgh-num">Açık Kalem</div>
                  <div class="cgh-cell cgh-num">Kur</div>
                  <div class="cgh-cell cgh-center">Ort. Gün</div>
                  <div class="cgh-cell cgh-center">Ort. Gün (DocDate)</div>
                </div>
                <div
                  v-for="currRow in agingStore.getCurrenciesByMaster(props.row.group_key)"
                  :key="currRow.group_key"
                  class="currency-group"
                >
                  <div class="currency-group-header">
                    <div class="cgh-cell cgh-expand">
                      <q-btn
                        dense
                        flat
                        round
                        size="sm"
                        :icon="currencyExpanded[currRow.group_key] ? 'expand_less' : 'expand_more'"
                        @click="toggleCurrency(currRow.group_key)"
                      />
                    </div>
                    <div class="cgh-cell cgh-code">{{ currRow.doc_currency_code }}</div>
                    <div class="cgh-cell cgh-num">{{ formatAmount(currRow.satir_sayisi, 0) }}</div>
                    <div class="cgh-cell cgh-num">{{ formatAmount(currRow.toplam_tutar) }}</div>
                    <div class="cgh-cell cgh-num">{{ formatAmount(currRow.toplam_usd) }}</div>
                    <div class="cgh-cell cgh-num">{{ formatAmount(currRow.normal_tutar) }}</div>
                    <div class="cgh-cell cgh-num">{{ formatAmount(currRow.acik_kalem_tutar) }}</div>
                    <div class="cgh-cell cgh-num">{{ formatAmount(currRow.kur) }}</div>
                    <div class="cgh-cell cgh-center">{{ formatAmount(currRow.ortalama_gun, 0) }}</div>
                    <div class="cgh-cell cgh-center">{{ formatAmount(currRow.ortalama_gun_docdate, 0) }}</div>
                  </div>

                  <div v-if="currencyExpanded[currRow.group_key]" class="detail-host-row">
                    <q-table
                      :rows="agingStore.getDetailsByCurrency(currRow.group_key)"
                      :columns="detailColumns"
                      row-key="detail_key"
                      flat
                      dense
                      bordered
                      hide-bottom
                      :rows-per-page-options="[0]"
                      :pagination="{ rowsPerPage: 0 }"
                      class="detail-subtable"
                      :table-style="{ minWidth: '1500px' }"
                    >
                      <template #body-cell-eslesen_tutar="d">
                        <q-td :props="d" class="text-right">{{ formatAmount(d.row.eslesen_tutar) }}</q-td>
                      </template>
                      <template #body-cell-usd_tutar="d">
                        <q-td :props="d" class="text-right">{{ formatAmount(d.row.usd_tutar) }}</q-td>
                      </template>
                      <template #body-cell-currency_usd_rate="d">
                        <q-td :props="d" class="text-right">{{ formatAmount(d.row.currency_usd_rate) }}</q-td>
                      </template>
                      <template #body-cell-gun_sayisi="d">
                        <q-td :props="d" class="text-center">{{ formatAmount(d.row.gun_sayisi, 0) }}</q-td>
                      </template>
                      <template #body-cell-gun_sayisi_docdate="d">
                        <q-td :props="d" class="text-center">{{ formatAmount(d.row.gun_sayisi_docdate, 0) }}</q-td>
                      </template>
                    </q-table>
                  </div>
                </div>
              </div>
            </q-td>
          </q-tr>
        </template>
      </q-table>
    </div>
  </q-page>

  <q-page v-else class="q-pa-md flex flex-center">
    <div class="text-negative text-subtitle1">Bu modüle erişim yetkiniz yok.</div>
  </q-page>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { useQuasar } from 'quasar'
import dayjs from 'dayjs'
import { usePermission } from 'src/composables/usePermission'
import { useAccountStore } from 'src/stores/accountStore'
import { useStatementAgingStore } from 'src/stores/statementAgingStore'
import { download, extractApiErrorDetail } from 'src/services/api'

const { canRead, canExport } = usePermission()
const canReadFinance = canRead('finance')
const canExportFinance = canExport('finance')

const $q = useQuasar()
const accountStore = useAccountStore()
const agingStore = useStatementAgingStore()

const selectedCari = ref(null)
const filteredOptions = ref([])
const dateTo = ref(dayjs().format('YYYY-MM-DD'))
const masterPagination = ref({
  page: 1,
  rowsPerPage: 0,
  sortBy: 'cari8',
  descending: false
})

const masterExpanded = ref({})
const currencyExpanded = ref({})
const allDetailsOpen = ref(false)
const filtersCollapsed = ref(false)

const monetaryTypeOptions = [
  { label: '1-2 hesap', value: ['1', '2'] },
  { label: '1-3 r hesap', value: ['1', '3'] }
]
const selectedMonType = ref(monetaryTypeOptions[0].value)

const masterColumns = [
  { name: 'expand', label: '', field: 'expand', align: 'center' },
  { name: 'cari8', label: 'Ana Cari Kod', field: 'cari8', align: 'left', sortable: true },
  { name: 'cari_detay', label: 'Ana Cari Detay', field: 'cari_detay', align: 'left', sortable: true },
  { name: 'satir_sayisi', label: 'Satır', field: 'satir_sayisi', align: 'right', sortable: true },
  { name: 'toplam_usd', label: 'Toplam USD', field: 'toplam_usd', align: 'right', sortable: true },
  { name: 'normal_usd', label: 'Normal USD', field: 'normal_usd', align: 'right', sortable: true },
  { name: 'acik_kalem_usd', label: 'Açık Kalem USD', field: 'acik_kalem_usd', align: 'right', sortable: true },
  { name: 'ortalama_gun', label: 'Ort. Gün', field: 'ortalama_gun', align: 'center', sortable: true },
  { name: 'ortalama_gun_docdate', label: 'Ort. Gün (DocDate)', field: 'ortalama_gun_docdate', align: 'center', sortable: true },
  { name: 'kur', label: 'Kur', field: 'kur', align: 'right', sortable: true }
]

const detailColumns = [
  { name: 'fatura_cari', label: 'Fatura Cari', field: 'fatura_cari', align: 'left' },
  { name: 'odeme_cari', label: 'Ödeme Cari', field: 'odeme_cari', align: 'left' },
  { name: 'fatura_ref', label: 'Fatura Ref', field: 'fatura_ref', align: 'left' },
  { name: 'odeme_ref', label: 'Ödeme Ref', field: 'odeme_ref', align: 'left' },
  { name: 'fatura_tarihi', label: 'Fatura Tarihi', field: 'fatura_tarihi', align: 'left' },
  { name: 'odeme_tarihi', label: 'Ödeme Vade', field: 'odeme_tarihi', align: 'left' },
  { name: 'odeme_doc_date', label: 'Ödeme DocDate', field: 'odeme_doc_date', align: 'left' },
  { name: 'eslesen_tutar', label: 'Eşleşen Tutar', field: 'eslesen_tutar', align: 'right' },
  { name: 'usd_tutar', label: 'USD Tutar', field: 'usd_tutar', align: 'right' },
  { name: 'currency_usd_rate', label: 'Kur', field: 'currency_usd_rate', align: 'right' },
  { name: 'gun_sayisi', label: 'Gün', field: 'gun_sayisi', align: 'center' },
  { name: 'gun_sayisi_docdate', label: 'Gün (DocDate)', field: 'gun_sayisi_docdate', align: 'center' },
  { name: 'aciklama', label: 'Açıklama', field: 'aciklama', align: 'left' },
  { name: 'doc_currency_code', label: 'Döviz', field: 'doc_currency_code', align: 'left' }
]

const masterNumericCols = ['satir_sayisi', 'toplam_usd', 'normal_usd', 'acik_kalem_usd', 'ortalama_gun', 'ortalama_gun_docdate', 'kur']
const masterCenteredCols = ['ortalama_gun', 'ortalama_gun_docdate']

function normalizeText(str) {
  return (str || '')
    .toString()
    .toLocaleLowerCase('tr-TR')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .trim()
}

function filterCari(val, update) {
  const needle = normalizeText(val)

  update(() => {
    if (!needle) {
      filteredOptions.value = accountStore.accountOptions
      return
    }

    filteredOptions.value = accountStore.accountOptions.filter(o => {
      const label = normalizeText(o.label)
      const value = normalizeText(o.value)
      return label.includes(needle) || value.includes(needle)
    })
  })
}

onMounted(async () => {
  await accountStore.fetchAccounts()
  filteredOptions.value = accountStore.accountOptions
})

async function onFilterClick() {
  if (!selectedCari.value || !dateTo.value) {
    $q.notify({
      type: 'warning',
      message: 'Lütfen cari ve son tarih seçiniz.',
      position: 'top-right'
    })
    return
  }

  try {
    await agingStore.load({
      accountcode: selectedCari.value,
      enddate: dateTo.value,
      parislemler: selectedMonType.value
    })

    const m = {}
    const c = {}
    for (const row of agingStore.masterRows) {
      m[row.group_key] = true
      for (const cr of agingStore.getCurrenciesByMaster(row.group_key)) {
        c[cr.group_key] = true
      }
    }
    masterExpanded.value = m
    currencyExpanded.value = c
    allDetailsOpen.value = agingStore.masterRows.length > 0
  } catch (err) {
    const msg = await extractApiErrorDetail(err)
    $q.notify({
      type: 'negative',
      message: msg || 'Veriler yüklenemedi',
      position: 'top-right'
    })
  }
}

function resetFilters() {
  selectedCari.value = null
  dateTo.value = dayjs().format('YYYY-MM-DD')
  selectedMonType.value = monetaryTypeOptions[0].value
  masterExpanded.value = {}
  currencyExpanded.value = {}
  allDetailsOpen.value = false
  agingStore.reset()
}

function toggleMaster(key) {
  masterExpanded.value[key] = !masterExpanded.value[key]
}

function toggleCurrency(key) {
  currencyExpanded.value[key] = !currencyExpanded.value[key]
}

function toggleAllDetails() {
  allDetailsOpen.value = !allDetailsOpen.value

  if (!allDetailsOpen.value) {
    masterExpanded.value = {}
    currencyExpanded.value = {}
    return
  }

  const m = {}
  const c = {}
  for (const row of agingStore.masterRows) {
    m[row.group_key] = true
    for (const cr of agingStore.getCurrenciesByMaster(row.group_key)) {
      c[cr.group_key] = true
    }
  }
  masterExpanded.value = m
  currencyExpanded.value = c
}

function toggleFiltersCollapsed() {
  filtersCollapsed.value = !filtersCollapsed.value
}

async function downloadAgingScreenPDF() {
  if (!canExportFinance.value) {
    $q.notify({ type: 'negative', message: 'PDF export yetkiniz yok', position: 'top-right' })
    return
  }
  if (!selectedCari.value || !dateTo.value) {
    $q.notify({ type: 'warning', message: 'Önce cari ve son tarih seçiniz.', position: 'top-right' })
    return
  }

  try {
    const blob = await download('/finance/account-aging-statement/export-screen-pdf', {
      accountcode: String(selectedCari.value || '').trim(),
      cari_search: String(selectedCari.value || '').trim(),
      enddate: dateTo.value,
      selected_date: dateTo.value,
      parislemler: selectedMonType.value,
      exclude_zero_12: '0',
      exclude_zero_13: '0',
      sort_by: String(masterPagination.value?.sortBy || ''),
      sort_desc: masterPagination.value?.descending ? '1' : '0'
    })
    const pdfUrl = window.URL.createObjectURL(new Blob([blob], { type: 'application/pdf' }))
    window.open(pdfUrl, '_blank')
  } catch (err) {
    const detail = await extractApiErrorDetail(err?.original || err)
    $q.notify({
      type: 'negative',
      message: detail || 'PDF oluşturulamadı',
      position: 'top-right'
    })
  }
}

function formatAmount(value, fraction = 2) {
  const n = Number(value || 0)
  return new Intl.NumberFormat('tr-TR', {
    minimumFractionDigits: fraction,
    maximumFractionDigits: fraction
  }).format(n)
}
</script>

<style scoped>
.statement-page {
  --lvl1-top: 0px;
  --lvl1-h: 30px;
  --lvl2-h: 30px;
  --lvl3-h: 30px;
  --lvl3-shift-up: 78px;
  --lvl2-top: calc(var(--lvl1-top) + var(--lvl1-h));
  --lvl3-top: calc(var(--lvl2-top) + var(--lvl2-h));
  --lvl4-top: calc(var(--lvl3-top) + var(--lvl3-h));

  height: calc(100vh - 56px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.table-scroll {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.compact-filter {
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 8px;
  background: #fafafa;
}

.statement-page .local-filter-bar {
  position: sticky;
  top: 0;
  z-index: 40;
}

.sticky-bar {
  position: sticky;
  top: 0;
  z-index: 30;
  flex: 0 0 auto;
  background: var(--q-secondary);
  color: #fff;
  border: 1px solid rgba(0, 0, 0, 0.08);
}

.statement-table {
  flex: 1;
  min-height: 0;
}

.statement-table :deep(.q-table__container) {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.statement-table :deep(.q-table__top) {
  flex: 0 0 auto;
  position: static;
}

.statement-table :deep(.q-table__middle) {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto !important;
  max-height: none !important;
}

.statement-table :deep(.header-row th) {
  position: sticky;
  top: var(--lvl1-top);
  z-index: 40;
  background: var(--q-primary);
  color: #fff;
  font-weight: 600;
  border-bottom: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.2), 0 1px 0 rgba(0, 0, 0, 0.2);
}

.statement-table :deep(.master-row td) {
  background: color-mix(in srgb, var(--q-secondary) 12%, white);
  border-bottom: 2px solid rgba(0, 0, 0, 0.18);
  font-weight: 600;
}

.statement-table :deep(.master-row td:first-child) {
  border-left: 3px solid var(--q-primary);
}

.statement-table :deep(.master-sub-row td) {
  background: #f4f6fb;
  border-bottom: 8px solid #fff;
  vertical-align: top;
  padding: 0 !important;
}

.currency-groups {
  padding: 6px;
  background: #f8faff;
}

.currency-group {
  position: relative;
  border-left: 4px solid var(--q-secondary);
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  border-right: 1px solid rgba(0, 0, 0, 0.08);
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  margin-bottom: 8px;
  background: #fff;
}

.currency-level-head {
  position: sticky;
  top: var(--lvl2-top);
  z-index: 34;
  display: grid;
  grid-template-columns: 48px 100px 80px 1.2fr 1.2fr 1.1fr 1.1fr 100px 110px 140px;
  align-items: center;
  gap: 0;
  background: var(--q-secondary);
  color: #fff;
  border: 1px solid rgba(0, 0, 0, 0.15);
  margin-bottom: 6px;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}

.currency-group-header {
  position: sticky;
  top: var(--lvl3-top);
  z-index: 32;
  display: grid;
  grid-template-columns: 48px 100px 80px 1.2fr 1.2fr 1.1fr 1.1fr 100px 110px 140px;
  align-items: center;
  gap: 0;
  background: #4c5f7a;
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.18);
}

.cgh-cell {
  padding: 6px 8px;
  border-right: 1px solid rgba(255, 255, 255, 0.2);
  font-weight: 600;
  font-size: 11px;
}

.cgh-cell:last-child {
  border-right: none;
}

.cgh-num {
  text-align: right;
}

.cgh-center {
  text-align: center;
}

.cgh-expand {
  text-align: center;
}

.detail-host-row :deep(td) {
  background: #fdfdfd;
  padding: 6px !important;
}

.detail-subtable {
  border-left: 4px solid var(--q-primary);
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  border-right: 1px solid rgba(0, 0, 0, 0.08);
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  background: #fff;
}

.statement-table :deep(th),
.statement-table :deep(td),
.detail-subtable :deep(th),
.detail-subtable :deep(td) {
  padding: 3px 6px !important;
  font-size: 11px !important;
  line-height: 1.2 !important;
}

.detail-subtable :deep(.q-table__top) {
  position: static;
}

.detail-subtable :deep(thead) {
  position: sticky;
  top: calc(var(--lvl3-top) - var(--lvl3-shift-up));
  z-index: 31;
}

.detail-subtable :deep(thead th) {
  position: static;
  background: #1f3b5b;
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}

.detail-subtable :deep(td[data-col="gun_sayisi"]),
.detail-subtable :deep(td[data-col="gun_sayisi_docdate"]),
.statement-table :deep(td[data-col="ortalama_gun"]),
.statement-table :deep(td[data-col="ortalama_gun_docdate"]) {
  text-align: center !important;
}

@media (max-width: 1366px) {
  .statement-table :deep(th),
  .statement-table :deep(td),
  .detail-subtable :deep(th),
  .detail-subtable :deep(td) {
    font-size: 10px !important;
    padding: 2px 4px !important;
  }

  .currency-group-header {
    grid-template-columns: 44px 90px 70px 1.1fr 1.1fr 1fr 1fr 84px 90px 120px;
  }
}
</style>
