import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { get, post, extractApiErrorDetail } from 'src/services/api'

const DRAFT_KEY = 'bssapp:production-product-costing:default-quantities:draft:v1'

function safeJsonParse (raw) {
  try {
    return JSON.parse(raw)
  } catch {
    return null
  }
}

export const useProductionProductCostingDefaultQtyStore = defineStore('production_product_costing_default_qty', () => {
  const rows = ref([])
  const loading = ref(false)
  const saving = ref(false)
  const error = ref('')

  // draftByNo: { [nHammaddeTuruNo]: { lDefaultMiktar } }
  const draftByNo = ref({})
  const persistTimer = ref(0)

  const dirtyNos = computed(() => Object.keys(draftByNo.value || {}).map(k => Number(k)).filter(n => n > 0))
  const hasUnsavedChanges = computed(() => dirtyNos.value.length > 0)

  function schedulePersistDraft () {
    try {
      if (persistTimer.value) window.clearTimeout(persistTimer.value)
      persistTimer.value = window.setTimeout(() => {
        persistTimer.value = 0
        persistDraftNow()
      }, 350)
    } catch {
      persistDraftNow()
    }
  }

  function persistDraftNow () {
    try {
      const payload = {
        version: 1,
        savedAt: new Date().toISOString(),
        draftByNo: draftByNo.value || {}
      }
      localStorage.setItem(DRAFT_KEY, JSON.stringify(payload))
    } catch {
      // ignore
    }
  }

  function hydrateDraft () {
    try {
      const raw = localStorage.getItem(DRAFT_KEY)
      if (!raw) return
      const payload = safeJsonParse(raw)
      if (!payload || typeof payload !== 'object') return
      if (!payload.draftByNo || typeof payload.draftByNo !== 'object') return
      draftByNo.value = payload.draftByNo
    } catch {
      // ignore
    }
  }

  function clearDraft () {
    draftByNo.value = {}
    try {
      localStorage.removeItem(DRAFT_KEY)
    } catch {
      // ignore
    }
  }

  function setDraft (nHammaddeTuruNo, patch) {
    const no = Number(nHammaddeTuruNo || 0)
    if (!(no > 0)) return
    const prev = draftByNo.value?.[String(no)] || {}
    draftByNo.value = {
      ...(draftByNo.value || {}),
      [String(no)]: {
        ...prev,
        ...(patch || {})
      }
    }
    schedulePersistDraft()
  }

  function getEffectiveRow (row) {
    const no = Number(row?.nHammaddeTuruNo || 0)
    if (!(no > 0)) return row
    const draft = draftByNo.value?.[String(no)]
    if (!draft) return row
    return {
      ...row,
      lDefaultMiktar: typeof draft.lDefaultMiktar === 'number' ? draft.lDefaultMiktar : row?.lDefaultMiktar,
      __dirty: true
    }
  }

  async function fetch ({ search = '', limit = 2000 } = {}) {
    loading.value = true
    error.value = ''
    try {
      const data = await get('/pricing/production-product-costing/default-quantities', {
        search: String(search || '').trim(),
        limit
      })
      const base = Array.isArray(data) ? data : []
      rows.value = base.map(getEffectiveRow)
    } catch (e) {
      error.value = extractApiErrorDetail(e) || String(e?.message || e || 'Hata')
      throw e
    } finally {
      loading.value = false
    }
  }

  async function calcAvgForRow ({ nHammaddeTuruNo, topN = 10 } = {}) {
    const no = Number(nHammaddeTuruNo || 0)
    if (!(no > 0)) return null
    const resp = await post('/pricing/production-product-costing/default-quantities/calc-avg', {
      nHammaddeTuruNo: no,
      topN: Number(topN || 10)
    })
    return resp
  }

  async function saveAll () {
    if (!hasUnsavedChanges.value) return { updated: 0 }
    saving.value = true
    error.value = ''
    try {
      const items = dirtyNos.value.map(no => {
        const patch = draftByNo.value?.[String(no)] || {}
        return {
          nHammaddeTuruNo: Number(no),
          lDefaultMiktar: Number(patch.lDefaultMiktar || 0)
        }
      }).filter(it => it.nHammaddeTuruNo > 0 && it.lDefaultMiktar > 0)

      const resp = await post('/pricing/production-product-costing/default-quantities/update-bulk', { items })
      clearDraft()
      return resp
    } catch (e) {
      error.value = extractApiErrorDetail(e) || String(e?.message || e || 'Hata')
      throw e
    } finally {
      saving.value = false
    }
  }

  hydrateDraft()

  return {
    rows,
    loading,
    saving,
    error,
    draftByNo,
    dirtyNos,
    hasUnsavedChanges,
    fetch,
    setDraft,
    calcAvgForRow,
    saveAll,
    clearDraft
  }
})
