import { defineStore } from 'pinia'
import api from 'src/services/api'
import qs from 'qs'

export const useStatementAgingStore = defineStore('statementAging', {
  state: () => ({
    rows: [],
    masterRows: [],
    currencyRowsByMaster: {},
    detailByCurrency: {},
    loading: false
  }),

  actions: {
    async load(params = {}) {
      this.loading = true
      try {
        const { data } = await api.get('/finance/account-aging-statement', {
          params,
          paramsSerializer: p => qs.stringify(p, { arrayFormat: 'repeat' })
        })

        const base = Array.isArray(data) ? data.map(normalizeRowKeys) : []
        this.rows = base.map((r, idx) => ({
          ...r,
          detail_key: `${idx}-${r.cari8 || ''}-${r.doc_currency_code || ''}-${r.fatura_ref || ''}-${r.odeme_ref || ''}`
        }))

        this.rebuildHierarchical()
      } catch (err) {
        console.error('Aging statement load failed:', err)
        this.reset()
        throw err
      } finally {
        this.loading = false
      }
    },

    rebuildHierarchical() {
      const masterMap = {}
      const currencyMap = {}
      const detailMap = {}

      for (const row of this.rows) {
        const cari8 = String(row?.cari8 || '').trim()
        const curr = String(row?.doc_currency_code || '').trim().toUpperCase() || 'N/A'
        if (!cari8) continue

        const masterKey = cari8
        const currencyKey = `${cari8}|${curr}`
        const tutar = Number(row?.eslesen_tutar) || 0
        const usd = Number(row?.usd_tutar) || 0
        const absUsd = Math.abs(usd)
        const gun = Number(row?.gun_sayisi) || 0
        const gunDoc = Number(row?.gun_sayisi_docdate) || 0
        const usdBasedRate = Number(row?.currency_usd_rate) || 0
        const aciklama = String(row?.aciklama || '').toUpperCase()

        if (!masterMap[masterKey]) {
          masterMap[masterKey] = {
            group_key: masterKey,
            cari8: masterKey,
            cari_detay: String(row?.cari_detay || '').trim(),
            satir_sayisi: 0,
            toplam_tutar: 0,
            toplam_usd: 0,
            normal_usd: 0,
            acik_kalem_usd: 0,
            kur: 0,
            weighted_gun_sum: 0,
            weighted_gun_doc_sum: 0,
            weighted_base: 0,
            kur_weighted_sum: 0,
            kur_weighted_base: 0,
            kur_fallback: 0,
            ortalama_gun: 0,
            ortalama_gun_docdate: 0
          }
        }

        if (!currencyMap[currencyKey]) {
          currencyMap[currencyKey] = {
            group_key: currencyKey,
            master_key: masterKey,
            cari8,
            cari_detay: String(row?.cari_detay || '').trim(),
            doc_currency_code: curr,
            satir_sayisi: 0,
            toplam_tutar: 0,
            toplam_usd: 0,
            normal_tutar: 0,
            acik_kalem_tutar: 0,
            kur: 0,
            weighted_gun_sum: 0,
            weighted_gun_doc_sum: 0,
            weighted_base: 0,
            kur_weighted_sum: 0,
            kur_weighted_base: 0,
            kur_fallback: 0,
            ortalama_gun: 0,
            ortalama_gun_docdate: 0
          }
        }

        const m = masterMap[masterKey]
        const c = currencyMap[currencyKey]

        m.satir_sayisi += 1
        m.toplam_tutar += tutar
        m.toplam_usd += usd
        if (aciklama === 'ACIKKALEM') {
          m.acik_kalem_usd += usd
        } else {
          m.normal_usd += usd
        }

        c.satir_sayisi += 1
        c.toplam_tutar += tutar
        c.toplam_usd += usd
        if (aciklama === 'ACIKKALEM') {
          c.acik_kalem_tutar += tutar
        } else {
          c.normal_tutar += tutar
        }

        if (absUsd > 0) {
          m.weighted_base += absUsd
          m.weighted_gun_sum += absUsd * gun
          m.weighted_gun_doc_sum += absUsd * gunDoc

          c.weighted_base += absUsd
          c.weighted_gun_sum += absUsd * gun
          c.weighted_gun_doc_sum += absUsd * gunDoc

          if (usdBasedRate > 0) {
            m.kur_weighted_base += absUsd
            m.kur_weighted_sum += absUsd * usdBasedRate
            c.kur_weighted_base += absUsd
            c.kur_weighted_sum += absUsd * usdBasedRate
          }
        }

        if (usdBasedRate > 0) {
          m.kur_fallback = usdBasedRate
          c.kur_fallback = usdBasedRate
        }

        if (!detailMap[currencyKey]) detailMap[currencyKey] = []
        detailMap[currencyKey].push(row)
      }

      this.masterRows = Object.values(masterMap)
        .map((m) => ({
          ...m,
          kur: m.kur_weighted_base > 0 ? (m.kur_weighted_sum / m.kur_weighted_base) : m.kur_fallback,
          ortalama_gun: m.weighted_base > 0 ? (m.weighted_gun_sum / m.weighted_base) : 0,
          ortalama_gun_docdate: m.weighted_base > 0 ? (m.weighted_gun_doc_sum / m.weighted_base) : 0
        }))
        .sort((a, b) => String(a.cari8).localeCompare(String(b.cari8), 'tr', { sensitivity: 'base' }))

      const currencyByMaster = {}
      for (const c of Object.values(currencyMap)) {
        const row = {
          ...c,
          kur: c.kur_weighted_base > 0 ? (c.kur_weighted_sum / c.kur_weighted_base) : c.kur_fallback,
          ortalama_gun: c.weighted_base > 0 ? (c.weighted_gun_sum / c.weighted_base) : 0,
          ortalama_gun_docdate: c.weighted_base > 0 ? (c.weighted_gun_doc_sum / c.weighted_base) : 0
        }
        if (!currencyByMaster[row.master_key]) currencyByMaster[row.master_key] = []
        currencyByMaster[row.master_key].push(row)
      }

      for (const key of Object.keys(currencyByMaster)) {
        currencyByMaster[key].sort((a, b) => String(a.doc_currency_code).localeCompare(String(b.doc_currency_code), 'en', { sensitivity: 'base' }))
      }

      for (const key of Object.keys(detailMap)) {
        detailMap[key].sort((a, b) => {
          const aOpen = isAcikKalem(a?.aciklama)
          const bOpen = isAcikKalem(b?.aciklama)
          if (aOpen !== bOpen) {
            return aOpen ? -1 : 1
          }

          const aDate = toSortableDate(a)
          const bDate = toSortableDate(b)
          if (aDate !== bDate) {
            return bDate - aDate
          }

          const aRef = String(a?.fatura_ref || '')
          const bRef = String(b?.fatura_ref || '')
          return aRef.localeCompare(bRef, 'tr', { sensitivity: 'base' })
        })
      }

      this.currencyRowsByMaster = currencyByMaster
      this.detailByCurrency = detailMap
    },

    reset() {
      this.rows = []
      this.masterRows = []
      this.currencyRowsByMaster = {}
      this.detailByCurrency = {}
      this.loading = false
    },

    getCurrenciesByMaster(masterKey) {
      return this.currencyRowsByMaster[String(masterKey || '').trim()] || []
    },

    getDetailsByCurrency(currencyKey) {
      return this.detailByCurrency[String(currencyKey || '').trim()] || []
    }
  }
})

function normalizeRowKeys(row) {
  if (!row || typeof row !== 'object') return {}
  return {
    cari8: row.Cari8 ?? row.cari8 ?? null,
    cari_detay: row.CariDetay ?? row.cari_detay ?? null,
    fatura_cari: row.FaturaCari ?? row.fatura_cari ?? null,
    odeme_cari: row.OdemeCari ?? row.odeme_cari ?? null,
    fatura_ref: row.FaturaRef ?? row.fatura_ref ?? null,
    odeme_ref: row.OdemeRef ?? row.odeme_ref ?? null,
    fatura_tarihi: row.FaturaTarihi ?? row.fatura_tarihi ?? null,
    odeme_tarihi: row.OdemeTarihi ?? row.odeme_tarihi ?? null,
    odeme_doc_date: row.OdemeDocDate ?? row.odeme_doc_date ?? null,
    eslesen_tutar: Number(row.EslesenTutar ?? row.eslesen_tutar ?? 0),
    usd_tutar: Number(row.UsdTutar ?? row.usd_tutar ?? 0),
    gun_sayisi: Number(row.GunSayisi ?? row.gun_sayisi ?? 0),
    gun_sayisi_docdate: Number(row.GunSayisi_DocDate ?? row.gun_sayisi_docdate ?? 0),
    currency_try_rate: Number(row.CurrencyTryRate ?? row.currency_try_rate ?? 0),
    usd_try_rate: Number(row.UsdTryRate ?? row.usd_try_rate ?? 0),
    currency_usd_rate: Number(row.CurrencyUsdRate ?? row.currency_usd_rate ?? 0),
    aciklama: row.Aciklama ?? row.aciklama ?? null,
    doc_currency_code: row.DocCurrencyCode ?? row.doc_currency_code ?? null
  }
}

function isAcikKalem(value) {
  return String(value || '').trim().toUpperCase() === 'ACIKKALEM'
}

function toSortableDate(row) {
  const raw = row?.odeme_doc_date || row?.odeme_tarihi || row?.fatura_tarihi || ''
  const t = Date.parse(String(raw || '').trim())
  return Number.isFinite(t) ? t : 0
}
